lib/mixins.scss (93 lines of code) (raw):
// NOTE: This file is a separate export from the core library CSS
// It specifically enables the 'bp' and 'bpc' mixins
// (It's separate so that it must be imported into a project's SCSS,
// wherein the mixins become available to the other project SCSS files)
// ==========================================================================
// VARIABLES
// ==========================================================================
// NOTE: If you're going to change any of these, you'll also need
// to change the corresponding variables in the core library JS
$CORE_CLASS: 'bpc';
$BP_PREFIX: '-';
$BP_CONTENT: '#{$CORE_CLASS}__content';
$BP_BROWSER: '#{$CORE_CLASS}__browser';
$DEBUG_MODIFIER: '-debug';
$DEBUG_INDICATOR: '#{$CORE_CLASS}__debugIndicator';
$DEBUG_IDENTIFIER: '#{$CORE_CLASS}__debugIdentifier';
// ==========================================================================
// BREAKPOINTS
// ==========================================================================
// NOTE: If you're going to add or change bps, follow this checklist:
// - (Below) Add to $bps map
// - (Below) Add matching entry to $bps-max map (if adding a new bp)
// - (Below) Add matching debug output in bp-indicator() mixin
// - (React) Add to BREAKPOINTS const obj in BreakpointContainer.js component
$bps: (
none: 0,
xxxs: 320,
xxs: 359,
xs: 480,
s: 640,
m: 768,
l: 1024,
xl: 1244,
xxl: 1410,
xxxl: 1690,
);
// A breakpoint's 'max' is its upper-limit, which we can set by pointing to the 'next' breakpoint up
$bps-max: (
none: xxxs,
xxxs: xxs,
xxs: xs,
xs: s,
s: m,
m: l,
l: xl,
xl: xxl,
xxl: xxxl,
// This last value has itself as its max, because there is no upper limit
xxxl: xxxl,
);
// ==========================================================================
// SHORTHAND MIXINS
// ==========================================================================
// DDBreakpoints behaviour backward-compatibility; usage of 'bp()' mixin will behave
// as per the original library, provided the browser/app is wrapped with the BrowserContainer
// component as per the docs' recommended usage (requires app to stretch to the viewport's full width)
@mixin bp($min, $max: 0) {
@include bp-base($min, $max) {
@content;
}
}
// Container-based
@mixin bpc($min, $max: 0) {
@include bp-base($min, $max, true) {
@content;
}
}
// ==========================================================================
// CORE MIXIN
// ==========================================================================
// Shared breakpoint logic between browser/container mixins below
@mixin bp-base($min, $max, $container: false, $property: width) {
@if ($max == 0) {
// @include bp(l); if the second variable is blank or 0, we want min (e.g. large and above)
@include browserOrContainer($min, 0, $container) {
@content;
}
} @else if ($min == 0) {
// @include bp(0, l); if the first variable is 0, we want max (e.g. large and below)
@include browserOrContainer(0, $max, $container) {
@content;
}
} @else {
// @include bp(s, l); if both variables are different, we want between (e.g. small to large)
// @include bp(l, l); if both are the same, we want just that breakpoint (e.g. large)
@include browserOrContainer($min, $max, $container) {
@content;
}
}
}
// ==========================================================================
// LOCAL MIXINS
// ==========================================================================
// Routes to one of the two mixins below as appropriate
@mixin browserOrContainer($bp-min, $bp-max: 0, $container: false) {
@if $container == false {
@include bp-browser($bp-min, $bp-max) {
@content;
}
} @else {
@include bp-container($bp-min, $bp-max) {
@content;
}
}
}
@mixin bp-browser($bp-min, $bp-max: 0) {
@if $bp-max == 0 {
.#{$BP_PREFIX}#{$bp-min} > .#{$BP_BROWSER} & {
@content;
}
} @else {
@if ($bp-min == '0' or $bp-min == 0) {
$bp-min: 'none';
}
.#{$BP_PREFIX}#{$bp-min}:not(.#{$BP_PREFIX}#{map-get($bps-max, $bp-max)}) > .#{$BP_BROWSER} & {
@content;
}
}
}
@mixin bp-container($bp-min, $bp-max: 0) {
@if $bp-max == 0 {
.#{$BP_PREFIX}#{$bp-min} > & { @content; }
} @else {
@if ($bp-min == '0' or $bp-min == 0) {
$bp-min: 'none';
}
.#{$BP_PREFIX}#{$bp-min}:not(.#{$BP_PREFIX}#{map-get($bps-max, $bp-max)}) > & {
@content;
}
}
}