Using variables in an #include block in SASS - css

I have this mixin:
#mixin mobile {
#media (max-width: 576px) {
#content;
}
}
And I'm trying to do the following:
height: calc($image_height - $spacing_between_items);
But the variables don't get evaluated. I think it might be because of how #content works, but I'm not a SASS expert.
Why is this happening and how can I fix it?

It's not the way #content works but the way calc() works. You have to interpolate the variables within the calc() function:
$image_height: 100%;
$spacing_between_items: 10px;
#include mobile {
.class {
height: calc(#{$image_height} - #{$spacing_between_items}});
}
}
Outputs:
#media (max-width: 576px) {
.class {
height: calc(100% - 10px});
}
}

Related

Make a dynamic SCSS method to change variable values

I have done a project with a lot of code duplicity, so the problem occurs because I have to write the class in each query.
I'm trying to improve performance here. In order to do that, I want to use dynamic values for styling.
For example, the way CSS is being used here, but in ten different places using the same animation.
$center : 590px;
.container {
width: $center;
}
#media only screen and (max-width: 1660px){
//here I want to change $center to 490px;
// =================================================
// but the way that I found is to duplicate it
$center: 490px;
.container {
width: $center;
}
/*note : if I don't call the '.container' everytime that I'm changing the $center variable it does not work,
I have some animations that must use the variables .
*/
}
You can make use of #mixin and #include to avoid duplication.
#mixin media-container($center) {
#media only screen and (max-width: 1660px) {
.container {
width: $center;
}
}
}
In order to use the #mixin in any classes you want, you can add the following to the class you want to use this in:
.container-class {
#include media-container(540px);
}
Note that the 540px above can be replaced with any configuration you want for $center variable, which would change the width for your container.
Documentation: https://sass-lang.com/documentation/at-rules/mixin
SCSS variables are static (compile time) to do what you want you need to use CSSVariables that are dynamic (run time) - something like this
.container {
width: var(--width, 590px); /* default */
}
#media only screen and (max-width: 1660px){
.container {
--width: 490px;
}
}
If you need to set multiple values - you can use Sass nesting
to make it a little easier to type
.container {
width: var(--width, 50px);
#media (min-width: 100px) { --width: 100px; }
#media (min-width: 200px) { --width: 200px; }
#media (min-width: 300px) { --width: 300px; }
...
}
// output
.container {
width: var(--width, 50px);
}
#media (min-width: 100px) {
.container { --width: 100px; }
}
#media (min-width: 200px) {
.container { --width: 200px; }
}
#media (min-width: 300px) {
.container { --width: 300px; }
}

How to apply styles to both a class and a media query in SASS?

On mobile devices, my header must be always sticky. On other devices, it must be sticky only when it has the class sticky:
.header {
&.sticky {
position: fixed;
// other styles
}
}
#media only screen and (max-width: 600px) {
.header {
position: fixed;
// other styles
}
}
I want to write my styles once only (DRY principle), is there a way to achieve that with SASS?
It might look like:
.header {
#include media_600,
&.sticky {
position: fixed;
}
}
.. or something similar, but I don't know what.
I think you are on the right track. Creating a mixin with a content block (https://sass-lang.com/documentation/at-rules/mixin#content-blocks) will allow you to add styles without having to specify the selector again and also will enable you to reuse it throughout your code.
#mixin mobile {
#media only screen and (max-width: 600px) {
#content;
}
}
.header {
&.sticky {
position: fixed;
}
#include mobile {
position: fixed;
}
}
If you only want to write the CSS property once then you can do this.
#mixin sticky-header {
position: fixed;
}
.header {
&.sticky {
#include sticky-header;
}
#media only screen and (max-width: 600px) {
#include sticky-header;
}
}

Use container width in Bootstrap 4

