JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
stylus-helpers: add transparent vendor expansion for user-select
[wfpl.git] / stylus-helpers.styl
1 // Copyright 2014 Jason Woofenden -- Public Domain (CC0)
2
3 // This file contains helpers for using stylus in your project.
4 //
5 // Put something like this in your styl.styl:
6 //     @require 'code/wfpl/stylus-helpers.styl'
7
8
9 // set units to px if it doesn't have a unit already
10 _px(i)
11         unit(i) == '' ? unit(i, px) : i
12
13 // transparently support vender-specific tags
14 border-radius()
15         -webkit-border-radius: arguments
16         border-radius: arguments
17 box-shadow()
18         -webkit-box-shadow: arguments
19         box-shadow: arguments
20 box-sizing()
21         -webkit-box-sizing: arguments
22         -moz-box-sizing: arguments
23         box-sizing: arguments
24 user-select()
25         -webkit-user-select: arguments
26         -moz-user-select: arguments
27         -ms-user-select: arguments
28         user-select: arguments
29
30 // map "whitespace:" to "white-space:"
31 whitespace()
32         white-space: arguments
33
34 // helper function
35 _pos(type, args)
36         position: unquote(type)
37         for i in (0...length(args))
38                 if not args[i] is a 'unit'
39                         {args[i]}: args[i + 1] is a 'unit' ? args[i + 1] : 0
40
41 // you can pass directions and units, or just directions. Examples:
42 //     absolute: top 20px left 0
43 //     fixed: top right
44 //     relative: top -4px
45 absolute()
46         _pos('absolute', arguments)
47 fixed()
48         _pos('fixed', arguments)
49 relative()
50         _pos('relative', arguments)
51
52 // Make children of this element inline-blocks that are spaced evenly accross.
53 //
54 // To create a minimum distance between: don't use word-spacing, it's broken in
55 // firefox. Instead, try padding on the children and negative margin on the
56 // parent.
57 space_evenly(line_height = 1.2em)
58         text-align justify
59         & > *
60                 display inline-block
61                 relative top line_height
62         &:before
63                 content ''
64                 display block
65                 width 100%
66                 margin-bottom -(line_height)
67         &:after
68                 content ''
69                 display inline-block
70                 width 100%
71
72 // image layout: left column has normal, right column hover versions
73 //
74 // arguments: width/height are pixel dimensions of a single sprite
75 //
76 // markup: put classes n1, n2, etc on the items.
77 //
78 // Example
79 //
80 //     html:
81 //         <nav>
82 //             <ul>
83 //                 <li class="n1">home</li>
84 //                 <li class="n2">contact</li>
85 //             </ul>
86 //         </nav>
87 //     styl:
88 //         nav li
89 //             sprite-rollover "images/nav.png" 150 35 2
90 sprite-rollover(image, width, height, count)
91         width = unit(width, px)
92         height = unit(width, px)
93         width width
94         height height
95         background: transparent url(image) top left no-repeat;
96         for n in (1..count)
97                 &.n{n}
98                         y = (2px - n * 35px)
99                         background-position 0 y
100                         &:hover
101                                 background-position -(width) y
102
103 // Styling for a variable height element with an image background where the
104 // middle repeats vertically. You must split your image into three images, and
105 // name them with "-top", "-mid" and "-bot" suffixes (right before the file
106 // extension.) then pass a filepath as the first argument to this function
107 // which does not have a suffix.
108 //
109 // Example:
110 //
111 //     image files:
112 //         i/foo-top.png  (900x20)
113 //         i/foo-mid.png  (900xwhatever)
114 //         i/foo-bot.png  (900x30)
115 //
116 //     dom layout: <div id="expando"><div><div><div>...</div></div></div></div>
117 //
118 //     Stylus:
119 //
120 //         #expando
121 //            mangin: 10px auto;
122 //            width: 900px;
123 //            background-vertical-stretch("i/foo.png", 20, 30)
124 //
125 //     Notes:
126 //
127 //         You can (optionally) pass 1-4 additional arguments which
128 //         (effectively) add padding to the inner most div. The default is to
129 //         have the height and width of the inner div match exactly the outer
130 //         one. Parameters you specify are relative to that (not the section
131 //         filled with the "-mid" image).
132 background-vertical-stretch(image, top-height, bottom-height, top-pad = 0, right-pad = top-pad, bottom-pad = top-pad, left-pad = right-pad)
133         top-height = _px(top-height)
134         bottom-height = _px(bottom-height)
135         top-pad = _px(top-pad)
136         right-pad = _px(right-pad)
137         bottom-pad = _px(bottom-pad)
138         left-pad = _px(left-pad)
139         ext = extname(image)
140         path = pathjoin(dirname(image), basename(image, ext))
141
142         // bottom image (outermost block)
143         background transparent url(path + '-bot' + ext)
144         padding-bottom bottom-height + 1 // +1 to prevent margin collapsing
145         > *
146                 background transparent url(path + '-top' + ext) 0 0 no-repeat
147                 padding-top top-height + 1 // +1 to prevent margin collapsing
148         > * > *
149                 background transparent url(path + '-mid' + ext) 0 0 repeat-y;
150                 margin-top -1px; // correct for above +1 from top
151                 margin-bottom -1px; // correct for above +1 from bottom
152                 padding 1px; // to prevent margin collapsing
153         > * > * > *
154                 // all "2px" below are to correct for 1px above padding and below
155                 padding 1px;
156                 margin-top 2px - top-height + top-pad
157                 margin-left: left-pad - 2px
158                 margin-right: right-pad - 2px
159                 margin-bottom: 2px - bottom-height + bottom-pad
160                 background transparent;
161
162 li-reset()
163         margin 0
164         padding 0
165         list-style none