How to refer to $container-max-widths in Bootstrap - sass

I am currently working with Bootstrap 4 and I've made some changes to breakpoints - it looks like that:
$container-max-widths: (
xs: 540px,
sm: 700px,
md: 960px,
lg: 1140px,
xl: 1300px,
g: 1560px,
xg: 1920px
) !default;
Here's my question: how can I refer to $container-max-widths -> g to get 1560px out of it?
I'd like to do something like this, but it's not working:
max-width: $grid-breakpoints('g');
Any ideas if that's possible?

You can create a function to retrieve the breakpoint values like so:
#function get-breakpoints($key: "md") {
#return map-get($container-max-widths, $key);
}
.test-class {
max-width: get-breakpoints("g");
}

It's possible.
max-width: map-get($container-max-widths, "g");

Import the following into your bootstrap files css/scss folder
scss/_functions.scss
scss/_variables.scss
scss/mixins/_breakpoints.scss
Then add the new breakpoints and container widths into your scss file
$grid-breakpoints: (
xs: 0,
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px
);
$container-max-widths: (
sm: 540px,
md: 720px,
lg: 940px,
xl: 1000px
);
#mixin make-max-widths-container-width($max-widths: $container-max-
widths, $breakpoints: $grid-breakpoints) {
#each $breakpoint, $container-max-width in $max-widths {
#include media-breakpoint-up($breakpoint, $breakpoints) {
max-width: $container-max-width;
}
}
}
.container{
#include make-max-widths-container-width();
}
So it creates a new set of widths which overrides the bootstrap width.

Another option that seemed to work, Bootstrap v.5, might not be the optimal way since using #extend
.your-container {
#include make-container();
#extend .container;
}

Related

Import multiple files at once (with namespaces) by importing a single file with #use

I have a folder where I store all the variables and functions of the project. Separated by functionality in its own file, with a strong use of namespacing.
Right now, maybe because of lack of knowledge about dart-sass, I am forced to import all these files with #use every time they are needed.
index.scss
#use "core/color";
#use "core/font";
#use "core/spacing";
#use "core/breakpoint" as bp;
#use "core/mixins/normalize";
#use "core/functions" as *;
body {
background-color: color.$background;
font-family: font.$family;
font-size: rem(16px); // rem is a function inside _functions.scss
}
.row {
max-width: spacing.$content-max-width;
padding: 0 spacing.$content-padding;
#media (max-width: bp.$sm) {
padding: 0 spacing.$content-padding-sm;
}
}
.btn {
#include normalize.button;
}
So my question is: is there any way to get that same functionality with a single #use?
I thought something like that would work, but it seems that #forward don't accept namespaces, only prefixes.
// What follows won't work, don't try it. I just want to show what I'm trying to achieve
core/_index.scss
#forward "color" as color;
#forward "font" as font;
#forward "spacing" as spacing;
#forward "breakpoint" as bp;
#forward "mixins/normalize" as normalize;
#forward "functions";
index.scss
#use "core" as *;
body {
background-color: color.$background;
font-family: font.$family;
font-size: rem(16px); // rem is a function inside _functions.scss
}
.row {
max-width: spacing.$content-max-width;
padding: 0 spacing.$content-padding;
#media (max-width: bp.$sm) {
padding: 0 spacing.$content-padding-sm;
}
}
.btn {
#include normalize.button;
}

SCSS: Calculating with a value with unit from function

I am defining values for a theme via a map, like this:
$sizes: (
small: 768,
medium: 1024,
large: 1200,
xlarge: 1600,
gutter: 48
);
and afterwards give them a unit with the following function:
#function sz($size) {
#return map-get($sizes, $size) + px;
}
How can I define a variable by calculating with one of the values out of the function, e.g.
$gutterhalf: (sz(gutter) / 2);
So the variable would return 48px / 2 = 24px? I know I could just go with the unitless value and add the unit afterwards, like so:
$gutterhalf: (map-get($sizes, gutter) / 2) + px;
Would there be a way to handle it differently with the value from the function?
Normally I would use sassmeister to do live sass demos but I can't seem to share my sass demo without it automatically switching to dart-sass. Very weird.
But I've made a fiddle outputting results to a before pseudo content style on divs by id.
See experimental ideas in fiddle... https://jsfiddle.net/joshmoto/0mbsc2g3/
And here is scss code below...
// array with no pixel unit, just integers
$sizes_0: (
sm: 768,
md: 1024,
lg: 1200,
xl: 1600,
gutter: 48
);
// both functions below use array above
// this function allows you pass diving data through
#function sz_0($size, $divide: 1) {
#return map-get($sizes_0, $size) / $divide + px;
}
// this outputs 24px
$gutterhalf_0: sz_0(gutter, 2);
// this function simply returns the array value
#function sz_2($size) {
#return map-get($sizes_0, $size);
}
// this outputs 24px
$gutterhalf_2: ( sz_2(gutter) / 2 ) + px;
// array with pixel unit
$sizes_1: (
sm: 768px,
md: 1024px,
lg: 1200px,
xl: 1600px,
gutter: 48px
);
// this function simply returns the array value with unit
#function sz_1($size) {
#return map-get($sizes_1, $size);
}
// this outputs 24px
$gutterhalf_1: sz_1(gutter) / 2;
// sass results in content
#sz_0::before {
content: '#{$gutterhalf_0}';
}
#sz_1::before {
content: '#{$gutterhalf_1}';
}
#sz_2::before {
content: '#{$gutterhalf_2}';
}

