Skip to content

Instantly share code, notes, and snippets.

@sveetch
Created May 26, 2015 15:06
Show Gist options
  • Save sveetch/bd47274f57460dcd5993 to your computer and use it in GitHub Desktop.
Save sveetch/bd47274f57460dcd5993 to your computer and use it in GitHub Desktop.
SCSS mixins to add support for Flexbox prefixes for IE10
@import "compass/css3";
@import "compass/css3/shared";
// For more information see https://gist.github.com/cimmanon/727c9d558b374d27c5b6
// NOTE:
// -----
// All mixins for the @box spec have been written assuming they'll be fed property values that
// correspond to the standard spec. Some mixins can be fed values from the @box spec, but don't
// rely on it. The `legacy-order` mixin will increment the value fed to it because the @box
// `box-ordinal-group` property begins indexing at 1, while the modern `order` property begins
// indexing at 0.
// @private Flex
// -------------
// September 2012 Candidate Recommendation (http://www.w3.org/TR/2012/CR-css3-flexbox-20120918/)
// NOTE: FF did not support wrapping until version ??. Because the `display: flex` property
// is wrapped in a `@supports (flex-wrap: wrap)` block (when $flex-wrap-required or the $wrap
// argument to the `display-flex` mixin is set to `true`), it will Just Work(TM) when support is
// finally added
// Chrome 21 (prefixed)
// Opera 12.1 (unprefixed)
// Firefox 20 (unprefixed)
// @private css3-feature-support variables must always include a list of five boolean values
// representing in order: -moz, -webkit, -o, -ms, -khtml.
$flex-support: not -moz, -webkit, not -o, not -ms, not -khtml !default;
// if `true`, `$flex-legacy-enabled` is treated as false and an `@supports` block is added to
// the display property to hide the standard value from versions of Firefox that support the
// unprefixed properties, but do not support wrapping
// (this includes suppressing the automatic emittion of @box properties)
$flex-wrap-required : false !default;
// @private Flexbox
// ----------------
// March 2012 Working Draft (http://www.w3.org/TR/2012/WD-css3-flexbox-20120322/)
// Chrome 17 (prefixed)
// Internet Explorer 10 (prefixed)
// @private css3-feature-support variables must always include a list of five boolean values
// representing in order: -moz, -webkit, -o, -ms, -khtml.
$flexbox-support: not -moz, not -webkit, not -o, -ms, not -khtml, not standard !default;
// @private Box
// ------------
// July 2009 Working Draft (http://www.w3.org/TR/2009/WD-css3-flexbox-20090723/)
// NOTE: no browser that implements this spec is known to support `box-lines: multiple`
// Chrome 4? (prefixed)
// Safari 3.1 (prefixed)
// Firefox <20 (prefixed)
// @private css3-feature-support variables must always include a list of five boolean values
// representing in order: -moz, -webkit, -o, -ms, -khtml.
$box-support: -moz, -webkit, not -o, not -ms, not -khtml, not standard !default;
// If `true`, the @box properties will be emitted as part of the normal mixin call
// (if this is false, you're still free to explicitly call the legacy mixins yourself)
$flex-legacy-enabled: false !default;
// The modern `flex-direction` property corresponds to two properties in the @box spec and the
// `legacy-flex-direction` mixin will emit both by default.
// This variable controls the emition of the `box-direction` property:
// true : always emit
// false : always suppress
// normal : only emit if the direction is `normal`
// reverse: only emit if the direction is `reverse`
$flex-legacy-direction: true !default;
// This variable controls the emition of the `box-orient` property:
// true : always emit
// false : always suppress
// horizontal: only emit if the orient is `horizontal`
// vertical : only emit if the orient is `vertical`
$flex-legacy-orient: true !default;
// @doc off
// Common Mixins
// =============
// @doc on
// function for converting a value from the standard specification to one that is comparable from
// an older specification
@function flex-translate-value($value, $version: box) {
$value: unquote($value);
@if $value == flex {
@return if($version == box, box, flexbox);
} @else if $value == inline-flex {
@return if($version == box, inline-box, inline-flexbox);
} @else if $value == flex-start {
@return start;
} @else if $value == flex-end {
@return end;
} @else if $value == space-between {
@return justify;
} @else if $value == space-around { // @box doesn't have a value equivalent to `space-around`
@return if($version == box, justify, distribute);
}
@return $value;
}
@function flex-support-common() {
$common: ();
@for $i from 1 through length($flex-support) {
$common: append($common, nth($flex-support, $i) or nth($flexbox-support, $i), comma);
}
@return $common;
}
// @doc off
// Display Property
// ================
// @doc on
// $type: flex | inline-flex
@mixin display-flex($type: flex, $wrap: $flex-wrap-required, $legacy: $flex-legacy-enabled) {
@if $legacy and not $wrap {
@include legacy-display-flex($type);
}
@include experimental-value(display, flex-translate-value($type, flexbox), $flexbox-support...);
// if `$wrap` is true, then we need to suppress official support as generated by the `experimental()`
// mixin so that we can insert it inside an `@supports` block
$flex-support-standard: true;
$flex-support-list: $flex-support;
@if length($flex-support) > 5 {
$flex-support-standard: nth($flex-support, 6);
// a `slice()` function would really be handy here...
$flex-support-list: nth($flex-support, 1), nth($flex-support, 2), nth($flex-support, 3), nth($flex-support, 4), nth($flex-support, 5);
}
$flex-support-list: append($flex-support-list, if($wrap, false, $flex-support-standard));
@include experimental-value(display, $type, $flex-support-list...);
@if $wrap and $flex-support-standard {
@supports (flex-wrap: wrap) {
display: $type;
}
}
}
@mixin legacy-display-flex($type: flex) {
@include experimental-value(display, flex-translate-value($type, box), $box-support...);
}
// @doc off
// Flex Container Properties
// =========================
// @doc on
// $value: <'flex-direction'> || <'flex-wrap'>
@mixin flex-flow($value: row nowrap, $wrap: $flex-wrap-required, $legacy: $flex-legacy-enabled, $orient: $flex-legacy-orient, $direction: $flex-legacy-direction) {
@if $legacy and not $wrap {
@include legacy-flex-flow($value, $orient, $direction);
}
@include experimental(flex-flow, $value, flex-support-common()...);
}
@mixin legacy-flex-flow($value: row nowrap, $orient: $flex-legacy-orient, $direction: $flex-legacy-direction) {
@if length($value) > 1 { // @box version doesn't have a shorthand
@include legacy-flex-direction(nth($value, 1), $orient, $direction);
@include legacy-flex-wrap(nth($value, 2));
} @else {
$value: unquote($value);
@if $value == row or $value == row-reverse or $value == column or $value == column-reverse {
@include legacy-flex-direction($value);
} @else {
@include legacy-flex-wrap($value);
}
}
}
// $value: row | row-reverse | column | column-reverse
@mixin flex-direction($value: row, $wrap: $flex-wrap-required, $legacy: $flex-legacy-enabled, $orient: $flex-legacy-orient, $direction: $flex-legacy-direction) {
@if $legacy and not $wrap {
@include legacy-flex-direction($value, $orient, $direction);
}
@include experimental(flex-direction, $value, flex-support-common()...);
}
@mixin legacy-flex-direction($value: row, $orient: $flex-legacy-orient, $direction: $flex-legacy-direction) {
$value: unquote($value);
$translated-orient: if($value == row or $value == row-reverse, horizontal, vertical);
$translated-direction: if($value == row or $value == column, normal, reverse);
@if $orient == true or $translated-orient == $orient {
@include experimental(box-orient, $translated-orient, $box-support...);
}
@if $direction == true or $translated-direction == $direction {
@include experimental(box-direction, $translated-direction, $box-support...);
}
}
// $value: nowrap | wrap | wrap-reverse
@mixin flex-wrap($value: nowrap, $wrap: $flex-wrap-required, $legacy: $flex-legacy-enabled) {
@if $legacy and not $wrap {
@include legacy-flex-wrap($value);
}
@include experimental(flex-wrap, $value, flex-support-common()...);
}
@mixin legacy-flex-wrap($value: nowrap) {
// NOTE: @box has no equivalent of wrap-reverse
@include experimental(box-lines, if($value == nowrap, single, multiple), $box-support...);
}
// Distributing extra space along the "main axis"
// $value: flex-start | flex-end | center | space-between | space-around
@mixin justify-content($value: flex-start, $wrap: $flex-wrap-required, $legacy: $flex-legacy-enabled) {
@if $legacy and not $wrap {
@include legacy-justify-content($value);
}
@include experimental(flex-pack, flex-translate-value($value, flexbox), $flexbox-support...);
@include experimental(justify-content, $value, $flex-support...);
}
@mixin legacy-justify-content($value: flex-start) {
@include experimental(box-pack, flex-translate-value($value, box), $box-support...);
}
// Distributing extra space along the "cross axis"
// $value: flex-start | flex-end | center | space-between | space-around | stretch
@mixin align-content($value: flex-start) {
// There is no @box version of this property
@include experimental(flex-line-pack, flex-translate-value($value, flexbox), $flexbox-support...);
@include experimental(align-content, $value, $flex-support...);
}
// Align items along the "cross axis"
// $value: flex-start | flex-end | center | baseline | stretch
@mixin align-items($value: stretch, $wrap: $flex-wrap-required, $legacy: $flex-legacy-enabled) { // the flex container
@if $legacy and not $wrap {
@include legacy-align-items($value);
}
@include experimental(flex-align, flex-translate-value($value, flexbox), $flexbox-support...);
@include experimental(align-items, $value, $flex-support...);
}
@mixin legacy-align-items($value: flex-start) {
@include experimental(box-align, flex-translate-value($value, box), $box-support...);
}
// @doc off
// Flex Item Properties
// ====================
// @doc on
// $value: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
@mixin flex($value: 0 1 auto, $wrap: $flex-wrap-required, $legacy: $flex-legacy-enabled) {
$value: unquote($value);
@if $legacy and unitless(nth($value, 1)) {
@include legacy-flex($value);
}
@include experimental(flex, $value, flex-support-common()...);
}
@mixin legacy-flex($value: 0) {
$value: nth($value, 1);
@if not unitless($value) {
@warn 'The legacy flex property `box-flex` requires an Integer (eg. 1)';
}
@include experimental(box-flex, $value, $box-support...);
}
// $value: Integer
@mixin flex-grow($value: 0, $wrap: $flex-wrap-required, $legacy: $flex-legacy-enabled) {
// There is no @box version of this property
// There is no @flexbox version of this property
@include experimental(flex-grow, $value, $flex-support...);
}
// $value: Integer
@mixin flex-shrink($value: 1) {
// There is no @box version of this property
// There is no @flexbox version of this property
@include experimental(flex-shrink, $value, $flex-support...);
}
// $value: united number (eg: 100px)
@mixin flex-basis($value: auto) {
// There is no @box version of this property
// There is no @flexbox version of this property
@include experimental(flex-basis, $value, $flex-support...);
}
// Align items along the "cross axis" -- overrides `align-items` value on individual items
// $value: auto | flex-start | flex-end | center | baseline | stretch
@mixin align-self($value: auto) { // children of flex containers
// There is no @box version of this property
@include experimental(flex-item-align, flex-translate-value($value, flexbox), $flexbox-support...);
@include experimental(align-self, $value, $flex-support...);
}
// $value: Integer
@mixin order($value: 0, $wrap: $flex-wrap-required, $legacy: $flex-legacy-enabled) {
@if $legacy and not $wrap {
@include legacy-order($value);
}
@include experimental(flex-order, $value, $flexbox-support...);
@include experimental(order, $value, $flex-support...);
}
@mixin legacy-order($value: 0) {
// the @box spec starts the ordering at 1 instead of 0 like the modern specs
@include experimental(box-ordinal-group, $value + 1, $box-support...);
}
@import "flexbox_support";
/*
* Mixin to do inline list with flexbox, use the media query variables from Foundation5
*
* TODO: Use 33.3333 but use floor() to make have class name "xx-33" and not "xx-33.3333"
*/
$flex-inline-list-sizes: 18 20 23 25 31 33 48 50 73 75 98 100 !default;
@mixin flex-inline-list-classes($sizes, $viewport: small) {
@each $size in $sizes{
$width: $size / 100;
// Will name it like "&.small-50"
&>.#{$viewport}-#{$size} {
@include flex(1 0 percentage($width));
max-width: percentage($width);
}
}
}
/*
* Inline list with flexbox, can wrap to multiple lines if needed
*
* TODO: Should have a fallback for non flex browsers using modernizr classes
* to detect "no-flex"
*/
.flex-inline-list{
@include display-flex;
@include flex-wrap(wrap);
&>.cell{
// Default is to have the same width and height for all items using
// the largest value from all items
@include flex(1 0 auto);
max-width: auto;
margin: 0;
list-style-type: none;
}
@media #{$small-up} {
@include flex-inline-list-classes($flex-inline-list-sizes, $viewport: small);
}
@media #{$medium-up} {
@include flex-inline-list-classes($flex-inline-list-sizes, $viewport: medium);
}
@media #{$large-up} {
@include flex-inline-list-classes($flex-inline-list-sizes, $viewport: large);
}
@media #{$xlarge-up} {
@include flex-inline-list-classes($flex-inline-list-sizes, $viewport: xlarge);
}
@media #{$xxlarge-up} {
@include flex-inline-list-classes($flex-inline-list-sizes, $viewport: xxlarge);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment