UNPKG

10.9 kBSCSSView Raw
1// Foundation for Sites by ZURB
2// foundation.zurb.com
3// Licensed under MIT Open Source
4
5////
6/// @group functions
7////
8
9/// Creates an inner box-shadow for only one side
10///
11/// @param {Keyword} $side - Side the shadow is supposed to appear. Can be `top`, `left`, `right` or `bottom`.
12/// @param {Number} $size - Width for the target side.
13/// @param {Color} $color - Color of the shadow.
14@mixin inner-side-shadow(
15 $side: bottom,
16 $size: 20px,
17 $color: rgba($black, 0.25)
18) {
19
20 $helper: round($size * 0.65);
21
22 @if ($side == top) {
23 box-shadow: inset 0 $helper $size (-1)*$helper $color;
24 } @else if ($side == left) {
25 box-shadow: inset $helper 0 $size (-1)*$helper $color;
26 } @else if ($side == right) {
27 box-shadow: inset (-1)*$helper 0 $size (-1)*$helper $color;
28 } @else if ($side == bottom) {
29 box-shadow: inset 0 (-1)*$helper $size (-1)*$helper $color;
30 }
31}
32
33/// Creates a CSS triangle, which can be used for dropdown arrows, dropdown pips, and more. Use this mixin inside a `&::before` or `&::after` selector, to attach the triangle to an existing element.
34///
35/// @param {Number} $triangle-size - Width of the triangle.
36/// @param {Color} $triangle-color - Color of the triangle.
37/// @param {Keyword} $triangle-direction - Direction the triangle points. Can be `up`, `right`, `down`, or `left`.
38@mixin css-triangle(
39 $triangle-size,
40 $triangle-color,
41 $triangle-direction
42) {
43 display: block;
44 width: 0;
45 height: 0;
46
47 border: inset $triangle-size;
48
49 content: '';
50
51 @if ($triangle-direction == down) {
52 border-bottom-width: 0;
53 border-top-style: solid;
54 border-color: $triangle-color transparent transparent;
55 }
56 @if ($triangle-direction == up) {
57 border-top-width: 0;
58 border-bottom-style: solid;
59 border-color: transparent transparent $triangle-color;
60 }
61 @if ($triangle-direction == right) {
62 border-right-width: 0;
63 border-left-style: solid;
64 border-color: transparent transparent transparent $triangle-color;
65 }
66 @if ($triangle-direction == left) {
67 border-left-width: 0;
68 border-right-style: solid;
69 border-color: transparent $triangle-color transparent transparent;
70 }
71}
72
73/// Creates a menu icon with a set width, height, number of bars, and colors. The mixin uses the height of the icon and the weight of the bars to determine spacing. <div class="docs-example-burger"></div>
74///
75/// @param {Color} $color [$black] - Color to use for the icon.
76/// @param {Color} $color-hover [$dark-gray] - Color to use when the icon is hovered over.
77/// @param {Number} $width [20px] - Width of the icon.
78/// @param {Number} $height [16px] - Height of the icon.
79/// @param {Number} $weight [2px] - Height of individual bars in the icon.
80/// @param {Number} $bars [3] - Number of bars in the icon.
81@mixin hamburger(
82 $color: $black,
83 $color-hover: $dark-gray,
84 $width: 20px,
85 $height: 16px,
86 $weight: 2px,
87 $bars: 3
88) {
89 // box-shadow CSS output
90 $shadow: ();
91 $hover-shadow: ();
92
93 // Spacing between bars is calculated based on the total height of the icon and the weight of each bar
94 $spacing: ($height - ($weight * $bars)) / ($bars - 1);
95
96 @if unit($spacing) == 'px' {
97 $spacing: floor($spacing);
98 }
99
100 @for $i from 2 through $bars {
101 $offset: ($weight + $spacing) * ($i - 1);
102 $shadow: append($shadow, 0 $offset 0 $color, comma);
103 }
104
105 // Icon container
106 position: relative;
107 display: inline-block;
108 vertical-align: middle;
109 width: $width;
110 height: $height;
111 cursor: pointer;
112
113 // Icon bars
114 &::after {
115 position: absolute;
116 top: 0;
117 left: 0;
118
119 display: block;
120 width: 100%;
121 height: $weight;
122
123 background: $color;
124 box-shadow: $shadow;
125
126 content: '';
127 }
128
129 // Hover state
130 @if $color-hover {
131 // Generate CSS
132 @for $i from 2 through $bars {
133 $offset: ($weight + $spacing) * ($i - 1);
134 $hover-shadow: append($hover-shadow, 0 $offset 0 $color-hover, comma);
135 }
136
137 &:hover::after {
138 background: $color-hover;
139 box-shadow: $hover-shadow;
140 }
141 }
142}
143
144/// Adds a downward-facing triangle as a background image to an element. The image is formatted as an SVG, making it easy to change the color. Because Internet Explorer doesn't support encoded SVGs as background images, a PNG fallback is also included.
145/// There are two PNG fallbacks: a black triangle and a white triangle. The one used depends on the lightness of the input color.
146///
147/// @param {Color} $color [$black] - Color to use for the triangle.
148@mixin background-triangle($color: $black) {
149 $rgb: 'rgb%28#{round(red($color))}, #{round(green($color))}, #{round(blue($color))}%29';
150
151 background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='32' height='24' viewBox='0 0 32 24'><polygon points='0,0 32,0 16,24' style='fill: #{$rgb}'></polygon></svg>");
152
153 @media screen and (min-width:0\0) {
154 @if lightness($color) < 60% {
155 // White triangle
156 background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAYCAYAAACbU/80AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIpJREFUeNrEkckNgDAMBBfRkEt0ObRBBdsGXUDgmQfK4XhH2m8czQAAy27R3tsw4Qfe2x8uOO6oYLb6GlOor3GF+swURAOmUJ+RwtEJs9WvTGEYxBXqI1MQAZhCfUQKRzDMVj+TwrAIV6jvSUEkYAr1LSkcyTBb/V+KYfX7xAeusq3sLDtGH3kEGACPWIflNZfhRQAAAABJRU5ErkJggg==');
157 }
158 @else {
159 // Black triangle
160 background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAYCAYAAACbU/80AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAMBJREFUeNrEllsOhCAMRVszC9IlzU7KCmVHTJsoMWYMUtpyv9BgbuXQB5ZSdgBYYY4ycgBivk8KYFsQMfMiTTBP4o3nUzCKzOabLJbLy2/g31evGkAginR4/ZegKH5qX3bJCscA3t0x3kgO5tQFyhhFf50xRqFLbyMUNJQzgyjGS/wgCpvKqkRBpuWrE4V9d+1E4dPUXqIg107SQOE/2DRQxMwTDygIInVDET9T3lCoj/6j/VCmGjZOl2lKpZ8AAwDQP7zIimDGFQAAAABJRU5ErkJggg==');
161 }
162 }
163}
164
165/// Applies the micro clearfix hack popularized by Nicolas Gallagher. Include this mixin on a container if its children are all floated, to give the container a proper height.
166/// The clearfix is augmented with specific styles to prevent borders in flexbox environments
167/// @link http://nicolasgallagher.com/micro-clearfix-hack/ Micro Clearfix Hack
168/// @link http://danisadesigner.com/blog/flexbox-clear-fix-pseudo-elements/ Flexbox fix
169@mixin clearfix {
170 &::before,
171 &::after {
172 display: table;
173 content: ' ';
174
175 @if $global-flexbox {
176 flex-basis: 0;
177 order: 1;
178 }
179 }
180
181 &::after {
182 clear: both;
183 }
184}
185
186/// Adds CSS for a "quantity query" selector that automatically sizes elements based on how many there are inside a container.
187/// @link http://alistapart.com/article/quantity-queries-for-css Quantity Queries for CSS
188///
189/// @param {Number} $max - Maximum number of items to detect. The higher this number is, the more CSS that's required to cover each number of items.
190/// @param {Keyword} $elem [li] - Tag to use for sibling selectors.
191@mixin auto-width($max, $elem: li) {
192 @for $i from 2 through $max {
193 &:nth-last-child(#{$i}):first-child,
194 &:nth-last-child(#{$i}):first-child ~ #{$elem} {
195 width: percentage(1 / $i);
196 }
197 }
198}
199
200/// Removes the focus ring around an element when a mouse input is detected.
201@mixin disable-mouse-outline {
202 [data-whatinput='mouse'] & {
203 outline: 0;
204 }
205}
206
207/// Makes an element visually hidden, but still accessible to keyboards and assistive devices.
208/// @link http://snook.ca/archives/html_and_css/hiding-content-for-accessibility Hiding Content for Accessibility
209/// @link http://hugogiraudel.com/2016/10/13/css-hide-and-seek/
210@mixin element-invisible {
211 position: absolute !important;
212 width: 1px;
213 height: 1px;
214 padding: 0;
215 overflow: hidden;
216 clip: rect(0,0,0,0);
217 white-space: nowrap;
218 clip-path: inset(50%);
219 border: 0;
220}
221
222/// Reverses the CSS output created by the `element-invisible()` mixin.
223@mixin element-invisible-off {
224 position: static !important;
225 width: auto;
226 height: auto;
227 overflow: visible;
228 clip: auto;
229 white-space: normal;
230 clip-path: none;
231}
232
233/// Vertically centers the element inside of its first non-static parent,
234/// @link http://www.sitepoint.com/centering-with-sass/ Centering With Sass
235@mixin vertical-center {
236 position: absolute;
237 top: 50%;
238 transform: translateY(-50%);
239}
240
241/// Horizontally centers the element inside of its first non-static parent,
242/// @link http://www.sitepoint.com/centering-with-sass/ Centering With Sass
243@mixin horizontal-center {
244 position: absolute;
245 left: 50%;
246 transform: translateX(-50%);
247}
248
249/// Absolutely centers the element inside of its first non-static parent,
250/// @link http://www.sitepoint.com/centering-with-sass/ Centering With Sass
251@mixin absolute-center {
252 position: absolute;
253 top: 50%;
254 left: 50%;
255 transform: translate(-50%, -50%);
256}
257
258/// Iterates through breakpoints defined in `$breakpoint-classes` and prints the CSS inside the mixin at each breakpoint's media query. Use this with the grid, or any other component that has responsive classes.
259///
260/// @param {Boolean} $small [true] - If `false`, the mixin will skip the `small` breakpoint. Use this with components that don't prefix classes with `small-`, only `medium-` and up.
261/// @param {Boolean} $auto-insert-breakpoints [true] - If `false`, the mixin will iterate over breakpoints without doing the media query itself. Useful for more complex media query generation as in the margin grid.
262@mixin -zf-each-breakpoint($small: true, $auto-insert-breakpoints: true) {
263 $list: $breakpoint-classes;
264
265 @if not $small {
266 $list: sl-remove($list, $-zf-zero-breakpoint);
267 }
268
269 @each $name in $list {
270 $-zf-size: $name !global;
271
272 @if $auto-insert-breakpoints {
273 @include breakpoint($name) {
274 @content;
275 }
276 }
277 @else {
278 @content;
279 }
280 }
281}
282
283/// Generate the `@content` passed to the mixin with a value `$-zf-bp-value` related to a breakpoint, depending on the `$name` parameter:
284/// - For a single value, `$-zf-bp-value` is this value.
285/// - For a breakpoint name, `$-zf-bp-value` is the corresponding breakpoint value in `$map`.
286/// - For "auto", `$-zf-bp-value` is the corresponding breakpoint value in `$map` and is passed to `@content`, which is made responsive for each breakpoint of `$map`.
287/// @param {Number|Array|Keyword} $name [auto] - Single value, breakpoint name, or list of breakpoint names to use. "auto" by default.
288/// @param {Number|Map} $map - Map of breakpoints and values or single value to use.
289@mixin -zf-breakpoint-value(
290 $name: auto,
291 $map: null
292) {
293 @if $name == auto and type-of($map) == 'map' {
294 // "auto"
295 @each $k, $v in $map {
296 @include breakpoint($k) {
297 @include -zf-breakpoint-value($v, $map) {
298 @content;
299 }
300 }
301 }
302 }
303 @else {
304 // breakpoint name
305 @if type-of($name) == 'string' {
306 $name: -zf-get-bp-val($map, $name);
307 }
308
309 // breakpoint value
310 $-zf-bp-value: $name !global;
311 @content;
312 }
313}