diff --git a/_includes/demo-list.html b/docs/_includes/demo-list.html
similarity index 100%
rename from _includes/demo-list.html
rename to docs/_includes/demo-list.html
diff --git a/docs/_includes/events.html b/docs/_includes/events.html
new file mode 100644
index 0000000..94c09e5
--- /dev/null
+++ b/docs/_includes/events.html
@@ -0,0 +1,19 @@
+
diff --git a/_includes/features.html b/docs/_includes/features.html
similarity index 100%
rename from _includes/features.html
rename to docs/_includes/features.html
diff --git a/docs/_includes/filters.html b/docs/_includes/filters.html
new file mode 100644
index 0000000..b7be2bf
--- /dev/null
+++ b/docs/_includes/filters.html
@@ -0,0 +1,45 @@
+
Show multiple groups at once by using an array.
diff --git a/_includes/foot.html b/docs/_includes/foot.html
similarity index 100%
rename from _includes/foot.html
rename to docs/_includes/foot.html
diff --git a/docs/_includes/footer.html b/docs/_includes/footer.html
new file mode 100644
index 0000000..5717b33
--- /dev/null
+++ b/docs/_includes/footer.html
@@ -0,0 +1,17 @@
+
diff --git a/_includes/head.html b/docs/_includes/head.html
similarity index 85%
rename from _includes/head.html
rename to docs/_includes/head.html
index 4452121..7cbdcd4 100644
--- a/_includes/head.html
+++ b/docs/_includes/head.html
@@ -13,7 +13,8 @@
{% endfor %}
{% endif %}
+
diff --git a/docs/_includes/install.html b/docs/_includes/install.html
new file mode 100644
index 0000000..cf7a136
--- /dev/null
+++ b/docs/_includes/install.html
@@ -0,0 +1,14 @@
+
diff --git a/docs/_includes/nav.html b/docs/_includes/nav.html
new file mode 100644
index 0000000..41397c1
--- /dev/null
+++ b/docs/_includes/nav.html
@@ -0,0 +1,72 @@
+
diff --git a/_includes/options.html b/docs/_includes/options.html
similarity index 90%
rename from _includes/options.html
rename to docs/_includes/options.html
index 82e1e09..cc77eb0 100644
--- a/_includes/options.html
+++ b/docs/_includes/options.html
@@ -4,23 +4,24 @@
diff --git a/docs/_includes/picture-item.html b/docs/_includes/picture-item.html
new file mode 100644
index 0000000..a5950cf
--- /dev/null
+++ b/docs/_includes/picture-item.html
@@ -0,0 +1,34 @@
+{%- if item.extras | size: > 0 -%}
+ {%- capture extras %} picture-item--{{ item.extras | join: " picture-item--" }}{%- endcapture -%}
+{%- else -%}
+ {%- assign extras = "" -%}
+{%- endif -%}
+{%- assign description = item.description -%}
+
diff --git a/_includes/public-methods.html b/docs/_includes/public-methods.html
similarity index 100%
rename from _includes/public-methods.html
rename to docs/_includes/public-methods.html
diff --git a/_includes/scripts.html b/docs/_includes/scripts.html
similarity index 57%
rename from _includes/scripts.html
rename to docs/_includes/scripts.html
index 277e6a1..f8c0ec0 100644
--- a/_includes/scripts.html
+++ b/docs/_includes/scripts.html
@@ -1,26 +1,23 @@
-{% if page.jquery %}
-
-{% endif %}
-
-{% if page.shuffle != false %}
-
-
-{% endif %}
-
-{% if page.prism %}
+{% if page.requirejs %}
+
+{% else %}
+
+
+
{% endif %}
+
-
-{% if page.pagejs != false %}
-
-
+{% if page.externalJS %}
+{% for src in page.externalJS %}
+
+{% endfor %}
{% endif %}
{% if page.extraJS && page.extraJS.length %}
{% for src in page.extraJS %}
-
+
{% endfor %}
{% endif %}
diff --git a/_includes/sorting.html b/docs/_includes/sorting.html
similarity index 59%
rename from _includes/sorting.html
rename to docs/_includes/sorting.html
index 6de94ee..c20bb54 100644
--- a/_includes/sorting.html
+++ b/docs/_includes/sorting.html
@@ -1,9 +1,9 @@
You can order the elements with a function you supply. In the demo above, each item has a data-date-created
and data-title
attribute. When the select option menu changes, a sort object is passed to shuffle.
You can order the elements with a function you supply. In the demo above, each item has a data-date-created
and data-title
attribute which are used for sorting.
@@ -21,7 +21,6 @@
Demo.prototype._handleSortChange = function (evt) {
var value = evt.target.value;
- var options = {};
function sortByDate(element) {
return element.getAttribute('data-created');
@@ -31,6 +30,7 @@ Demo.prototype._handleSortChange = function (evt) {
return element.getAttribute('data-title').toLowerCase();
}
+ var options;
if (value === 'date-created') {
options = {
reverse: true,
@@ -40,18 +40,20 @@ Demo.prototype._handleSortChange = function (evt) {
options = {
by: sortByTitle,
};
+ } else {
+ options = {};
}
this.shuffle.sort(options);
};
Calling sort with an empty object will reset the elements to DOM order.
diff --git a/_includes/usage.html b/docs/_includes/usage.html
similarity index 61%
rename from _includes/usage.html
rename to docs/_includes/usage.html
index 416723c..c609d79 100644
--- a/_includes/usage.html
+++ b/docs/_includes/usage.html
@@ -1,38 +1,38 @@
This example is using this site's grid. Each item would be 4 columns at the "sm" breakpoint (768px).
-
<div id="grid" class="row my-shuffle-container">
- <figure class="col-4@sm picture-item" data-groups='["photography"]' data-date-created="2010-09-14" data-title="Baseball">
+ <div class="row my-shuffle-container">
+ <figure class="col-4@sm picture-item" data-groups='["animal"]' data-date-created="2016-08-12" data-title="Crocodile">
<div class="aspect aspect--16x9">
<div class="aspect__inner">
- <img src="/img/baseball.png" alt="" height="145" width="230">
+ <img src="crocodile.jpg" alt="A close, profile view of a crocodile looking directly into the camera" />
</div>
</div>
- <figcaption>Baseball</figcaption>
+ <figcaption>Crocodile</figcaption>
</figure>
- <figure class="col-4@sm picture-item" data-groups='["wallpaper","3d"]' data-date-created="2011-08-14" data-title="Tennis">
+ <figure class="col-4@sm picture-item" data-groups='["city"]' data-date-created="2016-06-09" data-title="Crossroads">
<div class="aspect aspect--16x9">
<div class="aspect__inner">
- <img src="/img/tennis-ball.png" alt="" height="145" width="230">
+ <img src="crossroads.jpg" alt="A multi-level highway stack interchange in Puxi, Shanghai" />
</div>
</div>
- <figcaption>Tennis</figcaption>
+ <figcaption>Crossroads</figcaption>
</figure>
- <figure class="col-4@sm picture-item" data-groups='["wallpaper","3d"]' data-date-created="2009-05-27" data-title="iMac">
+ <figure class="col-4@sm picture-item" data-groups='["nature","city"]' data-date-created="2015-10-20" data-title="Central Park">
<div class="aspect aspect--16x9">
<div class="aspect__inner">
- <img src="/img/imac.png" alt="" height="145" width="230">
+ <img src="central-park.jpg" alt="Looking down on central park and the surrounding builds from the Rockefellar Center" />
</div>
</div>
- <figcaption>iMac</figcaption>
+ <figcaption>Central Park</figcaption>
</figure>
<div class="col-1@sm my-sizer-element"></div>
</div>
@@ -51,11 +51,11 @@
If you want functional buttons, check out the js file .
Shuffle uses a UMD definition so that you can use it with globals, AMD, or CommonJS.
-
var Shuffle = window.shuffle;
-var element = document.getElementById('grid');
+ var Shuffle = window.Shuffle;
+var element = document.querySelector('.my-shuffle-container');
var sizer = element.querySelector('.my-sizer-element');
-var shuffle = new Shuffle(element, {
+var shuffleInstance = new Shuffle(element, {
itemSelector: '.picture-item',
sizer: sizer // could also be a selector: '.my-sizer-element'
});
diff --git a/_layouts/default.html b/docs/_layouts/default.html
similarity index 55%
rename from _layouts/default.html
rename to docs/_layouts/default.html
index 856f4f7..99dce2a 100644
--- a/_layouts/default.html
+++ b/docs/_layouts/default.html
@@ -3,16 +3,16 @@
{% if page.includeHeader %}
-
+
Shuffle
-
{{ site.defaultDescription }}
-
By @Vestride
+
{{ site.defaultDescription }}
{% endif %}
-
+
{{ content }}
+{% include footer.html %}
{% include scripts.html %}
{% include foot.html %}
diff --git a/_posts/2013-05-01-basic.html b/docs/_posts/2013-05-01-basic.html
similarity index 61%
rename from _posts/2013-05-01-basic.html
rename to docs/_posts/2013-05-01-basic.html
index 170c707..e435e57 100644
--- a/_posts/2013-05-01-basic.html
+++ b/docs/_posts/2013-05-01-basic.html
@@ -26,9 +26,19 @@ extraJS: [ "demos/homepage.js" ]
-
Shuffle.js
-
{{ site.longDescription }}
+
+
Source code for this demo
+
This demo uses the same code as the home page (with the filters).
+
Link to demo source
+
-{% include credit-jake.html %}
+
+
+
+
Shuffle.js
+
{{ site.longDescription }}
+
+
+
diff --git a/_posts/2013-05-02-compound-filters.html b/docs/_posts/2013-05-02-compound-filters.html
similarity index 94%
rename from _posts/2013-05-02-compound-filters.html
rename to docs/_posts/2013-05-02-compound-filters.html
index 32c5243..93af3bc 100644
--- a/_posts/2013-05-02-compound-filters.html
+++ b/docs/_posts/2013-05-02-compound-filters.html
@@ -5,6 +5,7 @@ description: A demo with compound filtering
image: /demos/adaptive.jpg
extraJS: [ "demos/compound-filters.js" ]
prism: true
+photoCredit: false
---
@@ -19,7 +20,7 @@ prism: true
-
Colors
+
Colors
Green
Blue
Red
@@ -29,7 +30,7 @@ prism: true
-
Shapes
+
Shapes
Circle
diff --git a/_posts/2013-05-03-images.html b/docs/_posts/2013-05-03-images.html
similarity index 85%
rename from _posts/2013-05-03-images.html
rename to docs/_posts/2013-05-03-images.html
index aec0802..0e6fb3e 100644
--- a/_posts/2013-05-03-images.html
+++ b/docs/_posts/2013-05-03-images.html
@@ -14,8 +14,9 @@ prism: true
You can encounter problems when shuffle item dimensions depend on images. Like this demo . There are three good solutions to this.
Set an explicit height on .shuffle-item
s like the basic demo .
- Similar to number 1, make the height of the image container a percentage of the width. If you know the aspect ratio of the images you're using, this is the technique you should use. This demo uses this technique.
- Get notified when images load and call myShuffleInstance.layout()
. I recommend using Desandro's images loaded plugin to know when your images have finished loading.
+ Similar to number 1, make the height of the image container a percentage of the width. If you know the aspect ratio of the images you're using, this is the technique you should use. This demo uses that technique.
+ Get notified when images load and call shuffleInstance.layout()
. I recommend using Desandro's images loaded plugin to know when your images have finished loading.
+ Do nothing and let your shuffle instance call layout()
on the window
's load
event. This will the item layout to change on page load.
@@ -46,10 +47,10 @@ prism: true
-
+
- {{ item.groups | join: ', ' }}
+ {{ item.title }}
{% endfor %}
@@ -121,6 +122,3 @@ prism: true
-
-
-{% include credit-jake.html %}
diff --git a/_posts/2013-06-19-adding-removing.html b/docs/_posts/2013-06-19-adding-removing.html
similarity index 66%
rename from _posts/2013-06-19-adding-removing.html
rename to docs/_posts/2013-06-19-adding-removing.html
index eb79dfb..be2e79a 100644
--- a/_posts/2013-06-19-adding-removing.html
+++ b/docs/_posts/2013-06-19-adding-removing.html
@@ -5,6 +5,7 @@ description: This demo of shuffle shows how to add and removing items.
image: /demos/adding-removing.jpg
extraJS: [ "demos/adding-removing.js" ]
prism: true
+photoCredit: false
---
+
+
+
+
+
Shuffle with Flexbox (Bootstrap 4)
+
On this page, I have added the minified bootstrap css file from the Bootstrap CDN (which is also why some of the site-styles are being overriden).
+
The Bootstrap 4 grid system uses flexbox with padding for gutters.
+
The best way to handle this is to have the shuffle container element (#grid
in this case), to be a .row
so that all the shuffle items remain flex-items.
+
If you cannot make the shuffle container element a .row
, you will need to set a width
for each column (like width: 25%;
).
+
+
+
+
+
+
+
+ {% for i in (1..20) %}
+
+
+
+ {% cycle
+ 'Return on investment product management equity crowdfunding stock pivot innovator sales ownership.',
+ 'Founders ecosystem hackathon product management lean startup MVP.',
+ 'Traction bandwidth MVP direct mailing partner network gen-z growth hacking crowdsource channels responsive web design pivot.',
+ 'Conversion technology long tail influencer analytics rockstar market seed money.',
+ 'Investor bandwidth equity ecosystem vesting period client social media.',
+ 'Angel investor niche market client churn rate crowdsource infrastructure paradigm shift marketing prototype.'
+ %}
+
+
+
+ {% endfor %}
+
+
+
+
+
+
+
+
The one change I've made to the grid is to allow grid columns to fit on mobile.
+
By default, bootstrap 4 grid gutters are 30px, even on mobile, and they use as 12 column grid. At 320px, each column would need to be 26.667px for 12 columsn to fit, but since there is 30px of inner gutter, the columns are always >= 30px, so they don't fit for us.
+
If you're using Bootstrap's sass files, you can customize the gutter width via the $grid-gutter-widths
map. In this example, I'm overriding it instead.
+
+
@media (max-width: 575px) {
+ .row > [class*="col-"] {
+ padding-left: 8px;
+ padding-right: 8px;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
Shuffle.js
+
{{ site.longDescription }}
+
+
+
diff --git a/docs/_posts/2017-06-29-shuffle-with-react.html b/docs/_posts/2017-06-29-shuffle-with-react.html
new file mode 100644
index 0000000..05f2a2c
--- /dev/null
+++ b/docs/_posts/2017-06-29-shuffle-with-react.html
@@ -0,0 +1,82 @@
+---
+layout: default
+title: Shuffle with React
+description: TODO
+image: /demos/flexbox-grid.jpg
+extraJS: [ "demos/react.js" ]
+externalJS: ["https://unpkg.com/react@latest/dist/react.js", "https://unpkg.com/react-dom@latest/dist/react-dom.js", "https://unpkg.com/babel-standalone@6.15.0/babel.min.js"]
+jsType: "text/babel"
+prism: true
+---
+
+
+
+
+
+
+
Shuffle with React
+
And other view-based libraries like Vue and Preact.
+
The simplest way is to use shuffleInstance.resetItems();
inside the componentDidUpdate()
lifecycle method.
+
+
+
+
+
+
+
diff --git a/docs/_scss/components/_buttons.scss b/docs/_scss/components/_buttons.scss
new file mode 100644
index 0000000..bfc397d
--- /dev/null
+++ b/docs/_scss/components/_buttons.scss
@@ -0,0 +1,143 @@
+.btn-group {
+ @include clearfix();
+
+ .btn {
+ float: left;
+ border-radius: 0;
+ }
+
+ .btn:first-child {
+ border-radius: 3px 0 0 3px;
+ }
+
+ .btn:not(:first-child) {
+ margin-left: -1px;
+ }
+
+ .btn:last-child {
+ border-radius: 0 3px 3px 0;
+ }
+
+ label.btn input[type=radio] {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none;
+ }
+}
+
+.btn {
+ display: inline-block;
+ padding: .75em .8em;
+ text-align: center;
+ border-radius: 3px;
+ border: 1px solid $gray20;
+ color: $gray20;
+ font-size: 1rem;
+ background-color: rgba($gray20, 0);
+ transition: .2s ease-out;
+ cursor: pointer;
+ -webkit-appearance: none;
+
+ @include with-fine-pointer() {
+ &:hover {
+ color: white;
+ text-decoration: none;
+ background-color: $gray20;
+ }
+ }
+
+ &:focus {
+ outline-width: 0;
+ box-shadow: 0 0 0 2px rgba($gray20, 0.4);
+ }
+
+ &.active,
+ &:active {
+ box-shadow: inset 0 1px 2px rgba(0,0,0,.3);
+ color: white;
+ background-color: $gray20;
+ }
+
+ &:focus.active {
+ box-shadow: inset 0 1px 2px rgba(0,0,0,.3), 0 0 0 2px rgba($gray20, 0.4);
+ }
+}
+
+$btn-variants: (
+ 'warning': $carrot,
+ 'primary': $river,
+ 'danger': $alizarin,
+ 'go': $emerald,
+);
+
+@each $name, $color in $btn-variants {
+ .btn--#{$name} {
+ color: $color;
+ border-color: $color;
+ background-color: rgba($color, 0);
+
+ @include with-fine-pointer() {
+ &:hover {
+ background-color: $color;
+ }
+ }
+
+ &:focus {
+ box-shadow: 0 0 0 2px rgba($color, 0.4);
+ }
+
+ &.active,
+ &:active {
+ background-color: $color;
+ }
+
+ &:focus.active {
+ box-shadow: inset 0 1px 2px rgba(0,0,0,.3), 0 0 0 2px rgba($color, 0.4);
+ }
+ }
+}
+
+@include breakpoint(sm, true) {
+ .btn {
+ font-size: 0.875rem;
+ }
+}
+
+.filter-group .btn {
+ position: relative;
+
+ $size: 20px;
+ // Circle and check
+ &.active:before,
+ &.active:after {
+ content: '';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: $size;
+ height: $size;
+ margin-left: -$size / 2;
+ margin-top: -$size / 2;
+ opacity: 0;
+ transition: .2s;
+ }
+
+ // Circle
+ &:before {
+ background-color: $gray10;
+ border-radius: 50%;
+ }
+
+ // Check
+ &:after {
+ background-size: 60%;
+ background-position: center center;
+ background-repeat: no-repeat;
+ background-image: url(../img/check.svg);
+ }
+
+ &.active:before,
+ &.active:after {
+ opacity: 1;
+ }
+}
diff --git a/_scss/_demo-list.scss b/docs/_scss/components/_demo-list.scss
similarity index 98%
rename from _scss/_demo-list.scss
rename to docs/_scss/components/_demo-list.scss
index 71ad4ff..e5d1ea8 100644
--- a/_scss/_demo-list.scss
+++ b/docs/_scss/components/_demo-list.scss
@@ -37,6 +37,7 @@
}
.demo-list .figure-wrap figcaption {
+ height: 2em;
margin-top: .5em;
margin-bottom: 1em;
}
diff --git a/docs/_scss/components/_site-nav.scss b/docs/_scss/components/_site-nav.scss
new file mode 100644
index 0000000..5c65ec8
--- /dev/null
+++ b/docs/_scss/components/_site-nav.scss
@@ -0,0 +1,349 @@
+.site-nav {
+ padding: 10px 0;
+ border-bottom: 1px solid $gray90;
+ margin-bottom: 28px;
+ background: $gray95;
+}
+
+.site-nav__content {
+ display: flex;
+ justify-content: space-between;
+}
+
+.site-nav__logo {
+ font-size: 20px;
+}
+
+.site-nav__logo,
+.site-nav__logo:visited {
+ color: $gray20;
+
+ &:hover {
+ text-decoration: none;
+ }
+}
+
+.site-nav__logo,
+.site-nav__links {
+ display: flex;
+ align-items: center;
+}
+
+.site-nav__logo svg {
+ display: block;
+ width: 24px;
+ height: 24px;
+ margin-right: 4px;
+}
+
+.site-nav__logo rect {
+ transition: 180ms cubic-bezier(0.4, 0.0, 0.2, 1);
+}
+
+.site-nav__link {
+ position: relative;
+ z-index: 3;
+}
+
+.site-nav__link:not(:last-of-type) {
+ margin-right: 8px;
+}
+
+.site-nav__dropdown {
+ position: absolute;
+ z-index: 2;
+ top: 40px;
+ right: 0;
+ opacity: 0;
+ visibility: hidden;
+ max-height: 100vh;
+ transition: 300ms cubic-bezier(0.165, 0.84, 0.44, 1);
+ background-color: white;
+ transform: translateY(10px);
+ box-shadow: 0 7px 10px -1px rgba(0, 0, 0, 0.12);
+
+ // Triangle.
+ &::before {
+ content: '';
+ position: absolute;
+ top: -8px;
+ right: 32px;
+ display: block;
+ border-bottom: 8px solid white;
+ border-left: 9px solid transparent;
+ border-right: 9px solid transparent;
+ }
+
+ li + li {
+ margin-top: 8px;
+ }
+
+ a {
+ display: block;
+ color: $gray30;
+ }
+
+ a:hover {
+ background-color: $gray95;
+ text-decoration: none;
+ color: $gray30;
+ }
+
+ figure {
+ display: flex;
+ align-items: center;
+ }
+
+ picture {
+ flex-shrink: 0;
+ width: 100px;
+ height: 100px * 0.75;
+ }
+
+ figcaption {
+ padding-left: 8px;
+ padding-right: 8px;
+ }
+}
+
+.site-nav__dropdown--simple-links {
+ a {
+ padding: 8px 16px;
+ }
+
+ li + li {
+ margin-top: 0;
+ }
+}
+
+.site-nav__link-toggle {
+ padding: 6px 8px;
+}
+
+// Dropdown link triangle.
+.site-nav__link-toggle::after {
+ content: '';
+ display: inline-block;
+ vertical-align: middle;
+ margin-top: -1px;
+ margin-left: 4px;
+ border-top: 6px solid currentColor;
+ border-left: 5px solid transparent;
+ border-right: 5px solid transparent;
+ transition: transform 180ms cubic-bezier(0.4, 0.0, 0.2, 1);
+}
+
+.site-nav__link--dropdown-active {
+ // Dropdown link triangle.
+ .site-nav__link-toggle::after {
+ transform: rotate(-180deg);
+ }
+
+ .site-nav__dropdown {
+ visibility: visible;
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+// Rules for non-touch screens
+@include with-fine-pointer() {
+ $interval: 10ms;
+ .site-nav__logo:hover {
+ rect:nth-of-type(1) {
+ transform: translate(20px, 10px);
+ transition-delay: (1 - 1) * $interval;
+ }
+
+ rect:nth-of-type(2) {
+ transform: translate(0px, 20px);
+ transition-delay: (2 - 1) * $interval;
+ }
+
+ rect:nth-of-type(3) {
+ transform: translate(-20px, 6px);
+ transition-delay: (3 - 1) * $interval;
+ }
+
+ rect:nth-of-type(4) {
+ transform: translate(10px, -10px);
+ transition-delay: (4 - 1) * $interval;
+ }
+
+ rect:nth-of-type(5) {
+ transform: translate(-10px, 10px);
+ transition-delay: (5 - 1) * $interval;
+ }
+
+ rect:nth-of-type(6) {
+ transform: translate(-20px, -14px);
+ transition-delay: (6 - 1) * $interval;
+ }
+
+ rect:nth-of-type(7) {
+ transform: translate(0px, -20px);
+ transition-delay: (7 - 1) * $interval;
+ }
+ }
+
+ .site-nav__link-toggle:hover {
+ border-color: $gray20;
+ }
+}
+
+@include breakpoint(sm, true) {
+ // Affix the nav when a dropdown is open so that scrolling the page
+ // behind the dropdown doesn't scroll away the nav.
+ body.site-nav--open {
+ padding-top: 51px;
+ }
+
+ body.site-nav--open .site-nav {
+ position: fixed;
+ z-index: 4;
+ top: 0;
+ left: 0;
+ width: 100%;
+ }
+
+ .site-nav__dropdown {
+ position: fixed;
+ left: 0;
+ right: 0;
+ top: 51px;
+ width: 100vw;
+ padding: 8px calc(3.5vw + 8px);
+ overflow: auto;
+ -webkit-overflow-scrolling: touch;
+ }
+}
+
+@include breakpoint(sm) {
+ .site-nav {
+ padding: 16px 0;
+ }
+
+ .site-nav__logo {
+ font-size: 24px;
+ }
+
+ .site-nav__logo svg {
+ width: 32px;
+ height: 32px;
+ }
+
+ .site-nav__link:not(:last-child) {
+ margin-right: 16px;
+ }
+
+ .site-nav__link--dropdown:not(:last-child) {
+ margin-right: 12px;
+ }
+
+ .site-nav__dropdown {
+ max-height: none !important; // override inline style.
+ right: -100px;
+ padding: 16px;
+ box-shadow: 0 0 10px rgba(0, 0, 0, 0.12);
+
+ &::before {
+ right: 132px;
+ }
+
+ ul {
+ column-count: 2;
+ column-gap: 16px;
+ }
+
+ li {
+ -webkit-column-break-inside: avoid;
+ page-break-inside: avoid;
+ break-inside: avoid;
+ }
+
+ figcaption {
+ white-space: nowrap;
+ }
+ }
+
+ @supports (filter: drop-shadow(0 0 5px rgba(0, 0, 0, 0.12))) {
+ .site-nav__dropdown {
+ box-shadow: none;
+ filter: drop-shadow(0 0 5px rgba(0, 0, 0, 0.12));
+ }
+ }
+
+ .site-nav__link-img {
+ width: 24px;
+ height: 24px;
+ }
+
+ .site-nav__dropdown--simple-links {
+ right: 0;
+ padding: 0;
+
+ &::before {
+ right: 24px;
+ }
+
+ a {
+ width: 200px;
+ }
+ }
+}
+
+@include breakpoint(md) {
+ .site-nav__dropdown {
+ right: 0;
+
+ &::before {
+ right: 32px;
+ }
+ }
+
+ .site-nav__dropdown--simple-links {
+
+ &::before {
+ right: 24px;
+ }
+ }
+}
+
+// Footer
+// -------------
+.site-footer {
+ margin-top: 2em;
+ padding: 1em 0;
+ background-color: $gray20;
+
+ p {
+ color: $gray95;
+ }
+
+ a {
+ color: white;
+ text-decoration: underline;
+
+ &:hover {
+ color: $river;
+ }
+ }
+}
+
+.has-code-block .code-block pre {
+ margin-bottom: 0;
+}
+
+.has-code-block + .site-footer {
+ margin-top: 0;
+}
+
+.site-footer__credit {
+ // margin: 0;
+}
+
+@include breakpoint(sm) {
+ .site-footer__credit {
+ text-align: right;
+ }
+}
diff --git a/_scss/_grid-framework.scss b/docs/_scss/extensions/_grid-framework.scss
similarity index 100%
rename from _scss/_grid-framework.scss
rename to docs/_scss/extensions/_grid-framework.scss
diff --git a/_scss/_mixins.scss b/docs/_scss/extensions/_mixins.scss
similarity index 88%
rename from _scss/_mixins.scss
rename to docs/_scss/extensions/_mixins.scss
index af00815..1bd62ce 100644
--- a/_scss/_mixins.scss
+++ b/docs/_scss/extensions/_mixins.scss
@@ -18,6 +18,14 @@
}
}
+// https://caniuse.com/#feat=css-media-interaction
+// https://bugzilla.mozilla.org/show_bug.cgi?id=1035774#c9
+@mixin with-fine-pointer() {
+ @media (-moz-touch-enabled: 0), (pointer: fine) {
+ @content;
+ }
+}
+
@mixin clearfix() {
&::before,
&::after {
diff --git a/_scss/_variables.scss b/docs/_scss/extensions/_variables.scss
similarity index 82%
rename from _scss/_variables.scss
rename to docs/_scss/extensions/_variables.scss
index 6968d06..5f3c173 100644
--- a/_scss/_variables.scss
+++ b/docs/_scss/extensions/_variables.scss
@@ -7,44 +7,34 @@ $breakpoints: (
);
// Colors from Flat UI
-
$turqoise: #1ABC9C;
$greenSea: #16A085;
-
$emerald: #2ECC71;
$nephritis: #27AE60;
-
$river: #3498DB;
$belizeHole: #2980B9;
-
$amethyst: #9B59B6;
$wisteria: #8E44AD;
-
-$wetAsphalt: #34495E;
+$wet-asphalt: #34495E;
$midnightBlue: #2C3E50;
-
$sunflower: #F1C40F;
$orange: #F39C12;
-
$carrot: #E67E22;
$pumpkin: #D35400;
-
$alizarin: #E74C3C;
$pomegranate: #C0392B;
-
$clouds: #ECF0F1;
$silver: #BDC3C7;
-
$concrete: #95A5A6;
$asbestos: #7F8C8D;
-
-//
-
$black: #000;
$gray10: $midnightBlue;
-$gray20: $wetAsphalt;
+$gray20: $wet-asphalt;
$gray30: #5D6D77;
-$gray40: $concrete;
$gray50: $asbestos;
+$gray60: $concrete;
+$gray80: $silver;
+$gray90: #E1E5E6;
+$gray95: $clouds;
$white: #FFF;
diff --git a/docs/_scss/global-rules/_forms.scss b/docs/_scss/global-rules/_forms.scss
new file mode 100644
index 0000000..d400cfc
--- /dev/null
+++ b/docs/_scss/global-rules/_forms.scss
@@ -0,0 +1,40 @@
+.textfield {
+ -webkit-appearance: none;
+ box-sizing: border-box;
+ width: 100%;
+ border: 2px solid $gray60;
+ border-radius: 4px;
+ padding: 0.5em;
+ font-size: 1rem;
+ color: $gray20;
+ transition: .15s;
+
+ &::placeholder {
+ color: $gray60;
+ transition: .15s;
+ }
+
+ &:hover {
+ outline-width: 0;
+ color: $gray30;
+ border-color: $gray30;
+
+ &::placeholder {
+ color: $gray30;
+ }
+ }
+
+ &:focus {
+ outline-width: 0;
+ // color: $gray20;
+ border-color: $gray20;
+
+ &::placeholder {
+ color: $gray20;
+ }
+ }
+}
+
+.textfield--large {
+ font-size: 1.125em;
+}
diff --git a/_scss/_global.scss b/docs/_scss/global-rules/_global.scss
similarity index 64%
rename from _scss/_global.scss
rename to docs/_scss/global-rules/_global.scss
index e1ba129..a37e9dd 100644
--- a/_scss/_global.scss
+++ b/docs/_scss/global-rules/_global.scss
@@ -36,31 +36,15 @@ li {
line-height: 1.4;
}
-nav > a {
- display: block;
- margin: 5px 0;
-}
-
-.breathable-list li {
- line-height: 1.7;
-}
-
-// Filters
-.filter__label {
- margin: 0 0 3px;
+li + li {
+ margin-top: 4px;
}
-.filter__search {
+nav > a {
+ display: block;
margin: 5px 0;
}
-
-.sort-options {
- margin-top: 10px;
-}
-
-#be-social {
- h2 {
- margin-bottom: 32px;
- }
+#demos {
+ margin-top: 1em;
}
diff --git a/_scss/_grid.scss b/docs/_scss/global-rules/_grid.scss
similarity index 96%
rename from _scss/_grid.scss
rename to docs/_scss/global-rules/_grid.scss
index 29df1e9..00dc7c7 100644
--- a/_scss/_grid.scss
+++ b/docs/_scss/global-rules/_grid.scss
@@ -1,4 +1,4 @@
-@import "grid-framework";
+@import "../extensions/grid-framework";
// .container
.#{$grid-container} {
@@ -81,8 +81,10 @@
.code-block {
position: relative;
overflow: visible;
- margin-left: calc(-3.5vw - #{($grid-gutter-width / 2)});
+ margin-top: 0.5em;
margin-right: calc(-3.5vw - #{($grid-gutter-width / 2)});
+ margin-bottom: 0.5em;
+ margin-left: calc(-3.5vw - #{($grid-gutter-width / 2)});
pre {
position: relative;
@@ -92,7 +94,7 @@
padding-bottom: 1em;
padding-left: calc(3.5vw + #{($grid-gutter-width / 2)});
padding-right: calc(3.5vw + #{($grid-gutter-width / 2)});
- margin: .5em 0;
+ margin: 0;
}
}
diff --git a/_scss/_helpers.scss b/docs/_scss/global-rules/_helpers.scss
similarity index 93%
rename from _scss/_helpers.scss
rename to docs/_scss/global-rules/_helpers.scss
index 1eb7ef1..5120cf0 100644
--- a/_scss/_helpers.scss
+++ b/docs/_scss/global-rules/_helpers.scss
@@ -8,6 +8,10 @@
.hidden\@xs { display: none; }
}
+@include breakpoint(sm) {
+ .visible\@xs { display: none; }
+}
+
// Hide from both screenreaders and browsers.
.hidden {
display: none !important;
diff --git a/docs/_scss/global-rules/_type.scss b/docs/_scss/global-rules/_type.scss
new file mode 100644
index 0000000..54eb782
--- /dev/null
+++ b/docs/_scss/global-rules/_type.scss
@@ -0,0 +1,132 @@
+body {
+ font-family: 'Open Sans', 'Helvetica Neue', Helvetica, sans-serif;
+ color: $gray30;
+}
+
+// Links
+a {
+ text-decoration: none;
+
+ &,
+ &:visited {
+ color: $river;
+ }
+
+ &:hover {
+ text-decoration: underline;
+ }
+
+ &:active {
+ color: $emerald;
+ }
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ color: $gray20;
+ font-weight: 700;
+}
+
+h1 {
+ margin: 3vw 0;
+ font-size: 10vw;
+ font-weight: 400;
+ line-height: 1;
+}
+
+h2 {
+ position: relative;
+ font-size: 7vw;
+ margin: 3vw 0;
+}
+
+h3 {
+ font-size: 6vw;
+ margin: 2vw 0;
+}
+
+h4 {
+ font-size: 1.25em;
+}
+
+p {
+ margin: 1em 0;
+ line-height: 1.4;
+}
+
+.intro-text {
+ margin: 0.7em 0;
+ font-size: 1.125em;
+}
+
+@include breakpoint(sm) {
+ h1 {
+ margin: 0.5em 0 0.25em;
+ font-size: 3.5em;
+ }
+
+ h2 {
+ margin: 0.45em 0;
+ font-size: 2.5em;
+ }
+
+ h3 {
+ margin: 0.8em 0 0.5em;
+ font-size: 1.5em;
+ }
+
+ h1 > a,
+ h2 > a,
+ h3 > a {
+ display: none;
+ }
+
+ h1:hover > a,
+ h2:hover > a,
+ h3:hover > a {
+ position: absolute;
+ display: inline-block;
+ top: 0;
+ height: 50px;
+ width: 50px;
+ background: url('../img/link.svg') no-repeat;
+ overflow: hidden;
+ text-indent: -999em;
+ }
+
+ .intro-text {
+ font-size: 1.25em;
+ }
+}
+
+.unstyled {
+ list-style-type: none;
+ padding: 0;
+ margin: 0;
+}
+
+.type--underline {
+ text-decoration: underline;
+}
+
+code:not([class*="language"]) {
+ padding: 0;
+ padding-top: 0.2em;
+ padding-bottom: 0.2em;
+ margin: 0;
+ font-size: 85%;
+ color: $gray10;
+ background-color: rgba(27,31,35,0.05);
+ border-radius: 3px;
+ font-family: Menlo, Consolas, "Liberation Mono", Courier, monospace;
+}
+
+code:not([class*="language"])::before,
+code:not([class*="language"])::after {
+ content: "\00a0";
+ letter-spacing: -.2em;
+}
diff --git a/_scss/_compound-filters.scss b/docs/_scss/pages/_compound-filters.scss
similarity index 96%
rename from _scss/_compound-filters.scss
rename to docs/_scss/pages/_compound-filters.scss
index f9ffa04..adf03e3 100644
--- a/_scss/_compound-filters.scss
+++ b/docs/_scss/pages/_compound-filters.scss
@@ -1,4 +1,4 @@
-@import "variables";
+@import "../extensions/variables";
.compound-filter-options {
@@ -12,6 +12,7 @@
width: 40px;
height: 40px;
padding: 0;
+ background-color: currentColor;
}
label {
@@ -23,10 +24,6 @@
}
}
-.filter-group__label--compound {
- margin: 0 0 5px;
-}
-
.shape-shuffle-container {
position: relative;
overflow: hidden;
diff --git a/docs/_scss/pages/_faq.scss b/docs/_scss/pages/_faq.scss
new file mode 100644
index 0000000..9947d4d
--- /dev/null
+++ b/docs/_scss/pages/_faq.scss
@@ -0,0 +1,37 @@
+// FAQ
+
+.search-section {
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+.question {
+ float: none;
+ margin: 2em 0;
+ overflow: hidden;
+ transition: .2s ease-out;
+}
+
+.question--collapsed {
+ height: 0 !important; // Needs to override inline style
+ margin: 0;
+ border-width: 0;
+}
+
+.question--collapsed + .question {
+ margin-top: 0;
+}
+
+.question--unanswered {
+ padding-top: 1.25em;
+ border-top: 2px solid $emerald;
+}
+
+.question__title {
+ margin-top: 0;
+}
+
+.question__answer {
+ padding-bottom: 1px;
+ margin-bottom: 0;
+}
diff --git a/docs/_scss/pages/_homepage-filters.scss b/docs/_scss/pages/_homepage-filters.scss
new file mode 100644
index 0000000..4e59181
--- /dev/null
+++ b/docs/_scss/pages/_homepage-filters.scss
@@ -0,0 +1,19 @@
+
+// Filters
+.filter-label {
+ display: block;
+ margin-top: 0;
+ margin-bottom: 4px;
+ color: $gray60;
+}
+
+.filters-group {
+ margin-bottom: 4px;
+}
+
+@include breakpoint(sm) {
+ .filters-group-wrap {
+ display: flex;
+ justify-content: space-between;
+ }
+}
diff --git a/_scss/shuffle-styles.scss b/docs/_scss/shuffle-styles.scss
similarity index 72%
rename from _scss/shuffle-styles.scss
rename to docs/_scss/shuffle-styles.scss
index a07a0c2..aaabd31 100644
--- a/_scss/shuffle-styles.scss
+++ b/docs/_scss/shuffle-styles.scss
@@ -1,58 +1,68 @@
-@import "variables";
-@import "mixins";
+@import "./extensions/variables";
+@import "./extensions/mixins";
/*=============================================*\
Some styles to show off masonry layout
\*=============================================*/
-$pictureGutter: 24px;
-$itemHeight: 220px;
+$picture-gutter: 24px;
+$item-height: 220px;
.picture-item {
height: 220px;
- margin-top: $pictureGutter;
+ margin-top: $picture-gutter;
margin-left: 0; /* shuffle items shouldn't have a left margin*/
img {
display: block;
width: 100%;
+ }
+}
+
+@supports (object-fit: cover) {
+ .picture-item img {
max-width: none;
height: 100%;
object-fit: cover;
}
-
- .no-objectfit & img {
- height: auto;
- max-width: 100%;
- }
}
.picture-item--h2 {
- height: ($itemHeight * 2) + $pictureGutter; /* 2x the height + 1 gutter */
+ height: ($item-height * 2) + $picture-gutter; /* 2x the height + 1 gutter */
}
.picture-item__inner {
position: relative;
height: 100%;
overflow: hidden;
- background: $clouds;
+ background: $gray95;
}
-.picture-item__blur {
+img.picture-item__blur {
display: none;
}
-.picture-item__details,
-.picture-item__description {
- padding: 1em;
+.picture-item__details {
+ display: flex;
+ align-items: baseline;
+ justify-content: space-between;
width: 100%;
+ padding: 1em;
}
+
.picture-item__description {
+ width: 100%;
+ padding: 0 2em 1em 1em;
margin: 0;
- padding-top: 0;
- padding-right: 2em;
+}
+
+.picture-item__title {
+ flex-shrink: 0;
+ margin-right: 4px;
}
.picture-item__tags {
+ flex-shrink: 1;
+ text-align: right;
margin: 0;
}
@@ -86,7 +96,7 @@ $itemHeight: 220px;
left: 0;
display: block;
filter: blur(7px);
- clip-path: inset(#{$itemHeight - 50px} 0 0 0);
+ clip-path: inset(#{$item-height - 50px} 0 0 0);
}
.picture-item__details {
@@ -146,29 +156,20 @@ $itemHeight: 220px;
.picture-item {
height: auto;
margin-top: 20px;
+ }
- &.picture-item--h2 {
- height: auto;
- }
-
- .picture-item__details,
- .picture-item__description {
- font-size: .875em;
- padding: .625em;
- }
-
- .picture-item__description {
- padding-right: .875em;
- padding-bottom: 1.25em;
- }
+ .picture-item__details,
+ .picture-item__description {
+ font-size: .875em;
+ padding: .625em;
}
- .filter > .row,
- .filter > .row > div {
- margin: 10px 0;
+ .picture-item__description {
+ padding-right: .875em;
+ padding-bottom: 1.25em;
}
- .m-nofloat {
- float: none;
+ .picture-item--h2 {
+ height: auto;
}
}
diff --git a/docs/_scss/style.scss b/docs/_scss/style.scss
new file mode 100644
index 0000000..5303374
--- /dev/null
+++ b/docs/_scss/style.scss
@@ -0,0 +1,16 @@
+@import "./extensions/variables";
+@import "./extensions/mixins";
+
+@import "./global-rules/global";
+@import "./global-rules/type";
+@import "./global-rules/grid";
+@import "./global-rules/forms";
+@import "./global-rules/helpers";
+
+@import "./components/buttons";
+@import "./components/demo-list";
+@import "./components/site-nav";
+
+@import "./pages/homepage-filters";
+@import "./pages/compound-filters";
+@import "./pages/faq";
diff --git a/docs/css/normalize.css b/docs/css/normalize.css
new file mode 100644
index 0000000..e04d10a
--- /dev/null
+++ b/docs/css/normalize.css
@@ -0,0 +1,3 @@
+/*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */
+/* search cancel styles removed */
+html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,main,menu,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}abbr[title]{border-bottom:none;text-decoration:underline dotted}b,strong{font-weight:bolder}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{color:inherit;display:table;max-width:100%;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio],legend{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}[hidden],template{display:none}
diff --git a/css/prism.css b/docs/css/prism.css
similarity index 90%
rename from css/prism.css
rename to docs/css/prism.css
index 57ba41d..cf4a934 100644
--- a/css/prism.css
+++ b/docs/css/prism.css
@@ -1,4 +1,4 @@
-/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+scss&plugins=line-highlight+file-highlight */
+/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript+jsx+scss&plugins=line-highlight+file-highlight */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
@@ -150,9 +150,6 @@ pre[data-line] {
margin-top: 1em; /* Same as .prism’s padding-top */
background: hsla(24, 20%, 50%,.08);
- background: -moz-linear-gradient(to right, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
- background: -webkit-linear-gradient(to right, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
- background: -o-linear-gradient(to right, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
background: linear-gradient(to right, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
pointer-events: none;
diff --git a/docs/css/shuffle-styles.css b/docs/css/shuffle-styles.css
new file mode 100644
index 0000000..12eba13
--- /dev/null
+++ b/docs/css/shuffle-styles.css
@@ -0,0 +1 @@
+.picture-item{height:220px;margin-top:24px;margin-left:0}.picture-item img{display:block;width:100%}@supports ((-o-object-fit:cover) or (object-fit:cover)){.picture-item img{max-width:none;height:100%;-o-object-fit:cover;object-fit:cover}}.picture-item--h2{height:464px}.picture-item__inner{position:relative;height:100%;overflow:hidden;background:#ecf0f1}img.picture-item__blur{display:none}.picture-item__details{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;width:100%;padding:1em}.picture-item__description{width:100%;padding:0 2em 1em 1em;margin:0}.picture-item__title{-ms-flex-negative:0;flex-shrink:0;margin-right:4px}.picture-item__tags{-ms-flex-negative:1;flex-shrink:1;text-align:right;margin:0}@media screen and (min-width:768px){.picture-item--overlay .picture-item__details{position:absolute;bottom:0;left:0;width:100%;background-color:rgba(0,0,0,.6);color:#fff;overflow:hidden}.picture-item--overlay .picture-item__description{display:none}@supports ((-webkit-filter:blur(1px)) or (filter:blur(1px))) and ((-webkit-clip-path:inset(0 0 0 0)) or (clip-path:inset(0 0 0 0))){.picture-item--overlay .picture-item__blur{position:absolute;z-index:1;top:0;left:0;display:block;-webkit-filter:blur(7px);filter:blur(7px);-webkit-clip-path:inset(170px 0 0 0);clip-path:inset(170px 0 0 0)}.picture-item--overlay .picture-item__details{background:none}.picture-item--overlay .picture-item__tags,.picture-item--overlay .picture-item__title{position:relative;z-index:2}}}.my-shuffle-container{position:relative;overflow:hidden}.my-sizer-element{position:absolute;opacity:0;visibility:hidden}.shuffle--animatein{overflow:visible}.shuffle--animatein .picture-item__inner{opacity:0;-webkit-transform:translateY(220px);transform:translateY(220px)}.shuffle--animatein .picture-item__inner--transition{transition:all .6s ease}.shuffle--animatein .picture-item.in .picture-item__inner{opacity:1;-webkit-transform:translate(0);transform:translate(0)}@media screen and (max-width:767px){.picture-item{height:auto;margin-top:20px}.picture-item__description,.picture-item__details{font-size:.875em;padding:.625em}.picture-item__description{padding-right:.875em;padding-bottom:1.25em}.picture-item--h2{height:auto}}
\ No newline at end of file
diff --git a/docs/css/style.css b/docs/css/style.css
new file mode 100644
index 0000000..1b8c21b
--- /dev/null
+++ b/docs/css/style.css
@@ -0,0 +1 @@
+@charset "UTF-8";*,:after,:before{box-sizing:border-box}main{overflow:hidden}pre.max-height{max-height:30em}img,picture{display:block}img{max-width:100%;height:auto}figure,ul ul{margin:0}ul ul{padding-left:1.25em;list-style-type:circle}li{line-height:1.4}li+li{margin-top:4px}nav>a{display:block;margin:5px 0}#demos{margin-top:1em}body{font-family:Open Sans,Helvetica Neue,Helvetica,sans-serif;color:#5d6d77}a{text-decoration:none}a,a:visited{color:#3498db}a:hover{text-decoration:underline}a:active{color:#2ecc71}h1,h2,h3,h4,h5,h6{color:#34495e;font-weight:700}h1{font-size:10vw;font-weight:400;line-height:1}h1,h2{margin:3vw 0}h2{position:relative;font-size:7vw}h3{font-size:6vw;margin:2vw 0}h4{font-size:1.25em}p{margin:1em 0;line-height:1.4}.intro-text{margin:.7em 0;font-size:1.125em}@media screen and (min-width:768px){h1{margin:.5em 0 .25em;font-size:3.5em}h2{margin:.45em 0;font-size:2.5em}h3{margin:.8em 0 .5em;font-size:1.5em}h1>a,h2>a,h3>a{display:none}h1:hover>a,h2:hover>a,h3:hover>a{position:absolute;display:inline-block;top:0;height:50px;width:50px;background:url(../img/link.svg) no-repeat;overflow:hidden;text-indent:-999em}.intro-text{font-size:1.25em}}.unstyled{list-style-type:none;padding:0;margin:0}.type--underline{text-decoration:underline}code:not([class*=language]){padding:.2em 0;margin:0;font-size:85%;color:#2c3e50;background-color:rgba(27,31,35,.05);border-radius:3px;font-family:Menlo,Consolas,Liberation Mono,Courier,monospace}code:not([class*=language]):after,code:not([class*=language]):before{content:"\00a0";letter-spacing:-.2em}.container{padding-left:3.5%;padding-right:3.5%}.container:after,.container:before{content:" ";display:table}.container:after{clear:both}.row{margin-left:auto;margin-right:auto}.row:after,.row:before{content:" ";display:table}.row:after{clear:both}.row .row{margin-left:-8px;margin-right:-8px}.row--centered{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.aspect{position:relative;width:100%;height:0;overflow:hidden;padding-bottom:100%}.aspect--16x9{padding-bottom:56.25%}.aspect--9x16{padding-bottom:177.77778%}.aspect--4x3{padding-bottom:75%}.aspect--3x4{padding-bottom:133.33333%}.aspect--3x2{padding-bottom:66.66667%}.aspect--3x1{padding-bottom:33.33333%}.aspect--2x3{padding-bottom:150%}.aspect--2x1{padding-bottom:50%}.aspect--1x2{padding-bottom:200%}.aspect--1x1{padding-bottom:100%}.aspect--none{height:auto;padding-bottom:0;overflow:visible}.aspect--none>.aspect__inner{position:static}.aspect>div,.aspect__inner{position:absolute;top:0;left:0;right:0;bottom:0}.col-1\@lg,.col-1\@md,.col-1\@sm,.col-1\@xs,.col-2\@lg,.col-2\@md,.col-2\@sm,.col-2\@xs,.col-3\@lg,.col-3\@md,.col-3\@sm,.col-3\@xs,.col-4\@lg,.col-4\@md,.col-4\@sm,.col-4\@xs,.col-5\@lg,.col-5\@md,.col-5\@sm,.col-5\@xs,.col-6\@lg,.col-6\@md,.col-6\@sm,.col-6\@xs,.col-7\@lg,.col-7\@md,.col-7\@sm,.col-7\@xs,.col-8\@lg,.col-8\@md,.col-8\@sm,.col-8\@xs,.col-9\@lg,.col-9\@md,.col-9\@sm,.col-9\@xs,.col-10\@lg,.col-10\@md,.col-10\@sm,.col-10\@xs,.col-11\@lg,.col-11\@md,.col-11\@sm,.col-11\@xs,.col-12\@lg,.col-12\@md,.col-12\@sm,.col-12\@xs{position:relative;box-sizing:border-box;min-height:1px;padding-left:8px;padding-right:8px}.col-1\@xs,.col-2\@xs,.col-3\@xs,.col-4\@xs,.col-5\@xs,.col-6\@xs,.col-7\@xs,.col-8\@xs,.col-9\@xs,.col-10\@xs,.col-11\@xs,.col-12\@xs{float:left}.aspect--16x9\@xs{padding-bottom:56.25%}.aspect--9x16\@xs{padding-bottom:177.77778%}.aspect--4x3\@xs{padding-bottom:75%}.aspect--3x4\@xs{padding-bottom:133.33333%}.aspect--3x2\@xs{padding-bottom:66.66667%}.aspect--3x1\@xs{padding-bottom:33.33333%}.aspect--2x3\@xs{padding-bottom:150%}.aspect--2x1\@xs{padding-bottom:50%}.aspect--1x2\@xs{padding-bottom:200%}.aspect--1x1\@xs{padding-bottom:100%}.aspect--none\@xs{height:auto;padding-bottom:0;overflow:visible}.aspect--none\@xs>.aspect__inner{position:static}.col-1\@xs{width:16.66667%}.col-2\@xs{width:33.33333%}.col-3\@xs{width:50%}.col-4\@xs{width:66.66667%}.col-5\@xs{width:83.33333%}.col-6\@xs{width:100%}.col-pull-0\@xs{right:auto}.col-pull-1\@xs{right:16.66667%}.col-pull-2\@xs{right:33.33333%}.col-pull-3\@xs{right:50%}.col-pull-4\@xs{right:66.66667%}.col-pull-5\@xs{right:83.33333%}.col-pull-6\@xs{right:100%}.col-push-0\@xs{left:auto}.col-push-1\@xs{left:16.66667%}.col-push-2\@xs{left:33.33333%}.col-push-3\@xs{left:50%}.col-push-4\@xs{left:66.66667%}.col-push-5\@xs{left:83.33333%}.col-push-6\@xs{left:100%}.col-offset-0\@xs{margin-left:0}.col-offset-1\@xs{margin-left:16.66667%}.col-offset-2\@xs{margin-left:33.33333%}.col-offset-3\@xs{margin-left:50%}.col-offset-4\@xs{margin-left:66.66667%}.col-offset-5\@xs{margin-left:83.33333%}.col-offset-6\@xs{margin-left:100%}@media screen and (min-width:768px){.col-1\@sm,.col-2\@sm,.col-3\@sm,.col-4\@sm,.col-5\@sm,.col-6\@sm,.col-7\@sm,.col-8\@sm,.col-9\@sm,.col-10\@sm,.col-11\@sm,.col-12\@sm{float:left}.aspect--16x9\@sm{padding-bottom:56.25%}.aspect--9x16\@sm{padding-bottom:177.77778%}.aspect--4x3\@sm{padding-bottom:75%}.aspect--3x4\@sm{padding-bottom:133.33333%}.aspect--3x2\@sm{padding-bottom:66.66667%}.aspect--3x1\@sm{padding-bottom:33.33333%}.aspect--2x3\@sm{padding-bottom:150%}.aspect--2x1\@sm{padding-bottom:50%}.aspect--1x2\@sm{padding-bottom:200%}.aspect--1x1\@sm{padding-bottom:100%}.aspect--none\@sm{height:auto;padding-bottom:0;overflow:visible}.aspect--none\@sm>.aspect__inner{position:static}.col-1\@sm{width:8.33333%}.col-2\@sm{width:16.66667%}.col-3\@sm{width:25%}.col-4\@sm{width:33.33333%}.col-5\@sm{width:41.66667%}.col-6\@sm{width:50%}.col-7\@sm{width:58.33333%}.col-8\@sm{width:66.66667%}.col-9\@sm{width:75%}.col-10\@sm{width:83.33333%}.col-11\@sm{width:91.66667%}.col-12\@sm{width:100%}.col-pull-0\@sm{right:auto}.col-pull-1\@sm{right:8.33333%}.col-pull-2\@sm{right:16.66667%}.col-pull-3\@sm{right:25%}.col-pull-4\@sm{right:33.33333%}.col-pull-5\@sm{right:41.66667%}.col-pull-6\@sm{right:50%}.col-pull-7\@sm{right:58.33333%}.col-pull-8\@sm{right:66.66667%}.col-pull-9\@sm{right:75%}.col-pull-10\@sm{right:83.33333%}.col-pull-11\@sm{right:91.66667%}.col-pull-12\@sm{right:100%}.col-push-0\@sm{left:auto}.col-push-1\@sm{left:8.33333%}.col-push-2\@sm{left:16.66667%}.col-push-3\@sm{left:25%}.col-push-4\@sm{left:33.33333%}.col-push-5\@sm{left:41.66667%}.col-push-6\@sm{left:50%}.col-push-7\@sm{left:58.33333%}.col-push-8\@sm{left:66.66667%}.col-push-9\@sm{left:75%}.col-push-10\@sm{left:83.33333%}.col-push-11\@sm{left:91.66667%}.col-push-12\@sm{left:100%}.col-offset-0\@sm{margin-left:0}.col-offset-1\@sm{margin-left:8.33333%}.col-offset-2\@sm{margin-left:16.66667%}.col-offset-3\@sm{margin-left:25%}.col-offset-4\@sm{margin-left:33.33333%}.col-offset-5\@sm{margin-left:41.66667%}.col-offset-6\@sm{margin-left:50%}.col-offset-7\@sm{margin-left:58.33333%}.col-offset-8\@sm{margin-left:66.66667%}.col-offset-9\@sm{margin-left:75%}.col-offset-10\@sm{margin-left:83.33333%}.col-offset-11\@sm{margin-left:91.66667%}.col-offset-12\@sm{margin-left:100%}.container{padding-left:7%;padding-right:7%}.row{max-width:1200px}}@media screen and (min-width:1024px){.col-1\@md,.col-2\@md,.col-3\@md,.col-4\@md,.col-5\@md,.col-6\@md,.col-7\@md,.col-8\@md,.col-9\@md,.col-10\@md,.col-11\@md,.col-12\@md{float:left}.aspect--16x9\@md{padding-bottom:56.25%}.aspect--9x16\@md{padding-bottom:177.77778%}.aspect--4x3\@md{padding-bottom:75%}.aspect--3x4\@md{padding-bottom:133.33333%}.aspect--3x2\@md{padding-bottom:66.66667%}.aspect--3x1\@md{padding-bottom:33.33333%}.aspect--2x3\@md{padding-bottom:150%}.aspect--2x1\@md{padding-bottom:50%}.aspect--1x2\@md{padding-bottom:200%}.aspect--1x1\@md{padding-bottom:100%}.aspect--none\@md{height:auto;padding-bottom:0;overflow:visible}.aspect--none\@md>.aspect__inner{position:static}.col-1\@md{width:8.33333%}.col-2\@md{width:16.66667%}.col-3\@md{width:25%}.col-4\@md{width:33.33333%}.col-5\@md{width:41.66667%}.col-6\@md{width:50%}.col-7\@md{width:58.33333%}.col-8\@md{width:66.66667%}.col-9\@md{width:75%}.col-10\@md{width:83.33333%}.col-11\@md{width:91.66667%}.col-12\@md{width:100%}.col-pull-0\@md{right:auto}.col-pull-1\@md{right:8.33333%}.col-pull-2\@md{right:16.66667%}.col-pull-3\@md{right:25%}.col-pull-4\@md{right:33.33333%}.col-pull-5\@md{right:41.66667%}.col-pull-6\@md{right:50%}.col-pull-7\@md{right:58.33333%}.col-pull-8\@md{right:66.66667%}.col-pull-9\@md{right:75%}.col-pull-10\@md{right:83.33333%}.col-pull-11\@md{right:91.66667%}.col-pull-12\@md{right:100%}.col-push-0\@md{left:auto}.col-push-1\@md{left:8.33333%}.col-push-2\@md{left:16.66667%}.col-push-3\@md{left:25%}.col-push-4\@md{left:33.33333%}.col-push-5\@md{left:41.66667%}.col-push-6\@md{left:50%}.col-push-7\@md{left:58.33333%}.col-push-8\@md{left:66.66667%}.col-push-9\@md{left:75%}.col-push-10\@md{left:83.33333%}.col-push-11\@md{left:91.66667%}.col-push-12\@md{left:100%}.col-offset-0\@md{margin-left:0}.col-offset-1\@md{margin-left:8.33333%}.col-offset-2\@md{margin-left:16.66667%}.col-offset-3\@md{margin-left:25%}.col-offset-4\@md{margin-left:33.33333%}.col-offset-5\@md{margin-left:41.66667%}.col-offset-6\@md{margin-left:50%}.col-offset-7\@md{margin-left:58.33333%}.col-offset-8\@md{margin-left:66.66667%}.col-offset-9\@md{margin-left:75%}.col-offset-10\@md{margin-left:83.33333%}.col-offset-11\@md{margin-left:91.66667%}.col-offset-12\@md{margin-left:100%}}.code-block{position:relative;overflow:visible;margin:.5em calc(-3.5vw - 8px)}.code-block pre{position:relative;z-index:1;min-height:56px;padding:1em calc(3.5vw + 8px);margin:0}@media screen and (min-width:768px){.code-block{margin-left:calc(-7vw - 8px);margin-right:calc(-7vw - 8px)}.code-block pre{position:relative;z-index:1;padding-left:calc(7vw + 8px);padding-right:calc(7vw + 8px)}}@media (min-width:1395px){.code-block{margin-left:calc(-50vw + 592px);margin-right:calc(-50vw + 592px)}.code-block pre{padding-left:calc(50vw - 592px);padding-right:calc(50vw - 592px)}}.textfield{-webkit-appearance:none;box-sizing:border-box;width:100%;border:2px solid #95a5a6;border-radius:4px;padding:.5em;font-size:1rem;color:#34495e;transition:.15s}.textfield::-webkit-input-placeholder{color:#95a5a6;transition:.15s}.textfield:-ms-input-placeholder{color:#95a5a6;transition:.15s}.textfield::placeholder{color:#95a5a6;transition:.15s}.textfield:hover{outline-width:0;color:#5d6d77;border-color:#5d6d77}.textfield:hover::-webkit-input-placeholder{color:#5d6d77}.textfield:hover:-ms-input-placeholder{color:#5d6d77}.textfield:hover::placeholder{color:#5d6d77}.textfield:focus{outline-width:0;border-color:#34495e}.textfield:focus::-webkit-input-placeholder{color:#34495e}.textfield:focus:-ms-input-placeholder{color:#34495e}.textfield:focus::placeholder{color:#34495e}.textfield--large{font-size:1.125em}.text-center{text-align:center}.ib{display:inline-block}@media screen and (max-width:767px){.hidden\@xs{display:none}}@media screen and (min-width:768px){.visible\@xs{display:none}}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.clearfix,.clearfix:after{content:" ";display:table;clear:both}.pull-left{float:left}.pull-right{float:right}.full-width{width:100%}.full-height{height:100%}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.table-center-wrap{display:table;table-layout:fixed}.table-center{display:table-cell;vertical-align:middle}.btn-group:after,.btn-group:before{content:" ";display:table}.btn-group:after{clear:both}.btn-group .btn{float:left;border-radius:0}.btn-group .btn:first-child{border-radius:3px 0 0 3px}.btn-group .btn:not(:first-child){margin-left:-1px}.btn-group .btn:last-child{border-radius:0 3px 3px 0}.btn-group label.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn{display:inline-block;padding:.75em .8em;text-align:center;border-radius:3px;border:1px solid #34495e;color:#34495e;font-size:1rem;background-color:rgba(52,73,94,0);transition:.2s ease-out;cursor:pointer;-webkit-appearance:none}@media (-moz-touch-enabled:0),(pointer:fine){.btn:hover{color:#fff;text-decoration:none;background-color:#34495e}}.btn:focus{outline-width:0;box-shadow:0 0 0 2px rgba(52,73,94,.4)}.btn.active,.btn:active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3);color:#fff;background-color:#34495e}.btn:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(52,73,94,.4)}.btn--warning{color:#e67e22;border-color:#e67e22;background-color:rgba(230,126,34,0)}@media (-moz-touch-enabled:0),(pointer:fine){.btn--warning:hover{background-color:#e67e22}}.btn--warning:focus{box-shadow:0 0 0 2px rgba(230,126,34,.4)}.btn--warning.active,.btn--warning:active{background-color:#e67e22}.btn--warning:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(230,126,34,.4)}.btn--primary{color:#3498db;border-color:#3498db;background-color:rgba(52,152,219,0)}@media (-moz-touch-enabled:0),(pointer:fine){.btn--primary:hover{background-color:#3498db}}.btn--primary:focus{box-shadow:0 0 0 2px rgba(52,152,219,.4)}.btn--primary.active,.btn--primary:active{background-color:#3498db}.btn--primary:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(52,152,219,.4)}.btn--danger{color:#e74c3c;border-color:#e74c3c;background-color:rgba(231,76,60,0)}@media (-moz-touch-enabled:0),(pointer:fine){.btn--danger:hover{background-color:#e74c3c}}.btn--danger:focus{box-shadow:0 0 0 2px rgba(231,76,60,.4)}.btn--danger.active,.btn--danger:active{background-color:#e74c3c}.btn--danger:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(231,76,60,.4)}.btn--go{color:#2ecc71;border-color:#2ecc71;background-color:rgba(46,204,113,0)}@media (-moz-touch-enabled:0),(pointer:fine){.btn--go:hover{background-color:#2ecc71}}.btn--go:focus{box-shadow:0 0 0 2px rgba(46,204,113,.4)}.btn--go.active,.btn--go:active{background-color:#2ecc71}.btn--go:focus.active{box-shadow:inset 0 1px 2px rgba(0,0,0,.3),0 0 0 2px rgba(46,204,113,.4)}@media screen and (max-width:767px){.btn{font-size:.875rem}}.filter-group .btn{position:relative}.filter-group .btn.active:after,.filter-group .btn.active:before{content:"";position:absolute;top:50%;left:50%;width:20px;height:20px;margin-left:-10px;margin-top:-10px;opacity:0;transition:.2s}.filter-group .btn:before{background-color:#2c3e50;border-radius:50%}.filter-group .btn:after{background-size:60%;background-position:50%;background-repeat:no-repeat;background-image:url(../img/check.svg)}.filter-group .btn.active:after,.filter-group .btn.active:before{opacity:1}.demo-list .figure-wrap{position:relative;z-index:1}.demo-list .figure-wrap,.demo-list .figure-wrap img{-webkit-transform:translateZ(0);transform:translateZ(0);transition:.1s ease}.demo-list:hover .figure-wrap{-webkit-transform:scaleX(1);transform:scaleX(1)}.demo-list:hover .figure-wrap img{-webkit-filter:grayscale(1);filter:grayscale(1)}.demo-list:hover .figure-wrap:hover{z-index:2;-webkit-transform:scale3d(1.05,1.05,1);transform:scale3d(1.05,1.05,1)}.demo-list:hover .figure-wrap:hover img{-webkit-filter:none;filter:none}.demo-list .figure-wrap:nth-child(4n+1){margin-left:0}.demo-list .figure-wrap>a{display:block}.demo-list .figure-wrap figcaption{height:2em;margin-top:.5em;margin-bottom:1em}.demo-link-container:before{content:"➜";color:#2ecc71;margin-right:5px}span.demo-link-container:before{margin-left:5px}@media screen and (max-width:47.9375em){.demo-list+.demo-list{margin-top:1em}.figure-wrap:nth-child(odd){margin-left:0}.figure-wrap:nth-child(n+3){margin-top:1em}}.site-nav{padding:10px 0;border-bottom:1px solid #e1e5e6;margin-bottom:28px;background:#ecf0f1}.site-nav__content{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.site-nav__logo{font-size:20px}.site-nav__logo,.site-nav__logo:visited{color:#34495e}.site-nav__logo:hover,.site-nav__logo:visited:hover{text-decoration:none}.site-nav__links,.site-nav__logo{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.site-nav__logo svg{display:block;width:24px;height:24px;margin-right:4px}.site-nav__logo rect{transition:.18s cubic-bezier(.4,0,.2,1)}.site-nav__link{position:relative;z-index:3}.site-nav__link:not(:last-of-type){margin-right:8px}.site-nav__dropdown{position:absolute;z-index:2;top:40px;right:0;opacity:0;visibility:hidden;max-height:100vh;transition:.3s cubic-bezier(.165,.84,.44,1);background-color:#fff;-webkit-transform:translateY(10px);transform:translateY(10px);box-shadow:0 7px 10px -1px rgba(0,0,0,.12)}.site-nav__dropdown:before{content:"";position:absolute;top:-8px;right:32px;display:block;border-bottom:8px solid #fff;border-left:9px solid transparent;border-right:9px solid transparent}.site-nav__dropdown li+li{margin-top:8px}.site-nav__dropdown a{display:block;color:#5d6d77}.site-nav__dropdown a:hover{background-color:#ecf0f1;text-decoration:none;color:#5d6d77}.site-nav__dropdown figure{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.site-nav__dropdown picture{-ms-flex-negative:0;flex-shrink:0;width:100px;height:75px}.site-nav__dropdown figcaption{padding-left:8px;padding-right:8px}.site-nav__dropdown--simple-links a{padding:8px 16px}.site-nav__dropdown--simple-links li+li{margin-top:0}.site-nav__link-toggle{padding:6px 8px}.site-nav__link-toggle:after{content:"";display:inline-block;vertical-align:middle;margin-top:-1px;margin-left:4px;border-top:6px solid;border-left:5px solid transparent;border-right:5px solid transparent;transition:-webkit-transform .18s cubic-bezier(.4,0,.2,1);transition:transform .18s cubic-bezier(.4,0,.2,1);transition:transform .18s cubic-bezier(.4,0,.2,1),-webkit-transform .18s cubic-bezier(.4,0,.2,1)}.site-nav__link--dropdown-active .site-nav__link-toggle:after{-webkit-transform:rotate(-180deg);transform:rotate(-180deg)}.site-nav__link--dropdown-active .site-nav__dropdown{visibility:visible;opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}@media (-moz-touch-enabled:0),(pointer:fine){.site-nav__logo:hover rect:first-of-type{-webkit-transform:translate(20px,10px);transform:translate(20px,10px);transition-delay:0ms}.site-nav__logo:hover rect:nth-of-type(2){-webkit-transform:translateY(20px);transform:translateY(20px);transition-delay:10ms}.site-nav__logo:hover rect:nth-of-type(3){-webkit-transform:translate(-20px,6px);transform:translate(-20px,6px);transition-delay:20ms}.site-nav__logo:hover rect:nth-of-type(4){-webkit-transform:translate(10px,-10px);transform:translate(10px,-10px);transition-delay:30ms}.site-nav__logo:hover rect:nth-of-type(5){-webkit-transform:translate(-10px,10px);transform:translate(-10px,10px);transition-delay:40ms}.site-nav__logo:hover rect:nth-of-type(6){-webkit-transform:translate(-20px,-14px);transform:translate(-20px,-14px);transition-delay:50ms}.site-nav__logo:hover rect:nth-of-type(7){-webkit-transform:translateY(-20px);transform:translateY(-20px);transition-delay:60ms}.site-nav__link-toggle:hover{border-color:#34495e}}@media screen and (max-width:767px){body.site-nav--open{padding-top:51px}body.site-nav--open .site-nav{position:fixed;z-index:4;top:0;left:0;width:100%}.site-nav__dropdown{position:fixed;left:0;right:0;top:51px;width:100vw;padding:8px calc(3.5vw + 8px);overflow:auto;-webkit-overflow-scrolling:touch}}@media screen and (min-width:768px){.site-nav{padding:16px 0}.site-nav__logo{font-size:24px}.site-nav__logo svg{width:32px;height:32px}.site-nav__link:not(:last-child){margin-right:16px}.site-nav__link--dropdown:not(:last-child){margin-right:12px}.site-nav__dropdown{max-height:none!important;right:-100px;padding:16px;box-shadow:0 0 10px rgba(0,0,0,.12)}.site-nav__dropdown:before{right:132px}.site-nav__dropdown ul{-webkit-column-count:2;column-count:2;-webkit-column-gap:16px;column-gap:16px}.site-nav__dropdown li{-webkit-column-break-inside:avoid;break-inside:avoid}.site-nav__dropdown figcaption{white-space:nowrap}@supports ((-webkit-filter:drop-shadow(0 0 5px rgba(0,0,0,0.12))) or (filter:drop-shadow(0 0 5px rgba(0,0,0,0.12)))){.site-nav__dropdown{box-shadow:none;-webkit-filter:drop-shadow(0 0 5px rgba(0,0,0,.12));filter:drop-shadow(0 0 5px rgba(0,0,0,.12))}}.site-nav__link-img{width:24px;height:24px}.site-nav__dropdown--simple-links{right:0;padding:0}.site-nav__dropdown--simple-links:before{right:24px}.site-nav__dropdown--simple-links a{width:200px}}@media screen and (min-width:1024px){.site-nav__dropdown{right:0}.site-nav__dropdown:before{right:32px}.site-nav__dropdown--simple-links:before{right:24px}}.site-footer{margin-top:2em;padding:1em 0;background-color:#34495e}.site-footer p{color:#ecf0f1}.site-footer a{color:#fff;text-decoration:underline}.site-footer a:hover{color:#3498db}.has-code-block .code-block pre{margin-bottom:0}.has-code-block+.site-footer{margin-top:0}@media screen and (min-width:768px){.site-footer__credit{text-align:right}}.filter-label{display:block;margin-top:0;color:#95a5a6}.filter-label,.filters-group{margin-bottom:4px}@media screen and (min-width:768px){.filters-group-wrap{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}}.compound-filter-options{margin-top:20px;margin-bottom:40px}.filter-group--compound button{width:40px;height:40px;padding:0;background-color:currentColor}.filter-group--compound label{cursor:pointer}.filter-group--compound .ib+.ib{margin-left:8px}.shape-shuffle-container{position:relative;overflow:hidden}.shape{position:relative;margin-left:0;margin-top:10px}.shape .shape__space{width:100%;height:100%;background-color:#000;border:0 solid transparent}.shape--blue .shape__space{background-color:#3498db;border-bottom-color:#3498db}.shape--red .shape__space{background-color:#e74c3c;border-bottom-color:#e74c3c}.shape--orange .shape__space{background-color:#f39c12;border-bottom-color:#f39c12}.shape--green .shape__space{background-color:#2ecc71;border-bottom-color:#2ecc71}.shape--circle .shape__space{border-radius:50%}.shape--diamond .shape__space{-webkit-transform:rotate(45deg) scale(.70711);transform:rotate(45deg) scale(.70711)}.shape--triangle .shape__space{padding-top:9px;height:0;width:0;border-width:0 66px 114px;background-color:transparent;margin:auto}@media (min-width:425px){.shape--triangle .shape__space{padding-top:12px;height:0;width:0;border-width:0 90px 156px}}@media (min-width:600px){.shape--triangle .shape__space{padding-top:17.5px;height:0;width:0;border-width:0 131px 227px}}@media (min-width:768px){.shape--triangle .shape__space{padding-top:10px;height:0;width:0;border-width:0 74px 128px}}@media (min-width:1024px){.shape--triangle .shape__space{padding-top:13.5px;height:0;width:0;border-width:0 102px 177px}}@media (min-width:1200px){.shape--triangle .shape__space{padding-top:18px;height:0;width:0;border-width:0 135px 234px}}@media (min-width:1392px){.shape--triangle .shape__space{padding-top:19px;height:0;width:0;border-width:0 142px 246px}}.search-section{margin-top:1em;margin-bottom:1em}.question{float:none;margin:2em 0;overflow:hidden;transition:.2s ease-out}.question--collapsed{height:0!important;margin:0;border-width:0}.question--collapsed+.question{margin-top:0}.question--unanswered{padding-top:1.25em;border-top:2px solid #2ecc71}.question__title{margin-top:0}.question__answer{padding-bottom:1px;margin-bottom:0}
\ No newline at end of file
diff --git a/docs/dist b/docs/dist
new file mode 120000
index 0000000..85d8c32
--- /dev/null
+++ b/docs/dist
@@ -0,0 +1 @@
+../dist
\ No newline at end of file
diff --git a/favicon.png b/docs/favicon.png
similarity index 100%
rename from favicon.png
rename to docs/favicon.png
diff --git a/img/check.svg b/docs/img/check.svg
similarity index 100%
rename from img/check.svg
rename to docs/img/check.svg
diff --git a/docs/img/demos/adding-removing.jpg b/docs/img/demos/adding-removing.jpg
new file mode 100644
index 0000000..55c0ae8
Binary files /dev/null and b/docs/img/demos/adding-removing.jpg differ
diff --git a/docs/img/demos/adding-removing.webp b/docs/img/demos/adding-removing.webp
new file mode 100644
index 0000000..afdb6b2
Binary files /dev/null and b/docs/img/demos/adding-removing.webp differ
diff --git a/docs/img/demos/animated.jpg b/docs/img/demos/animated.jpg
new file mode 100644
index 0000000..404d72c
Binary files /dev/null and b/docs/img/demos/animated.jpg differ
diff --git a/docs/img/demos/animated.webp b/docs/img/demos/animated.webp
new file mode 100644
index 0000000..a08b906
Binary files /dev/null and b/docs/img/demos/animated.webp differ
diff --git a/docs/img/demos/basic.jpg b/docs/img/demos/basic.jpg
new file mode 100644
index 0000000..6479e5d
Binary files /dev/null and b/docs/img/demos/basic.jpg differ
diff --git a/docs/img/demos/basic.webp b/docs/img/demos/basic.webp
new file mode 100644
index 0000000..aa6200a
Binary files /dev/null and b/docs/img/demos/basic.webp differ
diff --git a/docs/img/demos/bootstrap3-grid.jpg b/docs/img/demos/bootstrap3-grid.jpg
new file mode 100644
index 0000000..266ee4e
Binary files /dev/null and b/docs/img/demos/bootstrap3-grid.jpg differ
diff --git a/docs/img/demos/bootstrap3-grid.webp b/docs/img/demos/bootstrap3-grid.webp
new file mode 100644
index 0000000..414b154
Binary files /dev/null and b/docs/img/demos/bootstrap3-grid.webp differ
diff --git a/docs/img/demos/codepen-template.jpg b/docs/img/demos/codepen-template.jpg
new file mode 100644
index 0000000..6a238d1
Binary files /dev/null and b/docs/img/demos/codepen-template.jpg differ
diff --git a/docs/img/demos/codepen-template.webp b/docs/img/demos/codepen-template.webp
new file mode 100644
index 0000000..94b5c46
Binary files /dev/null and b/docs/img/demos/codepen-template.webp differ
diff --git a/docs/img/demos/compound-filters.jpg b/docs/img/demos/compound-filters.jpg
new file mode 100644
index 0000000..6ee299e
Binary files /dev/null and b/docs/img/demos/compound-filters.jpg differ
diff --git a/docs/img/demos/compound-filters.webp b/docs/img/demos/compound-filters.webp
new file mode 100644
index 0000000..b6d906d
Binary files /dev/null and b/docs/img/demos/compound-filters.webp differ
diff --git a/docs/img/demos/flexbox-grid.jpg b/docs/img/demos/flexbox-grid.jpg
new file mode 100644
index 0000000..f55ee5b
Binary files /dev/null and b/docs/img/demos/flexbox-grid.jpg differ
diff --git a/docs/img/demos/flexbox-grid.webp b/docs/img/demos/flexbox-grid.webp
new file mode 100644
index 0000000..383e140
Binary files /dev/null and b/docs/img/demos/flexbox-grid.webp differ
diff --git a/docs/img/demos/images.jpg b/docs/img/demos/images.jpg
new file mode 100644
index 0000000..0ddf7f8
Binary files /dev/null and b/docs/img/demos/images.jpg differ
diff --git a/docs/img/demos/images.webp b/docs/img/demos/images.webp
new file mode 100644
index 0000000..de3a930
Binary files /dev/null and b/docs/img/demos/images.webp differ
diff --git a/docs/img/demos/requirejs.jpg b/docs/img/demos/requirejs.jpg
new file mode 100644
index 0000000..818d444
Binary files /dev/null and b/docs/img/demos/requirejs.jpg differ
diff --git a/docs/img/demos/requirejs.webp b/docs/img/demos/requirejs.webp
new file mode 100644
index 0000000..57e2a6b
Binary files /dev/null and b/docs/img/demos/requirejs.webp differ
diff --git a/docs/img/demos/shuffle-with-react.jpg b/docs/img/demos/shuffle-with-react.jpg
new file mode 100644
index 0000000..9ea36b8
Binary files /dev/null and b/docs/img/demos/shuffle-with-react.jpg differ
diff --git a/docs/img/demos/shuffle-with-react.webp b/docs/img/demos/shuffle-with-react.webp
new file mode 100644
index 0000000..6397e6c
Binary files /dev/null and b/docs/img/demos/shuffle-with-react.webp differ
diff --git a/img/favicon-sprite.png b/docs/img/favicon-sprite.png
similarity index 100%
rename from img/favicon-sprite.png
rename to docs/img/favicon-sprite.png
diff --git a/img/favicon-sprite@2x.png b/docs/img/favicon-sprite@2x.png
similarity index 100%
rename from img/favicon-sprite@2x.png
rename to docs/img/favicon-sprite@2x.png
diff --git a/img/favicon.psd b/docs/img/favicon.psd
similarity index 100%
rename from img/favicon.psd
rename to docs/img/favicon.psd
diff --git a/docs/img/favicon.svg b/docs/img/favicon.svg
new file mode 100644
index 0000000..8de3579
--- /dev/null
+++ b/docs/img/favicon.svg
@@ -0,0 +1,10 @@
+
+ Shuffle.js logo
+
+
+
+
+
+
+
+
diff --git a/docs/img/github.svg b/docs/img/github.svg
new file mode 100644
index 0000000..e850b94
--- /dev/null
+++ b/docs/img/github.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/img/link.svg b/docs/img/link.svg
similarity index 100%
rename from img/link.svg
rename to docs/img/link.svg
diff --git a/img/shuffle.png b/docs/img/shuffle.png
similarity index 100%
rename from img/shuffle.png
rename to docs/img/shuffle.png
diff --git a/index.html b/docs/index.html
similarity index 66%
rename from index.html
rename to docs/index.html
index aa14024..04c9d26 100644
--- a/index.html
+++ b/docs/index.html
@@ -2,34 +2,18 @@
layout: default
title: Shuffle.js
bodyClass: home
-extraJS: [ "demos/homepage.js" ]
+extraJS: [ "demos/homepage.js", "animated-favicon.js" ]
includeHeader: true
prism: true
---
-
-
-
-
npm install shufflejs --save
-
-
Shuffle is also available on bower as shufflejs
.
-
-
-
-
@@ -39,31 +23,41 @@ prism: true
-
+
-
-
-
Filter:
-
-
Wallpapers
-
Graphic Design
-
Photos
-
3D Renders
+
+
+
+
Filter
+
+ Space
+ Nature
+ Animal
+ City
+
-
-
-
-
Sort:
-
- Default
- Title
- Date Created
-
+
@@ -72,10 +66,10 @@ prism: true
- {% for item in site.data.items %}
- {% assign item = item %}
- {% include picture-item.html %}
- {% endfor %}
+ {%- for item in site.data.items -%}
+ {%- assign item = item -%}
+ {%- include picture-item.html -%}
+ {%- endfor -%}
@@ -122,11 +116,21 @@ prism: true
-
+
- {% include events.html %}
+ {% include filters.html %}
+
+
+
+
+
+
+
+
+
+ {% include advanced-filters.html %}
@@ -142,11 +146,11 @@ prism: true
-
+
- {% include advanced-filters.html %}
+ {% include events.html %}
@@ -200,17 +204,17 @@ prism: true
Dependencies
Shuffle's dependencies are bundled with the dist file.
+
Shuffle does, however, expect the following ES6/7 features: Set
, Array.from
, Object.assign
, Array.prototype.find
, and Array.prototype.includes
. In order to support browsers like IE11 and Safari 8, you must include a polyfill for these features. You can use a service like polyfill.io to only load the polyfills that specific browser needs, or a polyfill script like babel-polyfill (which uses core-js
internally).
-
-
+
-
Supported Browsers
+
Supported Browsers
Chrome
@@ -220,7 +224,7 @@ prism: true
Safari
-
Support for other browsers may be added with polyfills for ES5 features. If you require broader browser support, use the most recent v3
release of Shuffle.
+
Depending on what browsers you support, you may need to polyfill features used by Shuffle .
@@ -243,7 +247,6 @@ prism: true
-
@@ -254,9 +257,6 @@ prism: true
-
-{% include credit-jake.html %}
-
+
diff --git a/test/test.js b/test/test.js
index ea2c23e..ad36006 100644
--- a/test/test.js
+++ b/test/test.js
@@ -8,7 +8,7 @@ var sinon = window.sinon;
describe('shuffle', function () {
- var Shuffle = window.shuffle;
+ var Shuffle = window.Shuffle;
var fixtures = {};
var fixture;
var instance;
@@ -62,19 +62,6 @@ describe('shuffle', function () {
fixture = null;
}
- function once(element, eventType, fn) {
- var handler = function (e) {
- element.removeEventListener(eventType, handler);
- fn(e);
- };
-
- element.addEventListener(eventType, handler);
- }
-
- function toArray(thing) {
- return Array.prototype.slice.call(thing);
- }
-
function id(id) {
return document.getElementById(id);
}
@@ -110,7 +97,6 @@ describe('shuffle', function () {
expect(instance.options.delimeter).to.equal(null);
expect(instance.options.initialSort).to.equal(null);
expect(instance.options.throttleTime).to.equal(300);
- expect(instance.useSizer).to.equal(false);
expect(instance.id).to.equal('shuffle_0');
expect(instance.isInitialized).to.be.true;
@@ -128,13 +114,13 @@ describe('shuffle', function () {
instance.items.forEach(function (item) {
expect(item.element).to.have.class('shuffle-item');
expect(item.element).to.have.class('shuffle-item--visible');
- expect(item.element.style.opacity).to.be.defined;
+ expect(item.element.style.opacity).to.be.exist;
expect(item.element.style.position).to.equal('absolute');
expect(item.element.style.visibility).to.equal('visible');
expect(item.isVisible).to.equal(true);
expect(item.scale).to.equal(Shuffle.ShuffleItem.Scale.VISIBLE);
- expect(item.point.x).to.be.defined;
- expect(item.point.y).to.be.defined;
+ expect(item.point.x).to.be.exist;
+ expect(item.point.y).to.be.exist;
});
});
@@ -237,7 +223,7 @@ describe('shuffle', function () {
expect(element.style.visibility).to.equal('visible');
});
- once(fixture, Shuffle.EventType.LAYOUT, third);
+ instance.once(Shuffle.EventType.LAYOUT, third);
// Filter by green.
instance.filter('green');
@@ -266,7 +252,7 @@ describe('shuffle', function () {
done();
}
- once(fixture, Shuffle.EventType.LAYOUT, second);
+ instance.once(Shuffle.EventType.LAYOUT, second);
instance.filter('design');
});
@@ -317,6 +303,42 @@ describe('shuffle', function () {
expect(Shuffle.__getAvailablePositions(positions, 2, 4)).to.deep.equal([150, 0, 0]);
});
+ it('can center already-positioned items', function() {
+ // 4-2-1 even heights
+ expect(Shuffle.__getCenteredPositions([
+ new Shuffle.Rect(0, 0, 250, 100, 0),
+ new Shuffle.Rect(250, 0, 250, 100, 1),
+ new Shuffle.Rect(500, 0, 250, 100, 2),
+ new Shuffle.Rect(750, 0, 250, 100, 3),
+ new Shuffle.Rect(0, 100, 600, 100, 4),
+ new Shuffle.Rect(600, 100, 300, 100, 5),
+ new Shuffle.Rect(0, 200, 250, 100, 6),
+ ], 1000)).to.deep.equal([
+ new Shuffle.Point(0, 0),
+ new Shuffle.Point(250, 0),
+ new Shuffle.Point(500, 0),
+ new Shuffle.Point(750, 0),
+ new Shuffle.Point(50, 100),
+ new Shuffle.Point(650, 100),
+ new Shuffle.Point(375, 200),
+ ]);
+
+ // 4 columns:
+ // 2x2 1x1
+ // 2x1
+ // Centers the first row, but then finds that the 3rd item will overlap
+ // the 2x2 and resets the first row.
+ expect(Shuffle.__getCenteredPositions([
+ new Shuffle.Rect(0, 0, 500, 200, 0),
+ new Shuffle.Rect(500, 0, 250, 100, 1),
+ new Shuffle.Rect(500, 100, 500, 100, 2),
+ ], 1000)).to.deep.equal([
+ new Shuffle.Point(0, 0),
+ new Shuffle.Point(500, 0),
+ new Shuffle.Point(500, 100),
+ ]);
+ });
+
it('can get an element option', function () {
instance = new Shuffle(fixture);
var first = fixture.firstElementChild;
@@ -393,13 +415,13 @@ describe('shuffle', function () {
instance.destroy();
expect(instance.element).to.be.null;
- expect(instance.items).to.be.null;
+ expect(instance.items).to.have.lengthOf(0);
expect(instance.options.sizer).to.be.null;
expect(instance.isDestroyed).to.be.true;
expect(fixture).to.not.have.class('shuffle');
- toArray(fixture.children).forEach(function (child) {
+ Array.from(fixture.children).forEach(function (child) {
expect(child).to.not.have.class('shuffle-item');
expect(child).to.not.have.class('shuffle-item--visible');
expect(child).to.not.have.class('shuffle-item--hidden');
@@ -425,20 +447,20 @@ describe('shuffle', function () {
expect(update.called).to.be.false;
});
- it('should not update when the container is the same size', function () {
+ it('should still update when the container is the same size', function () {
instance = new Shuffle(fixture);
var update = sinon.spy(instance, 'update');
instance._onResize();
- expect(update.called).to.be.false;
+ expect(update.called).to.be.true;
});
describe('removing elements', function () {
var children;
beforeEach(function () {
- children = toArray(fixture.children);
+ children = Array.from(fixture.children);
});
afterEach(function () {
@@ -450,12 +472,11 @@ describe('shuffle', function () {
speed: 16,
});
- once(fixture, Shuffle.EventType.REMOVED, function (evt) {
- var detail = evt.detail;
- expect(detail.shuffle.visibleItems).to.equal(8);
- expect(detail.collection[0].id).to.equal('item1');
- expect(detail.collection[1].id).to.equal('item2');
- expect(detail.shuffle.element.children).to.have.lengthOf(8);
+ instance.once(Shuffle.EventType.REMOVED, function (data) {
+ expect(data.shuffle.visibleItems).to.equal(8);
+ expect(data.collection[0].id).to.equal('item1');
+ expect(data.collection[1].id).to.equal('item2');
+ expect(data.shuffle.element.children).to.have.lengthOf(8);
expect(instance.isTransitioning).to.be.false;
done();
});
@@ -470,13 +491,12 @@ describe('shuffle', function () {
useTransforms: false,
});
- once(fixture, Shuffle.EventType.REMOVED, function (evt) {
- var detail = evt.detail;
- expect(detail.shuffle.visibleItems).to.equal(8);
- expect(detail.collection[0].id).to.equal('item2');
- expect(detail.collection[1].id).to.equal('item3');
- expect(detail.shuffle.element.children).to.have.lengthOf(8);
- expect(detail.shuffle.isTransitioning).to.be.false;
+ instance.once(Shuffle.EventType.REMOVED, function (data) {
+ expect(data.shuffle.visibleItems).to.equal(8);
+ expect(data.collection[0].id).to.equal('item2');
+ expect(data.collection[1].id).to.equal('item3');
+ expect(data.shuffle.element.children).to.have.lengthOf(8);
+ expect(data.shuffle.isTransitioning).to.be.false;
done();
});
@@ -538,14 +558,11 @@ describe('shuffle', function () {
});
});
- afterEach(function (done) {
- once(fixture, Shuffle.EventType.LAYOUT, function () {
- items.length = 0;
- done();
- });
+ afterEach(function () {
+ items.length = 0;
});
- it('can add items', function () {
+ it('can add items', function (done) {
fixture.appendChild(items[0]);
fixture.appendChild(items[1]);
instance.add(items);
@@ -553,9 +570,13 @@ describe('shuffle', function () {
// Already 2 in the items, plus number 11.
expect(instance.visibleItems).to.equal(3);
expect(instance.items).to.have.lengthOf(12);
+
+ instance.once(Shuffle.EventType.LAYOUT, function () {
+ done();
+ });
});
- it('can prepend items', function () {
+ it('can prepend items', function (done) {
fixture.insertBefore(items[1], fixture.firstElementChild);
fixture.insertBefore(items[0], fixture.firstElementChild);
instance.add(items);
@@ -563,6 +584,23 @@ describe('shuffle', function () {
expect(instance.items[0].element).to.equal(items[0]);
expect(instance.items[1].element).to.equal(items[1]);
expect(instance.items).to.have.lengthOf(12);
+
+ instance.once(Shuffle.EventType.LAYOUT, function () {
+ done();
+ });
+ });
+
+ it('can reset items', function () {
+ fixture.textContent = '';
+ fixture.appendChild(items[0]);
+ fixture.appendChild(items[1]);
+
+ instance.resetItems();
+
+ expect(instance.isInitialized).to.be.true;
+ expect(instance.items[0].element).to.equal(items[0]);
+ expect(instance.items[1].element).to.equal(items[1]);
+ expect(instance.items).to.have.lengthOf(2);
});
});
@@ -632,11 +670,11 @@ describe('shuffle', function () {
beforeEach(function (done) {
appendFixture('regular').then(function () {
- items = toArray(fixture.children).map(function (element) {
+ items = Array.from(fixture.children).map(function (element) {
return { element: element };
});
- clone = toArray(items);
+ clone = Array.from(items);
done();
});
@@ -656,7 +694,7 @@ describe('shuffle', function () {
expect(items).to.have.lengthOf(10);
expect(Shuffle.__sorter(items)).to.deep.equal(items);
- var clone = toArray(items);
+ var clone = Array.from(items);
expect(Shuffle.__sorter(clone, { randomize: true })).to.not.deep.equal(items);
});