We have recently changed to Bootstrap 4, and I'm looking into all the new ways to set widths, breakpoints etc.
I want to make a div have a max-width of the current breakpoint's container width, but I can't find the standard SASS variable name for that specific width.
Note that I can't use classes (e.g. .col-xl-) for this, since I don't have access to this specific part of the HTML.
Have a look at this built-in mixin:
// For each breakpoint, define the maximum width of the container in a media query
#mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {
#each $breakpoint, $container-max-width in $max-widths {
#include media-breakpoint-up($breakpoint, $breakpoints) {
width: $container-max-width;
max-width: 100%;
}
}
}
You can create a similar one to your needs like:
#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;
}
}
}
and use it:
.my-custom-class{
#include make-max-widths-container-width();
}
"Compiled" CSS produced (with default values on breakpoints and container widths):
#media (min-width: 576px) {
.my-custom-class {
max-width: 540px;
}
}
#media (min-width: 768px) {
.my-custom-class {
max-width: 720px;
}
}
#media (min-width: 992px) {
.my-custom-class {
max-width: 960px;
}
}
#media (min-width: 1200px) {
.my-custom-class {
max-width: 1140px;
}
}

the media condition repeat in each column

hi I"m working in one project, and i have create media condition for my column in Sass.
this the code
// for Mobile media - 320px width
#mixin mobile{
#media only screen and (max-width:767px){
width: 300px;
}
}
and this my loop for my column
#for $col from 1 through $grid-cols{
.col-#{$col}{
#include mobile;
}
}
and my $grid-cols = 12
so this my css output
#media only screen and (max-width: 767px) {
.col-1 {
width: 300px; } }
#media only screen and (max-width: 767px) {
.col-2 {
width: 300px; } }
etc... till .co-12
i need my output like this
#media only screen and (max-width: 767px) {
.col-1, .col-2 {width:300px;}
please, any hint
I think you will need to use a SASS placeholder in order to achieve that output. Replace your mixin:
#mixin mobile{
#media only screen and (max-width:767px){
width: 300px;
}
}
with a placeholder:
%mobile {
#media only screen and (max-width:767px){
width: 300px;
}
}
and call it with the #extend %mobile; instead of #include mobile; in your loop.
See this article for a very nice explanation on differences between mixins and placeholders.

Avoiding multiple "#media" when using Bootstrap 3 less mixins

When using less mixins to build a Website with Bootstrap I do something like this:
#logo {
.make-sm-column(3);
.make-md-column(3);
.make-lg-column(3);
}
#menu {
.make-sm-column(5);
.make-md-column(5);
.make-lg-column(5);
}
This looks very neat in the .less file but it does bloat up the compiled css a lot, isn't it?
Every class and id with such a mixin gets it's own set of media-queries:
#media (min-width: 768px) {
#logo {
float: left;
width: 25%;
}
}
#media (min-width: 992px) {
#logo {
float: left;
width: 25%;
}
}
#media (min-width: 1200px) {
#logo {
float: left;
width: 25%;
}
}
#media (min-width: 768px) {
#menu {
float: left;
width: 41.66666666666667%;
}
}
#media (min-width: 992px) {
#menu {
float: left;
width: 41.66666666666667%;
}
}
#media (min-width: 1200px) {
#menu {
float: left;
width: 41.66666666666667%;
}
}
This gets repeated for every class/id with the column-mixin. I think it would be more elegant and more effective to combine these definitions in 3 media-query blocks.
Is there a way I can do this (semi-)automatically.
I am using Windows and compiling with WinLess at the moment, but havent found such an option.
There's .make-xs-column mixin in current Bootstrap version, it generates the same CSS without any media queries.
Little late, but if you note the min-width in those media queries, you don't need to make the medium and large columns if they're the same as the small. You only need to specify the medium and large columns if they're different than your small columns. This is all you need to do:
#logo {
.make-sm-column(3);
}
#menu {
.make-sm-column(5);
}
That will output the minimal amount of code to get your desired layout.

Resources