├── .editorconfig
├── .gitignore
├── .prettierrc
├── .sassdocrc
├── .travis.yml
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── UPGRADING.md
├── _mq.import.scss
├── _mq.scss
├── bower.json
├── docs
├── assets
│ ├── css
│ │ └── main.css
│ ├── images
│ │ ├── favicon.png
│ │ ├── logo_full_compact.svg
│ │ ├── logo_full_inline.svg
│ │ ├── logo_light_compact.svg
│ │ └── logo_light_inline.svg
│ └── js
│ │ ├── main.js
│ │ ├── main.min.js
│ │ ├── search.js
│ │ ├── sidebar.js
│ │ └── vendor
│ │ ├── fuse.min.js
│ │ ├── jquery.min.js
│ │ └── prism.min.js
└── index.html
├── examples
├── advanced
│ ├── _layout.scss
│ ├── _mq-settings.scss
│ ├── _typography-headings.scss
│ ├── _typography.scss
│ ├── advanced.css
│ └── advanced.scss
├── basic
│ ├── basic.css
│ └── basic.scss
├── custom
│ ├── custom.css
│ └── custom.scss
└── legacy
│ ├── legacy.css
│ └── legacy.scss
├── icon.png
├── package-lock.json
├── package.json
├── scripts
└── sassdoc.sh
├── show-breakpoints.gif
└── test
├── mq-breakpoints.spec.scss
├── mq-media-type.spec.scss
├── mq-range-feature.spec.scss
├── mq-show-breakpoints.spec.scss
├── mq.spec.scss
└── scss.spec.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | ; This file is for unifying the coding style for different editors and IDEs
2 | ; See editorconfig.org
3 |
4 | ; top-most EditorConfig file
5 | root = true
6 |
7 | [*]
8 | indent_style = space
9 | indent_size = 2
10 | end_of_line = lf
11 | charset = utf-8
12 | trim_trailing_whitespace = true
13 | insert_final_newline = true
14 |
15 | [*.md]
16 | trim_trailing_whitespace = false
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .eyeglass-cache
2 | *.sassc
3 | .sass-cache
4 | **.orig
5 | .DS_Store
6 | bower_components
7 | node_modules
8 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "all",
3 | "tabWidth": 2,
4 | "semi": true,
5 | "singleQuote": true,
6 | "arrowParens": "always"
7 | }
8 |
--------------------------------------------------------------------------------
/.sassdocrc:
--------------------------------------------------------------------------------
1 | {
2 | "package": {
3 | "title": "Sass MQ+",
4 | "name": "@mcaskill/sass-mq",
5 | "homepage": "https://github.com/mcaskill/sass-mq",
6 | "description": "mq()+ is a Sass library that helps manipulating media queries in an elegant way."
7 | },
8 | "autofill": "false"
9 | }
10 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '12'
4 | - '13'
5 | - '14'
6 | before_script:
7 | - npm install
8 | script:
9 | - npm test
10 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](http://keepachangelog.com/)
6 | and this project adheres to [Semantic Versioning](http://semver.org/).
7 |
8 |
9 |
10 | ## v6.0.0 - 2022-06-20
11 |
12 | Replaces version **[6.0.0](https://github.com/sass-mq/sass-mq/releases/tag/v6.0.0)** of [Sass-MQ](https://github.com/sass-mq/sass-mq).
13 |
14 | > This fork has rebased its history from the original sass-mq to rebuild its enhancements on the latest codebase.
15 |
16 | ## Changes prior to v6.0.0
17 |
18 | Changes prior to v6.0.0 were logged in https://github.com/mcaskill/sass-mq/releases
19 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013-2022 Chauncey McAskill, Guardian Media Group and contributors
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |

3 |
4 |
5 | # Media Queries with superpowers [](https://app.travis-ci.com/github/mcaskill/sass-mq/branches)
6 |
7 | **`mq()`+** is a [Sass](http://sass-lang.com/ "Sass - Syntactically Awesome Stylesheets")
8 | library that helps you compose media queries in an elegant way.
9 |
10 | If you already use [@kaelig](https://github.com/kaelig)'s mixin, you know how to use MQ+.
11 |
12 | This fork provides various, often much-requested, enhancements over the original mixin.
13 |
14 | ## Features
15 |
16 | > 👋 Note: This fork matches the same version tags of the original package.
17 |
18 | - Moved core operations from the _mixin_ to a _function_
19 | - This separation allows media queries to be chained through the `$and` and new `$or` parameters
20 | - Added a `$range-feature` parameter to allow media queries to target a different feature (device dimensions, aspect ratios, color, and resolution)
21 |
22 | See [breaking changes to the API](#breaking-changes).
23 |
24 | > A variant of the mixin using [Jacket](https://github.com/at-import/jacket),
25 | for rasterization, can be found here: [`mj()`](https://gist.github.com/mcaskill/89944b7ef12f37c85c05).
26 |
27 | Here is a very basic example:
28 |
29 | ```scss
30 | @use 'mq' as * with (
31 | $breakpoints: (
32 | mobile: 320px,
33 | tablet: 740px,
34 | desktop: 980px,
35 | wide: 1300px,
36 | )
37 | );
38 |
39 | .foo {
40 | @include mq($from: mobile, $until: tablet) {
41 | background: red;
42 | }
43 | @include mq($from: tablet, $or: mq($until: mobile)) {
44 | background: green;
45 | }
46 | @include mq($from: 600px, $range-feature: height) {
47 | font-size: 1.25em;
48 | }
49 | }
50 | ```
51 |
52 | Compiles to:
53 |
54 | ```css
55 | @media (min-width: 20em) and (max-width: 46.24em) {
56 | .foo {
57 | background: red;
58 | }
59 | }
60 | @media (min-width: 46.25em), (max-width: 19.99em) {
61 | .foo {
62 | background: green;
63 | }
64 | }
65 | @media (min-height: 37.5em) {
66 | .foo {
67 | font-size: 125em;
68 | }
69 | }
70 | ```
71 |
72 | ## How to use it
73 |
74 | > 👋 Note: This library will assume you are familiar with
75 | > the [original mixin](https://github.com/sass-mq/sass-mq/tree/v6.0.0#how-to-use-it)
76 | > and [Dart Sass](https://github.com/sass/dart-sass).
77 |
78 | 1. Install:
79 |
80 | - with [Bower](http://bower.io/ 'Bower: A package manager for the web'): `bower install mcaskill-sass-mq@6 --save`
81 | - with [npm](https://www.npmjs.com/): `npm install @mcaskill/sass-mq@6 --save`
82 | - with [yarn](https://www.yarnpkg.com/): `yarn add @mcaskill/sass-mq@6`
83 |
84 | OR [Download \_mq.scss](https://raw.github.com/mcaskill/sass-mq/6.x/_mq.scss) into your Sass project.
85 |
86 | 2. Import the partial in your Sass files and override default settings
87 | with your own preferences:
88 |
89 | ```scss
90 | // Name your breakpoints in a way that creates a ubiquitous language
91 | // across team members. It will improve communication between
92 | // stakeholders, designers, developers, and testers.
93 | $breakpoints: (
94 | mobile: 320px,
95 | tablet: 740px,
96 | desktop: 980px,
97 | wide: 1300px,
98 | // Tweakpoints
99 | desktopAd: 810px,
100 | mobileLandscape: 480px,
101 | );
102 |
103 | // If you want to display the currently active breakpoint in the top
104 | // right corner of your site during development, add the breakpoints
105 | // to this list, ordered by width. For examples: (mobile, tablet, desktop).
106 | $show-breakpoints: (mobile, mobileLandscape, tablet, desktop, wide);
107 |
108 | @use 'path/to/mq' with (
109 | $breakpoints: $breakpoints,
110 | $show-breakpoints: $show-breakpoints,
111 | $range-feature: height
112 | );
113 | ```
114 |
115 | ### Breaking changes
116 |
117 | While the original mixin takes up to five parameters, the enhanced
118 | mixin and function take up to seven parameters which changes the position
119 | of the last two parameters:
120 |
121 | ```diff
122 | @mixin mq(
123 | $from: false, // One of the mapped breakpoints
124 | $until: false, // One of the mapped breakpoints
125 | $and: false, // Additional media query parameters
126 | + $or: false, // Alternate media query parameters
127 | + $range-feature: $range-feature // Media range feature (width, height…)
128 | $media-type: $media-type, // Media type (screen, print…)
129 | $breakpoints: $breakpoints // Map of breakpoints
130 | )
131 | ```
132 |
133 | ### Responsive mode
134 |
135 | `mq()` takes up to four optional parameters:
136 |
137 | - `$from`: _inclusive_ `min-*` boundary
138 | - `$until`: _exclusive_ `max-*` boundary
139 | - `$and`: additional custom directives
140 | - `$or`: alternate custom directives
141 |
142 | Note that `$until` as a keyword is a hard limit i.e. it's breakpoint - 1.
143 |
144 | ```scss
145 | @use 'mq';
146 |
147 | .responsive {
148 | // Apply styling to mobile and upwards
149 | @include mq.mq($from: mobile) {
150 | color: red;
151 | }
152 | // Apply styling up to devices smaller than tablets (exclude tablets)
153 | @include mq.mq($until: tablet) {
154 | color: blue;
155 | }
156 | // Same thing, in landscape orientation
157 | @include mq.mq($until: tablet, $and: '(orientation: landscape)') {
158 | color: hotpink;
159 | }
160 | // Apply styling to tablets up to desktop (exclude desktop)
161 | @include mq.mq(tablet, desktop) {
162 | color: green;
163 | }
164 | }
165 | ```
166 |
167 | ### Adding custom breakpoints
168 |
169 | ```scss
170 | @include add-breakpoint(tvscreen, 1920px);
171 |
172 | .hide-on-tv {
173 | @include mq(tvscreen) {
174 | display: none;
175 | }
176 | }
177 | ```
178 |
179 | ### Seeing the currently active breakpoint
180 |
181 | While developing, it can be nice to always know which breakpoint is
182 | active. To achieve this, set the `$show-breakpoints` variable to
183 | be a list of the breakpoints you want to debug, ordered by width.
184 | The name of the active breakpoint and its pixel and em values will
185 | then be shown in the top right corner of the viewport.
186 |
187 | ```scss
188 | // Adapt the list to include breakpoint names from your project
189 | $show-breakpoints: (phone, phablet, tablet);
190 |
191 | @use 'path/to/mq' with (
192 | $show-breakpoints: $show-breakpoints
193 | );
194 | ```
195 |
196 | 
197 |
198 | ### Changing range feature
199 |
200 | If you want to specify a range feature, for example to write breakpoints
201 | for height first, set `$range-feature`:
202 |
203 | #### SCSS
204 |
205 | ```scss
206 | @use 'mq' with (
207 | $range-feature: height
208 | );
209 |
210 | .hero {
211 | @include mq.mq(mobile) {
212 | height: 300px;
213 | }
214 | }
215 | ```
216 |
217 | #### CSS output
218 |
219 | ```css
220 | @media screen and (max-height: 19.99em) {
221 | .hero {
222 | height: 300px;
223 | }
224 | }
225 | ```
226 |
227 | ### Changing media type
228 |
229 | If you want to specify a media type, for example to output styles
230 | for screens only, set `$media-type`:
231 |
232 | #### SCSS
233 |
234 | ```scss
235 | @use 'mq' with (
236 | $media-type: screen
237 | );
238 |
239 | .screen-only-element {
240 | @include mq.mq(mobile) {
241 | width: 300px;
242 | }
243 | }
244 | ```
245 |
246 | #### CSS output
247 |
248 | ```css
249 | @media screen and (max-width: 19.99em) {
250 | .screen-only-element {
251 | width: 300px;
252 | }
253 | }
254 | ```
255 |
256 | ### Implementing sass-mq in your project
257 |
258 | Please see the `examples` folder which contains a variety of examples on how to implement "sass-mq"
259 |
260 | ### Backward compatibility with `@import`
261 |
262 | Just in case you need to have backward compatibility and want to use`@import` instead of `@use`,
263 | you can do so by importing `_mq.import.scss` instead of `_mq.scss`.
264 |
265 | Please see `legacy.scss` on `examples` folder.
266 |
267 | ## Running tests
268 |
269 | ```sh
270 | npm test
271 | ```
272 |
273 | ## Generating the documentation
274 |
275 | Sass MQ is documented using [SassDoc](http://sassdoc.com/).
276 |
277 | Generate the documentation locally:
278 |
279 | ```sh
280 | sassdoc .
281 | ```
282 |
283 | Generate & deploy the documentation to :
284 |
285 | ```sh
286 | npm run sassdoc
287 | ```
288 |
289 | ---
290 |
291 | > Sass MQ was crafted in-house at the Guardian and is improved upon by many contributors.
292 |
293 | Thank you to @kaelig, @sndrs, @area73, and contributors for the original mixin.
294 |
295 | ❤️
296 |
--------------------------------------------------------------------------------
/UPGRADING.md:
--------------------------------------------------------------------------------
1 | # Upgrading Guide
2 |
3 | ## Upgrade to 6.0
4 |
5 | Rename `$media-feature` to `$range-feature` to better [reflect][mdn-css-targeting-media-features]
6 | that the customizable media feature is prefixed with "min-" or "max-" to express
7 | "minimum condition" or "maximum condition" constraints.
8 |
9 | ```scss
10 | // @mcaskill/sass-mq v5
11 | .hero {
12 | @include mq.mq(mobile, $media-feature: height) {
13 | height: 300px;
14 | }
15 | }
16 |
17 | // @mcaskill/sass-mq v6
18 | .hero {
19 | @include mq.mq(mobile, $range-feature: height) {
20 | height: 300px;
21 | }
22 | }
23 | ```
24 |
25 | [mdn-css-targeting-media-features]: https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries#targeting_media_features
26 |
--------------------------------------------------------------------------------
/_mq.import.scss:
--------------------------------------------------------------------------------
1 | @forward 'mq' as mq-*;
2 | @forward 'mq' hide show-breakpoints, add-breakpoint, get-breakpoint-length,
3 | stringify, px2em, $range-feature, $media-type, $show-breakpoints, $breakpoints;
4 |
--------------------------------------------------------------------------------
/_mq.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:math';
2 | @use 'sass:map';
3 | @use 'sass:list';
4 |
5 | /// Breakpoint list
6 | ///
7 | /// Name your breakpoints in a way that creates a ubiquitous language
8 | /// across team members. It will improve communication between
9 | /// stakeholders, designers, developers, and testers.
10 | ///
11 | /// @type Map
12 | /// @link https://github.com/mcaskill/sass-mq#seeing-the-currently-active-breakpoint Full documentation and examples
13 | $breakpoints: (
14 | mobile: 320px,
15 | tablet: 740px,
16 | desktop: 980px,
17 | wide: 1300px,
18 | ) !default;
19 |
20 | /// Show breakpoints in the top right corner
21 | ///
22 | /// If you want to display the currently active breakpoint in the top
23 | /// right corner of your site during development, add the breakpoints
24 | /// to this list, ordered by length. For example: (mobile, tablet, desktop).
25 | ///
26 | /// @example scss
27 | /// @use 'path/to/mq' with ($show-breakpoints: ('mobile', 'tablet', 'desktop'));
28 | ///
29 | ///
30 | /// @type map
31 | $show-breakpoints: () !default;
32 |
33 | /// Customize the media range feature (for example: `@media (min-width…)`
34 | /// or `@media (min-height:…)`)
35 | /// By default sass-mq uses an `width` range feature.
36 | ///
37 | /// If you want to overried the range feature, you can use this option.
38 | /// @example scss
39 | /// @use 'path/to/mq' with ($range-feature: height);
40 | ///
41 | /// @type String
42 | /// @link https://github.com/mcaskill/sass-mq#changing-range-feature Full documentation and example
43 | $range-feature: width !default;
44 |
45 | /// Customize the media type (for example: `@media screen` or `@media print`)
46 | /// By default sass-mq uses an "all" media type (`@media all and …`)
47 | ///
48 | /// If you want to overried the media type, you can use this option.
49 | /// @example scss
50 | /// @use 'path/to/mq' with ($media-type: 'screen');
51 | ///
52 | /// @type String
53 | /// @link https://github.com/mcaskill/sass-mq#changing-media-type Full documentation and example
54 | $media-type: all !default;
55 |
56 | /// Convert pixels to ems
57 | ///
58 | /// @param {Number} $px - value to convert
59 | ///
60 | /// @example scss
61 | /// $font-size-in-ems: px2em(16px);
62 | /// p { font-size: px2em(16px); }
63 | ///
64 | /// @returns {Number}
65 | @function px2em($px) {
66 | @if math.is-unitless($px) {
67 | @warn "Assuming #{$px} to be in pixels, attempting to convert it into pixels.";
68 | @return px2em($px * 1px);
69 | }
70 | // if $px is compatible with em units, then return value unchanged
71 | @if math.compatible($px, 1em) {
72 | @return $px;
73 | }
74 | @return math.div($px, 16px) * 1em;
75 | }
76 |
77 | /// Get a breakpoint's length
78 | ///
79 | /// @param {String} $name - Name of the breakpoint. One of $breakpoints
80 | ///
81 | /// @example scss
82 | /// $tablet-width: get-breakpoint-length(tablet);
83 | /// @media (min-width: get-breakpoint-length(tablet)) {}
84 | ///
85 | /// @requires {Variable} $breakpoints
86 | ///
87 | /// @returns {Number} Value in pixels
88 | @function get-breakpoint-length($name, $breakpoints: $breakpoints) {
89 | @if map.has-key($breakpoints, $name) {
90 | @return map.get($breakpoints, $name);
91 | } @else {
92 | @warn "Breakpoint #{$name} wasn't found in $breakpoints.";
93 | @return null;
94 | }
95 | }
96 |
97 | /// Joins all elements of `$list` with `$glue`.
98 | ///
99 | /// @ignore Documentation: https://github.com/at-import/SassyLists/blob/master/stylesheets/functions/_to-string.scss
100 | ///
101 | /// @param {List} $list - list to cast
102 | /// @param {String} $glue [' and '] - value to use as a join string
103 | ///
104 | /// @example scss
105 | /// stringify(a b c)
106 | /// // a and b and c
107 | ///
108 | /// @example scss
109 | /// stringify(a b c, ', ')
110 | /// // a, b, c
111 | ///
112 | /// @returns {String}
113 | @function stringify($list, $glue: ' and ') {
114 | $result: '';
115 |
116 | @each $item in $list {
117 | $result: $result + if(length($item) > 1, stringify($item, $glue), $item);
118 |
119 | @if $item != nth($list, -1) {
120 | $result: $result + $glue;
121 | }
122 | }
123 |
124 | @return quote($result);
125 | }
126 |
127 | /// Media Query function
128 | ///
129 | /// Computes a media query based on a list of conditions.
130 | ///
131 | /// @param {String | Boolean} $from [false] - One of $breakpoints
132 | /// @param {String | Boolean} $until [false] - One of $breakpoints
133 | /// @param {String | Boolean} $and [false] - Additional media query parameters
134 | /// @param {String | Boolean} $or [false] - Alternative media query parameters
135 | /// @param {String} $range-feature [$range-feature] - Media range feature: width, height…
136 | /// @param {String} $media-type [$media-type] - Media type: screen, print…
137 | ///
138 | /// @ignore Undocumented API, for advanced use only:
139 | /// @ignore @param {Map} $breakpoints [$breakpoints]
140 | ///
141 | /// @requires {Variable} $range-feature
142 | /// @requires {Variable} $media-type
143 | /// @requires {Variable} $breakpoints
144 | /// @requires {function} stringify
145 | ///
146 | /// @example scss
147 | /// $mq-lap-and-up: mq($from: mobile);
148 | ///
149 | /// $mq-palm: mq($until: tablet);
150 | ///
151 | /// $mq-lap: mq(mobile, tablet);
152 | ///
153 | /// $mq-portable: mq($from: tablet, $and: '(orientation: landscape)');
154 | ///
155 | /// $mq-desk-small: mq(950px) {
156 | ///
157 | /// $mq-portable-screen: mq(tablet, $media-type: screen) {
158 | ///
159 | /// // Advanced use:
160 | /// $my-breakpoints: (L: 900px, XL: 1200px);
161 | /// $mq-custom: mq(L, $breakpoints: $my-breakpoints);
162 | @function mq(
163 | $from: false,
164 | $until: false,
165 | $and: false,
166 | $or: false,
167 | $range-feature: $range-feature,
168 | $media-type: $media-type,
169 | $breakpoints: $breakpoints
170 | ) {
171 | $min-value: 0;
172 | $max-value: 0;
173 | $media-query: ();
174 |
175 | // From: this breakpoint (inclusive)
176 | @if $from {
177 | @if type-of($from) == number {
178 | $min-value: px2em($from);
179 | } @else {
180 | $min-value: px2em(get-breakpoint-length($from, $breakpoints));
181 | }
182 | }
183 |
184 | // Until: that breakpoint (exclusive)
185 | @if $until {
186 | @if type-of($until) == number {
187 | $max-value: px2em($until);
188 | } @else {
189 | $max-value: px2em(get-breakpoint-length($until, $breakpoints)) - 0.01em;
190 | }
191 | }
192 |
193 | @if $range-feature {
194 | @if $min-value != 0 {
195 | $media-query: append($media-query, '(min-#{$range-feature}: #{$min-value})');
196 | }
197 | @if $max-value != 0 {
198 | $media-query: append($media-query, '(max-#{$range-feature}: #{$max-value})');
199 | }
200 | }
201 |
202 | @if $and {
203 | $media-query: append($media-query, '#{$and}');
204 | }
205 |
206 | $media-query: stringify($media-query, ' and ');
207 |
208 | // Prevent unnecessary media query prefix 'all and '
209 | @if ($media-type != 'all' and $media-query != '') {
210 | $media-query: '#{$media-type} and #{$media-query}';
211 | }
212 | @else if $media-query == '' {
213 | $media-query: $media-type;
214 | }
215 |
216 | @if $or {
217 | $media-query: append($media-query, '#{$or}');
218 | $media-query: stringify($media-query, ', ');
219 | }
220 |
221 | $media-query: unquote("#{$media-query}");
222 |
223 | @return $media-query;
224 | }
225 |
226 | /// Media Query mixin
227 | ///
228 | /// Generates a media query block, based on a list of conditions, around a set
229 | /// of nested CSS statements.
230 | ///
231 | /// @param {String | Boolean} $from [false] - One of $breakpoints
232 | /// @param {String | Boolean} $until [false] - One of $breakpoints
233 | /// @param {String | Boolean} $and [false] - Additional media query parameters
234 | /// @param {String | Boolean} $or [false] - Alternative media query parameters
235 | /// @param {String} $range-feature [$range-feature] - Media range feature: width, height…
236 | /// @param {String} $media-type [$media-type] - Media type: screen, print…
237 | ///
238 | /// @ignore Undocumented API, for advanced use only:
239 | /// @ignore @param {Map} $breakpoints [$breakpoints]
240 | ///
241 | /// @content styling rules, wrapped into a @media query
242 | ///
243 | /// @requires {Variable} $range-feature
244 | /// @requires {Variable} $media-type
245 | /// @requires {Variable} $breakpoints
246 | /// @requires {function} mq
247 | ///
248 | /// @link https://github.com/mcaskill/sass-mq#responsive-mode Full documentation and examples
249 | ///
250 | /// @example scss
251 | /// @use 'path/to/mq' as *;
252 | /// .element {
253 | /// @include mq($from: mobile) {
254 | /// color: red;
255 | /// }
256 | /// @include mq($until: tablet) {
257 | /// color: blue;
258 | /// }
259 | /// @include mq(mobile, tablet) {
260 | /// color: green;
261 | /// }
262 | /// @include mq($from: tablet, $and: '(orientation: landscape)') {
263 | /// color: teal;
264 | /// }
265 | /// @include mq(950px) {
266 | /// color: hotpink;
267 | /// }
268 | /// @include mq(tablet, $media-type: screen) {
269 | /// color: hotpink;
270 | /// }
271 | /// // Advanced use:
272 | /// $my-breakpoints: (L: 900px, XL: 1200px);
273 | /// @include mq(L, $breakpoints: $my-breakpoints) {
274 | /// color: hotpink;
275 | /// }
276 | /// }
277 | @mixin mq(
278 | $from: false,
279 | $until: false,
280 | $and: false,
281 | $or: false,
282 | $range-feature: $range-feature,
283 | $media-type: $media-type,
284 | $breakpoints: $breakpoints
285 | ) {
286 | $media-query: mq(
287 | $from,
288 | $until,
289 | $and,
290 | $or,
291 | $range-feature,
292 | $media-type,
293 | $breakpoints
294 | );
295 |
296 | @media #{$media-query} {
297 | @content;
298 | }
299 | }
300 |
301 | /// Quick sort
302 | ///
303 | /// @author Sam Richards
304 | /// @access private
305 | /// @param {List} $list - List to sort
306 | /// @returns {List} Sorted List
307 | @function _quick-sort($list) {
308 | $less: ();
309 | $equal: ();
310 | $large: ();
311 |
312 | @if length($list) > 1 {
313 | $seed: list.nth($list, math.ceil(math.div(length($list), 2)));
314 |
315 | @each $item in $list {
316 | @if ($item == $seed) {
317 | $equal: list.append($equal, $item);
318 | } @else if ($item < $seed) {
319 | $less: list.append($less, $item);
320 | } @else if ($item > $seed) {
321 | $large: list.append($large, $item);
322 | }
323 | }
324 |
325 | @return join(join(_quick-sort($less), $equal), _quick-sort($large));
326 | }
327 |
328 | @return $list;
329 | }
330 |
331 | /// Sort a map by values (works with numbers only)
332 | ///
333 | /// @access private
334 | /// @param {Map} $map - Map to sort
335 | /// @returns {Map} Map sorted by value
336 | @function _map-sort-by-value($map) {
337 | $map-sorted: ();
338 | $map-keys: map.keys($map);
339 | $map-values: map.values($map);
340 | $map-values-sorted: _quick-sort($map-values);
341 |
342 | // Reorder key/value pairs based on key values
343 | @each $value in $map-values-sorted {
344 | $index: index($map-values, $value);
345 | $key: list.nth($map-keys, $index);
346 | $map-sorted: map.merge(
347 | $map-sorted,
348 | (
349 | $key: $value,
350 | )
351 | );
352 |
353 | // Unset the value in $map-values to prevent the loop
354 | // from finding the same index twice
355 | $map-values: list.set-nth($map-values, $index, 0);
356 | }
357 |
358 | @return $map-sorted;
359 | }
360 |
361 | /// Add a breakpoint
362 | ///
363 | /// @param {String} $name - Name of the breakpoint
364 | /// @param {Number} $length - Length of the breakpoint
365 | ///
366 | /// @requires {Variable} $breakpoints
367 | ///
368 | /// @example scss
369 | /// @include add-breakpoint(tvscreen, 1920px);
370 | /// @include mq(tvscreen) {}
371 | @mixin add-breakpoint($name, $length) {
372 | $new-breakpoint: (
373 | $name: $length,
374 | );
375 | $breakpoints: map.merge($breakpoints, $new-breakpoint) !global;
376 | $breakpoints: _map-sort-by-value($breakpoints) !global;
377 | }
378 |
379 | /// Show the active breakpoint in the top right corner of the viewport
380 | /// @link https://github.com/mcaskill/sass-mq#seeing-the-currently-active-breakpoint
381 | ///
382 | /// @param {List} $show-breakpoints [$show-breakpoints] - List of breakpoints to show in the top right corner
383 | /// @param {Map} $breakpoints [$breakpoints] - Breakpoint names and sizes
384 | ///
385 | /// @requires {Variable} $breakpoints
386 | /// @requires {Variable} $show-breakpoints
387 | ///
388 | /// @example scss
389 | /// // Show breakpoints using global settings
390 | /// @include show-breakpoints;
391 | ///
392 | /// // Show breakpoints using custom settings
393 | /// @include show-breakpoints((L, XL), (S: 300px, L: 800px, XL: 1200px));
394 | @mixin show-breakpoints(
395 | $show-breakpoints: $show-breakpoints,
396 | $breakpoints: $breakpoints
397 | ) {
398 | body:before {
399 | background-color: #fcf8e3;
400 | border-bottom: 1px solid #fbeed5;
401 | border-left: 1px solid #fbeed5;
402 | color: #c09853;
403 | font: small-caption;
404 | padding: 3px 6px;
405 | pointer-events: none;
406 | position: fixed;
407 | right: 0;
408 | top: 0;
409 | z-index: 100;
410 |
411 | // Loop through the breakpoints that should be shown
412 | @each $show-breakpoint in $show-breakpoints {
413 | $length: get-breakpoint-length($show-breakpoint, $breakpoints);
414 | @include mq($show-breakpoint, $breakpoints: $breakpoints) {
415 | content: '#{$show-breakpoint} ≥ #{$length} (#{px2em($length)})';
416 | }
417 | }
418 | }
419 | }
420 |
421 | @if list.length($show-breakpoints) > 0 {
422 | @include show-breakpoints;
423 | }
424 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mcaskill-sass-mq",
3 | "description": "mq()+ is a Sass library that helps manipulating media queries in an elegant way.",
4 | "keywords": [
5 | "responsive",
6 | "sass",
7 | "rwd",
8 | "mediaquery",
9 | "query",
10 | "queries",
11 | "media"
12 | ],
13 | "main": "_mq.scss",
14 | "authors": [
15 | {
16 | "name": "Chauncey McAskill",
17 | "email": "chauncey@mcaskill.ca",
18 | "homepage": "https://mcaskill.ca"
19 | },
20 | {
21 | "name": "Guardian Media Group and Contributors",
22 | "homepage": "https://github.com/sass-mq/sass-mq"
23 | }
24 | ],
25 | "ignore": [
26 | "test",
27 | "sassdoc",
28 | "**/.*",
29 | "sassdoc.sh",
30 | "test.sh"
31 | ],
32 | "licenses": [
33 | {
34 | "type": "MIT",
35 | "url": "http://opensource.org/licenses/MIT"
36 | }
37 | ],
38 | "repository": {
39 | "type": "git",
40 | "url": "https://github.com/mcaskill/sass-mq"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/docs/assets/css/main.css:
--------------------------------------------------------------------------------
1 | .container:after,.header:after,.searchbar:after{content:"";display:table;clear:both}.visually-hidden{width:1px;height:1px;position:absolute;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}.sidebar__title{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}code[class*='language-'],pre[class*='language-']{color:black;text-shadow:0 1px white;font-family:Consolas, Monaco, 'Andale Mono', monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*='language-']::-moz-selection,pre[class*='language-'] ::-moz-selection,code[class*='language-']::-moz-selection,code[class*='language-'] ::-moz-selection{text-shadow:none;background:#b3d4fc}pre[class*='language-']::selection,pre[class*='language-'] ::selection,code[class*='language-']::selection,code[class*='language-'] ::selection{text-shadow:none;background:#b3d4fc}@media print{code[class*='language-'],pre[class*='language-']{text-shadow:none}}pre[class*='language-']{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*='language-'],pre[class*='language-']{background:white}:not(pre)>code[class*='language-']{padding:.1em;border-radius:.3em}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:slategray}.token.punctuation{color:#999}.namespace{opacity:.7}.token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol{color:#905}.token.selector,.token.attr-name,.token.string,.token.builtin{color:#690}.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string,.token.variable{color:#a67f59;background:rgba(255,255,255,0.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.regex,.token.important{color:#e90}.token.important{font-weight:bold}.token.entity{cursor:help}html{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*,*::after,*::before{-webkit-box-sizing:inherit;-moz-box-sizing:inherit;box-sizing:inherit}body{font:1em/1.35 "Open Sans","Helvetica Neue Light","Helvetica Neue","Helvetica","Arial",sans-serif;overflow:auto;margin:0}a{transition:0.15s;text-decoration:none;color:#dd5a6f}a:hover,a:hover code{color:#333}table p{margin:0 0 .5rem}:not(pre)>code{color:#dd5a6f;white-space:nowrap;font-weight:normal}@media (max-width: 800px){table,tbody,tr,td,th{display:block}thead{width:1px;height:1px;position:absolute;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);border:0}tr{padding-bottom:1em;margin-bottom:1em;border-bottom:2px solid #ddd}td::before,th::before{content:attr(data-label) ": ";text-transform:capitalize;font-weight:bold}td p,th p{display:inline}}.layout-toggle{display:none}@media (min-width: 801px){.layout-toggle{position:absolute;top:8px;left:20px;font-size:2em;cursor:pointer;color:white;display:block}}@media (min-width: 801px){.sidebar-closed .sidebar{-webkit-transform:translateX(-280px);-ms-transform:translateX(-280px);transform:translateX(-280px)}.sidebar-closed .main{padding-left:0}.sidebar-closed .header{left:0}}.list-unstyled{padding-left:0;list-style:none;line-height:1.5;margin-top:0;margin-bottom:1.5rem}.list-inline li{display:inline-block}.container{max-width:100%;width:1170px;margin:0 auto;padding:0 2rem}.relative{position:relative}.clear{clear:both}.header{position:fixed;top:0;right:0;left:280px;box-shadow:0 2px 5px rgba(0,0,0,0.26);padding:1em 0;background:#dd5a6f;color:#e0e0e0;z-index:4000}@media (max-width: 800px){.header{left:0}}@media (min-width: 801px){.header{transition:0.2s cubic-bezier(0.215, 0.61, 0.355, 1)}}.header__title{font-weight:500;text-align:center;margin:0 0 0.5em 0}.header__title a{color:#e0e0e0}@media (min-width: 801px){.header__title{float:left;font-size:1em;margin-top:.25em;margin-bottom:0}}.searchbar{display:inline-block;float:right}@media (max-width: 800px){.searchbar{display:block;float:none}}.searchbar__form{float:right;position:relative}@media (max-width: 800px){.searchbar__form{float:none}}@media (min-width: 801px){.searchbar__form{min-width:15em}}.searchbar__field{border:none;padding:0.5em;font-size:1em;margin:0;width:100%;box-shadow:0 1.5px 4px rgba(0,0,0,0.24),0 1.5px 6px rgba(0,0,0,0.12);border:1px solid #e0e0e0}.searchbar__suggestions{position:absolute;top:100%;right:0;left:0;box-shadow:0 1.5px 4px rgba(0,0,0,0.24),0 1.5px 6px rgba(0,0,0,0.12);border:1px solid #e0e0e0;background:white;padding:0;margin:0;list-style:none;z-index:2}.searchbar__suggestions:empty{display:none}.searchbar__suggestions .selected{background:#ddd}.searchbar__suggestions li{border-bottom:1px solid #e0e0e0}.searchbar__suggestions li:last-of-type{border:none}.searchbar__suggestions a{display:block;padding:0.5em;font-size:0.9em}.searchbar__suggestions a:hover,.searchbar__suggestions a:active,.searchbar__suggestions a:focus{background:#e0e0e0}.searchbar__suggestions code{margin-right:.5em}@media (min-width: 801px){.sidebar{position:fixed;top:0;bottom:0;left:0;overflow:auto;box-shadow:1px 0 1.5px rgba(0,0,0,0.12);width:280px;z-index:2;border-right:1px solid #e0e0e0;transition:0.2s cubic-bezier(0.215, 0.61, 0.355, 1)}}@media (max-width: 800px){.sidebar{margin-top:4em}}.sidebar__annotation{color:#5c4863}.sidebar__item{font-size:0.9em}.sidebar__item a{padding:0.5em 4.5em;display:block;text-decoration:none;color:#333}.sidebar__item:hover,.sidebar__item:active,.sidebar__item:focus{background:#e0e0e0}.sidebar__item.is-collapsed+*{display:none}.sidebar__item--heading{padding:1em 1.5em}.sidebar__item--heading a{font-weight:bold}.sidebar__item--sub-heading{padding:0.5em 2.5em}.sidebar__item--sub-heading a{color:#888}.sidebar__item--heading,.sidebar__item--sub-heading{position:relative}.sidebar__item--heading:after,.sidebar__item--sub-heading:after{position:absolute;top:50%;right:2em;content:'\25BC';margin-top:-0.5em;color:#ddd;font-size:0.7em}.sidebar__item--heading.is-collapsed:after,.sidebar__item--sub-heading.is-collapsed:after{content:'\25B6'}.sidebar__item--heading a,.sidebar__item--sub-heading a{padding:0;display:inline}.sidebar__description{color:#e0e0e0;padding-right:2em}.sidebar__header{border-bottom:1px solid #e0e0e0}.sidebar__title{font-size:1em;margin:0;padding:1.45em}.btn-toggle{background:#EFEFEF;border:none;border-bottom:1px solid #e0e0e0;display:block;padding:1em;width:100%;cursor:pointer;color:#999;font-weight:bold;margin:0;transition:0.15s ease-out}.btn-toggle:hover,.btn-toggle:active,.btn-toggle:focus{background:#DFDFDF}.main{background:#f9f9f9;position:relative}@media (min-width: 801px){.main{transition:0.2s cubic-bezier(0.215, 0.61, 0.355, 1);padding-left:280px;padding-top:4em;min-height:45em}}.main__section{margin-top:5em;border-top:5px solid rgba(92,72,99,0.2)}.header+.main__section{margin-top:0;border-top:none}.main__heading,.main__heading--secondary{padding:1em 0;margin-top:0}@media (min-width: 801px){.main__heading,.main__heading--secondary{padding:2em 0 0}}.main__heading{color:#5c4863;font-size:3.5em;text-align:center;border-bottom:5px solid rgba(92,72,99,0.2);padding-bottom:.5em;margin-bottom:1em;background:rgba(92,72,99,0.1)}.main__heading--secondary{font-size:3em;color:#dd5a6f;text-transform:uppercase;font-weight:bold;padding-top:0;margin-bottom:-3rem;position:relative}.main__heading--secondary .container{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.main__heading--secondary::before{content:'';position:absolute;left:0;right:0;bottom:0.15em;height:0.2em;background-color:#dd5a6f}.main__description{margin-bottom:1.5rem}.footer{background:#e0e0e0;padding:1em 0}.footer .container{position:relative}.footer__project-info{float:left}.footer__watermark{position:absolute;right:0;top:-0.7em}.footer__watermark img{display:block;max-width:7em}.project-info__name,.project-info__version,.project-info__license{display:inline-block}.project-info__version,.project-info__license{color:#555}.project-info__license{text-indent:-0.25em}.main__section{margin-bottom:4.5rem}.item__heading{color:#333;margin:4.5rem 0 1.5rem 0;position:relative;font-size:2em;font-weight:300;float:left}.item__name{color:#dd5a6f}.item__example{margin-bottom:1.5rem}.item__example,.item__code{box-shadow:0 1.5px 4px rgba(0,0,0,0.24),0 1.5px 6px rgba(0,0,0,0.12);border:1px solid #e0e0e0;word-wrap:break-word;line-height:1.42}.item__code{padding-right:7em;clear:both;cursor:pointer}.item__code--togglable::after{position:absolute;right:0;bottom:-2.5em;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";opacity:0;color:#c4c4c4;font-size:0.8em;transition:0.2s ease-out}.item__code--togglable:hover::after,.item__code--togglable:active::after,.item__code--togglable:focus::after{-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";opacity:1}.item__code--togglable[data-current-state='expanded']::after{content:'Click to collapse.'}.item__code--togglable[data-current-state='collapsed']::after{content:'Click to expand.'}.example__description{padding:1em;background:#EFEFEF}.example__description p{margin:0}.example__code[class*='language-']{margin:0}.item__anchor{font-size:0.6em;color:#eeafb9}@media (min-width: 801px){.item__anchor{position:absolute;right:101%;bottom:.25em;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";opacity:0}.item:hover .item__anchor{-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";opacity:1}}.item__deprecated{display:inline-block;overflow:hidden;margin-top:5.5em;margin-left:1em}.item__deprecated strong{float:left;color:#c00;text-transform:uppercase}.item__deprecated p{float:left;margin:0;padding-left:0.5em}.item__type{color:#ddd;text-transform:capitalize;font-size:0.75em}.item__alias,.item__aliased{color:#ddd;font-size:0.8em}.item__sub-heading{color:#333;margin-top:0;margin-bottom:1.5rem;font-size:1.2em}.item__parameters{width:100%;margin-bottom:1em;border-collapse:collapse}.item__parameters thead th{vertical-align:bottom;border-bottom:2px solid #ddd;border-top:none;text-align:left;color:#707070}.item__parameters tbody th{text-align:left}.item__parameters td,.item__parameters th{padding:0.5em 0.5em 0.5em 0;vertical-align:top}@media (min-width: 801px){tbody>.item__parameter:first-of-type>td{border-top:none}.item__parameters td,.item__parameters th{border-top:1px solid #ddd}}.item__access{text-transform:capitalize;color:#5c4863;font-size:0.8em}.item__since{float:right;padding-top:0.9em;color:#c4c4c4;margin-bottom:1em}.item__source-link{position:absolute;top:1px;right:1px;background:white;padding:1em;z-index:2;color:#c4c4c4}.item__cross-type{color:#4d4d4d;font-family:'Consolas', 'Monaco', 'Andale Mono', monospace;font-size:0.8em}.item__description{margin-bottom:1.5rem}li.item__description{margin-bottom:0}.item__description--inline>*{display:inline-block;margin:0}.item__code-wrapper{position:relative;clear:both;margin-bottom:1.5rem}.color-preview--inline{padding:2px 4px;border:1px solid rgba(0,0,0,0.1);border-radius:3px}.color-preview--block{width:2em;height:2em;position:absolute;top:140%;right:0;top:calc(100% + 20px);border:1px solid rgba(0,0,0,0.1);border-radius:3px}
2 |
--------------------------------------------------------------------------------
/docs/assets/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mcaskill/sass-mq/f0c3d666657b3181c0f7ea094d561927d92abd90/docs/assets/images/favicon.png
--------------------------------------------------------------------------------
/docs/assets/images/logo_full_compact.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/assets/images/logo_full_inline.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/assets/images/logo_light_compact.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/assets/images/logo_light_inline.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/assets/js/main.js:
--------------------------------------------------------------------------------
1 | /* global document */
2 |
3 | (function ($, global) {
4 | 'use strict';
5 |
6 | // Constructor
7 | var App = function (conf) {
8 | this.conf = $.extend({
9 | // Search module
10 | search: new global.Search(),
11 |
12 | // Sidebar module
13 | sidebar: new global.Sidebar(),
14 |
15 | // Initialisation
16 | init: true
17 | }, conf || {});
18 |
19 | // Launch the module
20 | if (this.conf.init !== false) {
21 | this.initialize();
22 | }
23 | };
24 |
25 | // Initialisation method
26 | App.prototype.initialize = function () {
27 | this.codePreview();
28 | };
29 |
30 | // Toggle code preview collapsed/expanded modes
31 | App.prototype.codePreview = function () {
32 | var $item;
33 | var $code;
34 | var switchTo;
35 |
36 | $('.item__code--togglable').on('click', function () {
37 | $item = $(this);
38 | $code = $item.find('code');
39 | switchTo = $item.attr('data-current-state') === 'expanded' ? 'collapsed' : 'expanded';
40 |
41 | $item.attr('data-current-state', switchTo);
42 | $code.html($item.attr('data-' + switchTo));
43 | Prism.highlightElement($code[0]);
44 | });
45 | };
46 |
47 | global.App = App;
48 | }(window.jQuery, window));
49 |
50 | (function ($, global) {
51 |
52 | $(document).ready(function () {
53 | var app = new global.App();
54 | });
55 |
56 | }(window.jQuery, window));
--------------------------------------------------------------------------------
/docs/assets/js/main.min.js:
--------------------------------------------------------------------------------
1 | !function(t){function e(t,n){this.list=t,this.options=n=n||{};var i,o,s;for(i=0,keys=["sort","includeScore","shouldSort"],o=keys.length;o>i;i++)s=keys[i],this.options[s]=s in n?n[s]:e.defaultOptions[s];for(i=0,keys=["searchFn","sortFn","keys","getFn"],o=keys.length;o>i;i++)s=keys[i],this.options[s]=n[s]||e.defaultOptions[s]}var n=function(t,e){if(e=e||{},this.options=e,this.options.location=e.location||n.defaultOptions.location,this.options.distance="distance"in e?e.distance:n.defaultOptions.distance,this.options.threshold="threshold"in e?e.threshold:n.defaultOptions.threshold,this.options.maxPatternLength=e.maxPatternLength||n.defaultOptions.maxPatternLength,this.pattern=e.caseSensitive?t:t.toLowerCase(),this.patternLen=t.length,this.patternLen>this.options.maxPatternLength)throw new Error("Pattern length is too long");this.matchmask=1<i;)this._bitapScore(e,l+o)<=u?i=o:d=o,o=Math.floor((d-i)/2+i);for(d=o,s=Math.max(1,l-o+1),r=Math.min(l+o,c)+this.patternLen,a=Array(r+2),a[r+1]=(1<=s;n--)if(p=this.patternAlphabet[t.charAt(n-1)],a[n]=0===e?(a[n+1]<<1|1)&p:(a[n+1]<<1|1)&p|((h[n+1]|h[n])<<1|1)|h[n+1],a[n]&this.matchmask&&(g=this._bitapScore(e,n-1),u>=g)){if(u=g,f=n-1,m.push(f),!(f>l))break;s=Math.max(1,2*l-f)}if(this._bitapScore(e+1,l)>u)break;h=a}return{isMatch:f>=0,score:g}};var i={deepValue:function(t,e){for(var n=0,e=e.split("."),i=e.length;i>n;n++){if(!t)return null;t=t[e[n]]}return t}};e.defaultOptions={id:null,caseSensitive:!1,includeScore:!1,shouldSort:!0,searchFn:n,sortFn:function(t,e){return t.score-e.score},getFn:i.deepValue,keys:[]},e.prototype.search=function(t){var e,n,o,s,r,a=new this.options.searchFn(t,this.options),h=this.list,p=h.length,c=this.options,l=this.options.keys,u=l.length,f=[],d={},g=[],m=function(t,e,n){void 0!==t&&null!==t&&"string"==typeof t&&(s=a.search(t),s.isMatch&&(r=d[n],r?r.score=Math.min(r.score,s.score):(d[n]={item:e,score:s.score},f.push(d[n]))))};if("string"==typeof h[0])for(var e=0;p>e;e++)m(h[e],e,e);else for(var e=0;p>e;e++)for(o=h[e],n=0;u>n;n++)m(this.options.getFn(o,l[n]),o,e);c.shouldSort&&f.sort(c.sortFn);for(var y=c.includeScore?function(t){return f[t]}:function(t){return f[t].item},L=c.id?function(t){return i.deepValue(y(t),c.id)}:function(t){return y(t)},e=0,v=f.length;v>e;e++)g.push(L(e));return g},"object"==typeof exports?module.exports=e:"function"==typeof define&&define.amd?define(function(){return e}):t.Fuse=e}(this);(function($,global){var Sidebar=function(conf){this.conf=$.extend({collapsedClass:"is-collapsed",storageKey:"_sassdoc_sidebar_index",indexAttribute:"data-slug",toggleBtn:".js-btn-toggle",init:true},conf||{});if(this.conf.init===true){this.initialize()}};Sidebar.prototype.initialize=function(){this.conf.nodes=$("["+this.conf.indexAttribute+"]");this.load();this.updateDOM();this.bind();this.loadToggle()};Sidebar.prototype.loadToggle=function(){$("",{"class":"layout-toggle",html:"×","data-alt":"→"}).appendTo($(".header"));$(".layout-toggle").on("click",function(){var $this=$(this);var alt;$("body").toggleClass("sidebar-closed");alt=$this.html();$this.html($this.data("alt"));$this.data("alt",alt)})};Sidebar.prototype.load=function(){var index="localStorage"in global?global.localStorage.getItem(this.conf.storageKey):null;this.index=index?JSON.parse(index):this.buildIndex()};Sidebar.prototype.buildIndex=function(){var index={};var $item;this.conf.nodes.each($.proxy(function(index,item){$item=$(item);index[$item.attr(this.conf.indexAttribute)]=!$item.hasClass(this.conf.collapsedClass)},this));return index};Sidebar.prototype.updateDOM=function(){var item;for(item in this.index){if(this.index[item]===false){$("["+this.conf.indexAttribute+'="'+item+'"]').addClass(this.conf.collapsedClass)}}};Sidebar.prototype.save=function(){if(!("localStorage"in global)){return}global.localStorage.setItem(this.conf.storageKey,JSON.stringify(this.index))};Sidebar.prototype.bind=function(){var $item,slug,fn,text;var collapsed=false;global.onbeforeunload=$.proxy(function(){this.save()},this);$(this.conf.toggleBtn).on("click",$.proxy(function(event){$node=$(event.target);text=$node.attr("data-alt");$node.attr("data-alt",$node.text());$node.text(text);fn=collapsed===true?"removeClass":"addClass";this.conf.nodes.each($.proxy(function(index,item){$item=$(item);slug=$item.attr(this.conf.indexAttribute);this.index[slug]=collapsed;$("["+this.conf.indexAttribute+'="'+slug+'"]')[fn](this.conf.collapsedClass)},this));collapsed=!collapsed;this.save()},this));this.conf.nodes.on("click",$.proxy(function(event){$item=$(event.target);slug=$item.attr(this.conf.indexAttribute);this.index[slug]=!this.index[slug];$item.toggleClass(this.conf.collapsedClass)},this))};global.Sidebar=Sidebar})(window.jQuery,window);(function($,global){var Search=function(conf){this.conf=$.extend({search:{items:".sassdoc__item",input:"#js-search-input",form:"#js-search",suggestionsWrapper:"#js-search-suggestions"},fuse:{keys:["name"],threshold:.3},init:true},conf||{});if(this.conf.init===true){this.initialize()}};Search.prototype.initialize=function(){this.index=new Fuse($.map($(this.conf.search.items),function(item){var $item=$(item);return{group:$item.data("group"),name:$item.data("name"),type:$item.data("type"),node:$item}}),this.conf.fuse);this.initializeSearch()};Search.prototype.fillSuggestions=function(items){var searchSuggestions=$(this.conf.search.suggestionsWrapper);searchSuggestions.html("");var suggestions=$.map(items.slice(0,10),function(item){var $li=$("",{"data-group":item.group,"data-type":item.type,"data-name":item.name,html:''+item.type.slice(0,3)+"
"+item.name+""});searchSuggestions.append($li);return $li});return suggestions};Search.prototype.search=function(term){return this.fillSuggestions(this.index.search(term))};Search.prototype.initializeSearch=function(){var searchForm=$(this.conf.search.form);var searchInput=$(this.conf.search.input);var searchSuggestions=$(this.conf.search.suggestionsWrapper);var currentSelection=-1;var suggestions=[];var selected;var self=this;searchSuggestions.on("click",function(e){var target=$(event.target);if(target.nodeName==="A"){searchInput.val(target.parent().data("name"));suggestions=self.fillSuggestions([])}});searchForm.on("keyup",function(e){e.preventDefault();if(e.keyCode===13){if(selected){suggestions=self.fillSuggestions([]);searchInput.val(selected.data("name"));window.location=selected.children().first().attr("href")}e.stopPropagation()}if(e.keyCode===40){currentSelection=(currentSelection+1)%suggestions.length}if(e.keyCode===38){currentSelection=currentSelection-1;if(currentSelection<0){currentSelection=suggestions.length-1}}if(suggestions[currentSelection]){if(selected){selected.removeClass("selected")}selected=suggestions[currentSelection];selected.addClass("selected")}});searchInput.on("keyup",function(e){if(e.keyCode!==40&&e.keyCode!==38){currentSelection=-1;suggestions=self.search($(this).val())}else{e.preventDefault()}}).on("search",function(){suggestions=self.search($(this).val())})};global.Search=Search})(window.jQuery,window);(function($,global){"use strict";var App=function(conf){this.conf=$.extend({search:new global.Search,sidebar:new global.Sidebar,init:true},conf||{});if(this.conf.init!==false){this.initialize()}};App.prototype.initialize=function(){this.codePreview()};App.prototype.codePreview=function(){var $item;var $code;var switchTo;$(".item__code--togglable").on("click",function(){$item=$(this);$code=$item.find("code");switchTo=$item.attr("data-current-state")==="expanded"?"collapsed":"expanded";$item.attr("data-current-state",switchTo);$code.html($item.attr("data-"+switchTo));Prism.highlightElement($code[0])})};global.App=App})(window.jQuery,window);(function($,global){$(document).ready(function(){var app=new global.App})})(window.jQuery,window);var self=typeof window!="undefined"?window:{},Prism=function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{encode:function(e){return e instanceof n?new n(e.type,t.util.encode(e.content)):t.util.type(e)==="Array"?e.map(t.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(p instanceof i)continue;a.lastIndex=0;var d=a.exec(p);if(d){l&&(c=d[1].length);var v=d.index-1+c,d=d[0].slice(c),m=d.length,g=v+m,y=p.slice(0,v+1),b=p.slice(g+1),w=[h,1];y&&w.push(y);var E=new i(u,f?t.tokenize(d,f):d);w.push(E);b&&w.push(b);Array.prototype.splice.apply(s,w)}}}return s},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[];r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(!r||!r.length)return;for(var i=0,s;s=r[i++];)s(n)}}},n=t.Token=function(e,t){this.type=e;this.content=t};n.stringify=function(e,r,i){if(typeof e=="string")return e;if(Object.prototype.toString.call(e)=="[object Array]")return e.map(function(t){return n.stringify(t,r,e)}).join("");var s={type:e.type,content:n.stringify(e.content,r,i),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:i};s.type=="comment"&&(s.attributes.spellcheck="true");t.hooks.run("wrap",s);var o="";for(var u in s.attributes)o+=u+'="'+(s.attributes[u]||"")+'"';return"<"+s.tag+' class="'+s.classes.join(" ")+'" '+o+">"+s.content+""+s.tag+">"};if(!self.document){if(!self.addEventListener)return self.Prism;self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,i=n.code;self.postMessage(JSON.stringify(t.tokenize(i,t.languages[r])));self.close()},!1);return self.Prism}var r=document.getElementsByTagName("script");r=r[r.length-1];if(r){t.filename=r.src;document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)}return self.Prism}();typeof module!="undefined"&&module.exports&&(module.exports=Prism);Prism.languages.markup={comment://g,prolog:/<\?.+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|[^\s'">=]+))?\s*)*\/?>/gi,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi,inside:{punctuation:/=|>|"/g}},punctuation:/\/?>/g,"attr-name":{pattern:/[\w:-]+/g,inside:{namespace:/^[\w-]+?:/}}}},entity:/\?[\da-z]{1,8};/gi};Prism.hooks.add("wrap",function(e){e.type==="entity"&&(e.attributes.title=e.content.replace(/&/,"&"))});Prism.languages.css={comment:/\/\*[\w\W]*?\*\//g,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*{))/gi,inside:{punctuation:/[;:]/g}},url:/url\((["']?).*?\1\)/gi,selector:/[^\{\}\s][^\{\};]*(?=\s*\{)/g,property:/(\b|\B)[\w-]+(?=\s*:)/gi,string:/("|')(\\?.)*?\1/g,important:/\B!important\b/gi,punctuation:/[\{\};:]/g,"function":/[-a-z0-9]+(?=\()/gi};Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{style:{pattern:/