JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
enc_htmlbrtab: don't double spaces
[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 'inc/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 // Specify width and height on the same line
53 dimensions(w, h)
54         width: _px(w)
55         height: _px(h)
56
57 // Make children of this element inline-blocks that are spaced evenly accross.
58 //
59 // To create a minimum distance between: don't use word-spacing, it's broken in
60 // firefox. Instead, try padding on the children and negative margin on the
61 // parent.
62 space_evenly(line_height = 1.2em)
63         text-align: justify
64         & > *
65                 display: inline-block
66                 relative: top line_height
67         &:before
68                 content: ''
69                 display: block
70                 width: 100%
71                 margin-bottom: -(line_height)
72         &:after
73                 content: ''
74                 display: inline-block
75                 width: 100%
76
77 // image layout: left column has normal, right column hover versions
78 //
79 // arguments: width/height are pixel dimensions of a single sprite
80 //
81 // markup: put classes n1, n2, etc on the items.
82 //
83 // Example
84 //
85 //     html:
86 //         <nav>
87 //             <ul>
88 //                 <li class="n0">home</li>
89 //                 <li class="n1">contact</li>
90 //             </ul>
91 //         </nav>
92 //     styl:
93 //         nav li
94 //             sprites_rollover "images/nav.png" 150 35 2
95 sprites_rollover(image, width, height, count, v_offset = 0, h_offset = 0)
96         width: unit(width, px)
97         height: unit(height, px)
98         if image[1]
99                 background: url(image[0])
100                 background: url(image[1]), linear-gradient(transparent, transparent);
101         else
102                 background-image: url(image)
103         background-position: top left
104         background-repeat: no-repeat;
105         for n in (0...count)
106                 &.n{n}
107                         y = - (@height * n) - unit(v_offset, px)
108                         background-position: (0 - unit(h_offset, px)) y
109                         &:hover
110                                 background-position: (0 - unit(h_offset, px) - @width) y
111 sprite_rollover(image, width, height, v_offset = 0, h_offset = 0)
112         sprites_rollover(image, width, height, 1, v_offset, h_offset)
113
114 // see sprites_rollover
115 sprites(image, height, count, v_offset = 0, h_offset = 0)
116         height: unit(height, px)
117         if image[1]
118                 background: url(image[0])
119                 background: url(image[1]), linear-gradient(transparent, transparent);
120         else
121                 background-image: url(image)
122         background-position: top left
123         background-repeat: no-repeat;
124         for n in (0...count)
125                 &.n{n}
126                         y = - (@height * n) - unit(v_offset, px)
127                         background-position: (0 - unit(h_offset, px)) y
128 sprite(image, height, v_offset = 0, h_offset = 0)
129         sprites(image, height, 1, v_offset, h_offset)
130
131 // Styling for a variable height element with an image background where the
132 // middle repeats vertically. You must split your image into three images, and
133 // name them with "-top", "-mid" and "-bot" suffixes (right before the file
134 // extension.) then pass a filepath as the first argument to this function
135 // which does not have a suffix.
136 //
137 // Example:
138 //
139 //     image files:
140 //         i/foo-top.png  (900x20)
141 //         i/foo-mid.png  (900xwhatever)
142 //         i/foo-bot.png  (900x30)
143 //
144 //     dom layout: <div id="expando"><div><div><div>...</div></div></div></div>
145 //
146 //     Stylus:
147 //
148 //         #expando
149 //            mangin: 10px auto;
150 //            width: 900px;
151 //            background_vertical_stretch("i/foo.png", 20, 30)
152 //
153 //     Notes:
154 //
155 //         You can (optionally) pass 1-4 additional arguments which
156 //         (effectively) add padding to the inner most div. The default is to
157 //         have the height and width of the inner div match exactly the outer
158 //         one. Parameters you specify are relative to that (not the section
159 //         filled with the "-mid" image).
160 background_vertical_stretch(image, top_height, bottom_height, top_pad = 0, right_pad = top_pad, bottom_pad = top_pad, left_pad = right_pad)
161         top_height = _px(top_height)
162         bottom_height = _px(bottom_height)
163         top_pad = _px(top_pad)
164         right_pad = _px(right_pad)
165         bottom_pad = _px(bottom_pad)
166         left_pad = _px(left_pad)
167         ext = extname(image)
168         path = pathjoin(dirname(image), basename(image, ext))
169
170         // bottom image (outermost block)
171         background: transparent url(path + '-bot' + ext)
172         padding-bottom: bottom_height + 1 // +1 to prevent margin collapsing
173         > *
174                 background: transparent url(path + '-top' + ext) 0 0 no-repeat
175                 padding-top: top_height + 1 // +1 to prevent margin collapsing
176         > * > *
177                 background: transparent url(path + '-mid' + ext) 0 0 repeat-y;
178                 margin-top: -1px; // correct for above +1 from top
179                 margin-bottom: -1px; // correct for above +1 from bottom
180                 padding: 1px; // to prevent margin collapsing
181         > * > * > *
182                 // all "2px" below are to correct for 1px above padding and below
183                 padding: 1px;
184                 margin-top: 2px - top_height + top_pad
185                 margin-left: left_pad - 2px
186                 margin-right: right_pad - 2px
187                 margin-bottom: 2px - bottom_height + bottom_pad
188                 background: transparent;
189
190 li_reset()
191         margin: 0
192         padding: 0
193         list-style: none
194
195 // Example:
196 //     input
197 //         +placeholder()
198 //             color: red
199 placeholder()
200         &::-webkit-input-placeholder
201                 {block}
202         &:-moz-placeholder // firefox 4-18
203                 {block}
204         &::-moz-placeholder // firefox 19+
205                 {block}
206         &:-ms-input-placeholder // ie
207                 {block}
208
209 // Example:
210 //     div.button
211 //         noselect()
212 noselect()
213         -webkit-touch-callout: none
214         -webkit-user-select: none
215         -khtml-user-select: none
216         -moz-user-select: none
217         -ms-user-select: none
218         user-select: none