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