SASS function darken & lighten not working when using object of colors

I am trying to use the darken sass function but when I read from the sass object in my scss module, it thinks the color is actually a string and thus the function fails to parse the variable passed in.
variables.scss
$primary: #ae9fec;
$secondary: #d19ac1;
$theme: (
"primary": ($primary, white),
"secondary": ($secondary, white)
);
Button.module.scss
#each $colorGroup in $theme {
&[data-variant="#{nth($colorGroup, 1)}"] {
background-color: #{nth(nth($colorGroup, 2), 1)}); // this works
&:hover {
background-color: darken(#{nth(nth($colorGroup, 2), 1)}), 10%); // this does not because it thinks its a string. I tried unquote() but that didn't work, still thinks it's a string.
}
}
}
If you remove the interpolation in your selector rules (not the selector itself), it should compile as intended.
Here's a test - and I'm assuming you are nesting the #each loop inside a selector or using #at-root, since base-level rules cannot contain the & character like this - with a .button selector for your ruleset:
/* variables.scss */
$primary: #ae9fec;
$secondary: #d19ac1;
$theme: (
"primary": ($primary, white),
"secondary": ($secondary, white)
);
/* Button.module.scss */
.button {
#each $colorGroup in $theme {
&[data-variant="#{nth($colorGroup, 1)}"] {
background-color: nth(nth($colorGroup, 2), 1);
&:hover {
background-color: darken(nth(nth($colorGroup, 2), 1), 10%);
}
}
}
}
The compiled code looks like this:
.button[data-variant="primary"] {
background-color: #ae9fec;
}
.button[data-variant="primary"]:hover {
background-color: #8a74e4; /* Darkened $primary */
}
.button[data-variant="secondary"] {
background-color: #d19ac1;
}
.button[data-variant="secondary"]:hover {
background-color: #c177ab; /* Darkened $secondary */
}
I also removed the extra parenthesis in the example.

the index() function returns null even if the value is present

I try to get the index of a value in a map, but it returns null. which is strange since I know the key/value is in the map.
And whats even stranger is that it works fine when using other values than the last one.
Code:
index(($mediaSizesMap), ($size $s))
$size = xl, $s = 1200px
Map:
$mediaSizesMap: (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px);
$mediaSizesMap: (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px);
$size: xl;
$s: 1200px;
div {
content: index($mediaSizesMap, ($size $s));
}
Output:
div {
content: 5;
}

Passing a list to a mixin in SASS as parameters?

I'm trying to make a SCSS stylesheet easily configurable by defining a set of constants that will be used in a number of mixins and with the Compass library. Ideally, I'd like to be able to do the following:
$item-bgs: linear-gradient(white, black), #ccc;
#mixin some-mixin() {
#include background-with-css2-fallback($item-bgs*);
}
The background-with-css2-fallback is a Compass mixin that accepts up to 10 params. I'm assuming that SASS does not currently support passing a list parameter as the argument list, otherwise Compass would probably use it, but I'm wondering if I can get the $item-bgs list to be the first 2 arguments to the background-with-css2-fallback mixin. Is there a way to do this currently, or is it even planned for SASS in the future?
It may not be supported by SASS natively, but Compass does support passing a list as the first argument to the background-with-css2-fallback mixin. If you look at the source for the mixin, you'll see that it uses a compact function that handles the logic for collapsing the arguments into a single list, whether passed individually or in a single list parameter.
For example, this works fine for me:
#import "compass";
$item-bgs: (linear-gradient(white, black), #ccc);
.test {
#include background-with-css2-fallback($item-bgs);
}
Examples of useing maps as arguments:
Example 1 (list)
#mixin transition($property...){
#if $property {
transition-property: $property;
}
#else {
transition-property: all;
}
transition-timing-function: ease-in-out;
transition-duration: .3s;
transition-delay: 0;
}
.btn {
color: black;
border: 1px solid black;
#include transition(color, border-color);
&:hover {
color: red;
border-color: red;
}
}
Example 2 (Custom params)
#use 'sass:meta';
#mixin example2($args...) {
#each $key, $value in meta.keywords($args) {
#{$key}: #{$value};
}
}
.shape {
#include example2($width:200px, $height:100px);
}
Example 3 (map)
#mixin colors($args:()) {
#if length($colors) > 0 {
#each $key, $val in $args{
.txt-#{$key} {
color: #{$value};
}
.bg-#{$key} {
background-color: #{$value};
}
}
}
}
$colors_map: (
primary: blue,
secondary: green,
accent: red,
light: white,
dark: black
);
#include colors($colors_map);

Resources