When the progressive introduction of SASS into the code base starts this month, I want to start converting common code into atoms, mixins, and functions. To reduce boilerplate, etc for viewport management.
Definition API
Ideally we should have a simple declarative API for defining the viewports which the Framework will dump into the theming output CSS else where. While we could use SASS Variables for this, I think an API based on SASS Mixins would be better due to being able to perform magic behind the scenes:
Arguments are named, each viewport's breakpoint width is defined, and it's all easily readable. Ideally we would've used a SASS Function, but those cannot be used outside of rule declarations.
As far as the implementation goes, the requirements are:
Place each new width value into a local SASS Map, viewports.
Store new width values into local maximum / minimum SASS Variables whenever the previously cached values are lower / higher than, respectively.
Accept arguments as a SASS List of Viewport names.
Pass through each Viewport name into query-viewport to wrap the inner declarations in media queries.
@mixin query-viewports($viewports...) {
@each $viewport, $index in $viewports {
@include query-viewport($viewport) using ($viewport) {
@content ($viewport);
}
}
}
CSS Variables
We need to dump all Viewport values as CSS Custom Properties. Ideally we would use these properties for media queries, but CSS doesn't support that. However they are still useful so the Javascript codebase doesn't have to hardcode the values.
Description
When the progressive introduction of SASS into the code base starts this month, I want to start converting common code into atoms, mixins, and functions. To reduce boilerplate, etc for viewport management.
Definition API
Ideally we should have a simple declarative API for defining the viewports which the Framework will dump into the theming output CSS else where. While we could use SASS Variables for this, I think an API based on SASS Mixins would be better due to being able to perform magic behind the scenes:
Arguments are named, each viewport's breakpoint width is defined, and it's all easily readable. Ideally we would've used a SASS Function, but those cannot be used outside of rule declarations.
As far as the implementation goes, the requirements are:
width
value into a local SASS Map,viewports
.width
values into localmaximum
/minimum
SASS Variables whenever the previously cached values are lower / higher than, respectively.Media Query
Using the above cached viewport data, we should have an API surface for simplifying
@media
access to promote non-repeating code.For this implementation we'll need a helper function
get-viewport-range($viewport: str)
first, to simplify Viewport calculations:Takes an input Viewport and looks up the cached width value.
Returns in a
($maximum-width: number, $minimum-width: number)
SASS Map.If the width matches the cached minimum width, just return
($maximum-width: $selected-width, $minimum-width: 0px)
.Or, if the width matches the cached maximum width, just return
($maximum-width: 999999px, $minimum-width: $target-width + 1px)
.Otherwise, loop through all Viewports that isn't the one from the input, and cache the Viewport that is numerically closest to the input.
Once the loop is finished, return
($maximum-width: $selected-width, $minimum-width: $target-width + 1px)
.Using that helper function, we can start with the
query-viewport($viewport: string)
mixin:get-viewport-range
.@media (min-width: $minimum-width)
query.@media (max-width: $maximum-width)
query.@media (min-width: #{$minimum-width}) and (max-width: #{$maximum-width})
query.Next we'll need a higher level multi-input mixin for accessing multiple Viewports at once, e.g.
So we need the following requirements:
query-viewport
to wrap the inner declarations in media queries.CSS Variables
We need to dump all Viewport values as CSS Custom Properties. Ideally we would use these properties for media queries, but CSS doesn't support that. However they are still useful so the Javascript codebase doesn't have to hardcode the values.
Which would have output similar to:
To accomplish this, we need the following implementation for the
each-viewport($viewports...: str[])
mixin: