Extending in a media query in Sass and Bootstrap 4 - css

I am updating to the new Bootstrap version 4 which now uses Sass over Less, and my application that uses Bootstrap used the Less files directly rather than the fully compiled css distribution.
But now I've hit a snag - I understand that Sass doesn't allow you to use an #extend within a #media query, but what I don't understand is how I get around the simple problem of overloading a style on a larger screen.
For example, a stripped down version of my Sass looks like:
.box {
//mobile styles
background: green;
.logout-button {
//mobile styles for logout button
background: red;
}
}
//everything over 767px
#media (min-width: 768px) {
.box {
.logout-button {
#extend .btn-link; //bring in the Bootstrap button link style here
}
}
}
In this example, I want the .logout-button to use the .btn-link style from Bootstrap. But because you can't #extend like this, I'm totally confused as to how to achieve this.
Is there a completely different approach required in Sass compared to Less? Less allows you to do this so I'd be surprised if this was a limitation considering Bootstrap's recent switch.
Thanks in advance!

You are right, you can not #extend like this.
But you can #include some #mixin.
There is unfortunately no #mixin to create .btn-link variant by default in Bootstrap 4.
If you wanted some other variant, you could use these #mixins which are part of Bootstrap 4:
#include button-variant($background, $border, $active-background: darken($background, 7.5%), $active-border: darken($border, 10%))
or this
#include button-outline-variant($color, $color-hover: #fff)
(Useful list of Boostrap 4 mixins)
But if you need .btn-link you have to make your own #mixin. Something like this (it's copy/paste style of .btn-link in to new mixin):
//
// Link buttons
//
// Make a button look and behave like a link
#mixin btn-link() {
font-weight: $font-weight-normal;
color: $link-color;
background-color: transparent;
#include hover {
color: $link-hover-color;
text-decoration: $link-hover-decoration;
background-color: transparent;
border-color: transparent;
}
&:focus,
&.focus {
text-decoration: $link-hover-decoration;
border-color: transparent;
box-shadow: none;
}
&:disabled,
&.disabled {
color: $btn-link-disabled-color;
pointer-events: none;
}
// No need for an active state here
}
And then you can use it as you wish:
//everything over 767px
#media (min-width: 768px) {
.box {
.logout-button {
#include btn-link;
}
}
}
Nice article about this: SCSS - Extending Classes Within Media Queries

Related

How to call variables for dark mode

Hello i want to make dark mode for my Ionic 3 Angular 5 project. I made the functions that change themes as i wanted.
My problem is that scss variables in my ionic.theme.dark scss file inside the theme folder don't apply e.g. $background-color simple css rules apply just ok. e.g. p{font-size:40px}.
I think there is a workaround because when i just call the ionic.theme.dark in the variables.scss file without putting it in a class it works fine but when i need to call the dark mode inside the class e.g. .dark-theme{#import "./ionic.theme.dark";} it calls only the css rules not the variables
For example
.dark-theme{
p{
font-size:76px
}
$text-color: #fff !default;
$link-color: color($colors, primary) !default;
$background-color: rgba(0,0,0,0.6) !important;
$subdued-text-color: #666 !default;
}
p font-size works but $background-color doesnt
smae thing happens when i loose the !default in all variables
Any idea why?
You can use media query to achieve
#media (prefers-color-scheme: dark) {
.day.dark-scheme { background: #333; color: white; }
.night.dark-scheme { background: black; color: #ddd; }
}
#media (prefers-color-scheme: light) {
.day.light-scheme { background: white; color: #555; }
.night.light-scheme { background: #eee; color: black; }
}
Reference : https://developer.mozilla.org/en-US/docs/Web/CSS/#media/prefers-color-scheme

Sass apply css to media query and class in same time

I use Sass and I want to apply some style with two conditions
first if media query < desktop
second if the container have class "affiliations"
How can I wrote it without duplicate the style
I try the following but its not work
#include media ('<desktop'),.affiliations {
.search
{
color:red;
.icon{
color: blue;
}.........etc
}
}
What you are trying to do can't be done with only sass, usually you would structure your code like this
.someclass {
color: deepskyblue;
#media (max-width: 1023) {
.affiliations & {
color: deeppink;
}
}
}

Swap color and background-color with sass/css

For a responsive layout I am trying to switch the color with the background-color and vice versa on defined occasions.
What's the cleanest way to swap the values of the color and background-color when using sass? Pure CSS doesn't work in this case, does it?
Something like
p {
#media … {
[swap currentTextColor and currentBgColor]
}
}
You could create a mixin:
#mixin swapColors($textColor, $bgColor) {
background-color: $bgColor;
color: $textColor;
#media ... {
background-color: $textColor;
color: $bgColor;
}
}
.tree {
#include swapMobile(red, black);
}
Besides from that i'm not aware of anything built in that could do such a thing.

Using Susy, is there a way to include a piece of CSS inside breakpoint?

Succinctly, By using Susy's at-breakpoint responsive mixin, is there a way or function to include an external CSS file in the body of the breakpoint call?
Something like this:
.page {
border: 1px dashed #000;
height: 650px;
#include container;
.content {
color: red;
text-align: center;
border: 1px dashed red;
height: 400px;
#include span-columns(4 omega, 6);
.main {
color: green;
border: 1px dashed green;
text-align: center;
#include span-columns(1, 2);
}
.secondary {
color: blue;
border: 1px dashed blue;
#include span-columns(2, 3);
}
}
#include at-breakpoint(800px 8 250px) {
#include container;
.content {
#include span-columns(1, 1);
}
//IMPORT or INCLUDE CSS FILE HERE somehow...
} //end of breakpoint
}
I was hoping it was possible, because that'd be a whole lot cleaner than writing all the CSS rules I wish to be applied right there inline. Let me know if it's possible or what's the best practice in this case.
Thank you!
Sure. This isn't really a question about Susy, so much as a question about Sass. The same answers are true for working in the context of any wrapping mixin.
You can only import files at the root level (for now, at least) — but that's not your only option. I've seen people write all their site styles inside mixins, and then simply include those mixins as needed:
#mixin medium-layout {
// your medium css
}
.page {
#include at-breakpoint($medium) {
#include medium-layout;
}
}
You can use as many mixins as you like, call them whatever you want, and put them in other files (as long as you #include those files before calling the mixins).
I use a different approach. Rather than nesting everything under a .page selector, with big groups for each breakpoint, I break things up into modules, and keep the breakpoint styles attached to each module as needed.
// _main.scss
.main {
color: green;
#include at-breakpoint($medium) { /* changes to main */ }
}
// _secondary.scss
.secondary {
color: blue;
#include at-breakpoint($medium) { /* changes to secondary */ }
}
From a mobile-first perspective, where breakpoint styles may need to override or build on existing styles, this keeps all the related code in one place.

Sass variables in print stylsheet override variables in "all" stylesheet

I use the latest SASS/Compass versions for developing CSS. I've declared some SASS variables at the beginning of the "media=all" stylesheet like this:
$var1: red;
$var2: blue;
$var3: black;
$var4: green;
Later in this SCSS file i import a print stylesheet (#import 'print.scss';) which looks like this:
#media print {
$var1: black;
$var2: black;
$var4:black;
}
I thought, that the variables in the print stylesheet overrides the "normal" vars only if the Browser is in "print mode". But the variables do override always the "normal" vars declared before.
I'm a little confused and appreciate any help.
Thanks!
As per this questions, it's basically not possible in your current form. If you want to achieve this, you'll have to import each style that makes use of your $varX, like:
$blue: blue;
.test{
color: $blue;
}
#media print {
$blue: pink;
.test{
color: $blue;
}
}
output:
.test{color:blue}#media print{.test{color:pink}}
It's not the ideal solution (you'll get lots of repeated code), but unfortunately it's all you can do due to the way CSS works.
This may be a slightly better solution:
$blue: blue;
$print_blue: pink;
.test{
color: $blue;
text-align: right;
#media print {
color: $print_blue;
}
}
output:
.test{color:blue;text-align:right}#media print{.test{color:pink}}

Resources