Created
June 19, 2014 20:47
-
-
Save barneycarroll/34e60e18705688df1b0f to your computer and use it in GitHub Desktop.
SASS mixin for creating absolutely positioned, fractional width items. It fulfils the common flexbox use-cases but uses a simpler syntax.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// gridItems is a mixin for creating absolutely positioned, | |
// fractional width items. It fulfils the common flexbox use-cases | |
// but uses a simpler syntax. | |
// | |
// The only requirement is that the parent be relatively positioned. | |
// Multiple invocation methods are possible, all of which are | |
// exemplified at the bottom. | |
// Occupy full dimensions of parent container. | |
// The gridItems mixin adds each passed selector to this rule. | |
%grid-item { | |
position : absolute; | |
left : 0; | |
top : 0; | |
height : 100%; | |
width : 100%; | |
} | |
// $opts is heavily overloaded: see bottom for details or read on. | |
@mixin gridItems( $opts ){ | |
// For horizontal grids (the default), $opts should be a map of | |
// ( @selector, @fractionUnit ) pairs. | |
$items : $opts; | |
// Again, horizontal is the default. These properties will be used | |
// When applying fractional positioning. | |
$dimension : 'width'; | |
$offset : 'left'; | |
// If the grid is non-horizontal (ie vertical), pass a map where | |
// @items conforms to the format detailed above as follows: | |
// ( vertical : true, items : @items... ) | |
@if map-get( $opts, items ){ | |
$items : map-get( $opts, items ); | |
} | |
// Remap properties when vertical property is passed | |
@if map-get( $opts, vertical ){ | |
$dimension : 'height'; | |
$offset : 'top'; | |
} | |
// Default item enumeration is ( @selector, @fraction ), | |
// but you can also pass ( @fraction ), in which case @selector | |
// is assumed to be '> :nth-child( [indexInMap] )' | |
$no-selectors : false; | |
// We need to increment fractions. | |
// In future, may implement an overload method in which empty $items | |
// results in equal-sized fractions for any number of items. | |
$fractions : 0; | |
// For items of index n > 1, we need to apply the cumulative offset | |
// of previous items | |
$previous : 0; | |
// In cases where selectors aren't passed, we need to remap our internal | |
// variables. Takes several iterations because of hard limitations in SASS. | |
@each $selector, $fraction in $items { | |
// Set a flag. Note that we need either all selectors or no selectors at all. | |
@if $no-selectors = null { | |
$no-selectors : $fraction = null; | |
} | |
// Temporarily remap. A second iteration applies the necessary selector. | |
@if $no-selectors { | |
$fraction : $selector; | |
// Because we can't retrieve iteration index from @each on maps, | |
// Use a unique id to create an unambiguous key for each item. | |
// This is a temporary measure, as explained below. | |
$selector : unique_id(); | |
} | |
} | |
// Create a list of keys from the $map. Necessary (in this implementation) | |
// to retrieve an index from unique keys when iterating (we still need a map). | |
// | |
// Should really create a higher-level fork for the $no-selectors API | |
// rather than literring the code with expensive conditions. | |
@if $no-selectors { | |
$selectorList : map-keys( $items ); | |
} | |
@each $selector, $fraction in $items { | |
@if no-selectors { | |
$index : index( $selectorList, $selector ) + 1; | |
$selector : #{ '> nth-child( ' + $index + ' )'; | |
} | |
$fractions : $fractions + $fraction; | |
} | |
@each $selector, $fraction in $items { | |
$percentage : ( $fraction / $fractions ) * 100; | |
#{ $selector } { | |
@extend %grid-item; | |
#{ $dimension } : #{ $percentage + '%' }; | |
#{ $offset } : #{ $previous + '%' }; | |
} | |
$previous : $previous + $percentage; | |
} | |
} | |
// |------|----| | |
// |xxxxxx|xxxx| | |
// |xxxxxx|xxxx| | |
// |xxxxxx|xxxx| | |
// |xxxxxx|xxxx| | |
// |xxxxxx|xxxx| | |
// |------|----| | |
// .container { | |
// @include gridItems( ( | |
// ( '.chartEngineBox', 3 ), | |
// ( '.sidePanelBox', 2 ) | |
// ) ); | |
// } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment