How to declare two classes for element with scss - css

I have this scss code:
button.green{
background-color: $green;
.current {
color: $white;
}
}
I want to apply two classes to my button <button class="green current"></button> but my scss code just does not work. How would you fix that in a proper scss manner?
Also tried that with no luck:
button {
.green{
background-color: $green;
}
& .current {
color: $white;
}
}

Nearly correct, missing "&" in your nesting to connect button.green and .current.
The css output of your scss is:
button.green > .current
meaning, you style an element "current" within its parent "button.green".
Correct:
button.green{
background-color: $green;
&.current {
color: $white;
}
}
Which outputs:
button.green.current

.green.current {
background-color: $green;
color: $white;
}
This will apply both class!!

Related

style priority not working as expected in SASS

I have the following scss styles defined in a separate file
.radio-button-focused {
background-color: $PURPLE;
text-align: left;
opacity: 1;
width: px-to-rem(1248px);
margin-bottom: px-to-rem(15px);
#include truncate;
}
.radio-button {
background-color: $BLACK;
text-align: left;
opacity: 1;
width: px-to-rem(1248px);
margin-bottom: px-to-rem(15px);
#include truncate;
}
Both of them are being applied to a button
But the problem is that radio button is overwritting the color of radio-button-focused
I understand that I could use !important , or just use one of them instead of using them both at the same time. But if I was forced to use both, can something else be done to fix this?
The literal order in the CSS file matters. If two rules have the same specificity, the last one is applied. Move .radio-button before .radio-button-focused. You could also make your focused selector more specific. .radio-button.radio-button-focused for example.
Here's class B before A as an example.
.b
{
color: red;
}
.a
{
color: blue;
}
<div class="a b">Hi</div>
And here's A before B.
.a
{
color: blue;
}
.b
{
color: red;
}
<div class="a b">Hi</div>

Angular: SCSS / SASS compiler produces unwanted whitespaces [duplicate]

This question already has answers here:
Sass Nesting for :hover does not work [duplicate]
(2 answers)
Closed 3 years ago.
I have *.scss file in an Angular 7 project.
After compiling it, the compiler adds unwanted whitespace to the css, which leads to wrong results in the UI.
To reproduce the error go to...
https://www.sassmeister.com/
...copy and paste the following code.
$color-background-default: white;
$color-foreground-default: black;
$color-background-disabled: #d3d3d3;
$color-foreground-disabled: #808080;
$color-background-mouseover: #00a7dc;
$color-foreground-mouseover: white;
$color-background-mousedown: #00467F;
$color-foreground-mousedown: white;
.Tab
{
background-color: $color-background-default;
color: $color-foreground-default;
:hover
{
background-color: $color-background-mouseover;
color: $color-foreground-mouseover;
}
:active
{
background-color: $color-background-mousedown;
color: $color-foreground-mousedown;
border-color: $color-background-mousedown;
}
}
In the CSS box of Sassmeister you should see, that there are whitespaces between ".Tab" and "hover" and "active" that look like this:
.Tab {
background-color: white;
color: black;
}
//WHITESPACE AFTER Tab
.Tab :hover {
background-color: #00a7dc;
color: white;
}
//WHITESPACE AFTER Tab
.Tab :active {
background-color: #00467F;
color: white;
border-color: #00467F;
}
Now when I remove the whitespaces between Tab and hover and active it looks like this:
.Tab {
background-color: white;
color: black;
}
//NO WHITESPACE AFTER Tab!
.Tab:hover {
background-color: #00a7dc;
color: white;
}
// NO WHITESPACE AFTER Tab!
.Tab:active {
background-color: #00467F;
color: white;
border-color: #00467F;
}
The second option without whitespaces gives me the correct UI result.
My question: How can I avoid these whitespaces in Angular 7?
The parent selector, &, is a special selector invented by Sass that’s
used in nested selectors to refer to the outer selector. It makes it
possible to re-use the outer selector in more complex ways, like
adding a pseudo-class or adding a selector before the parent.
(from SASS official documentation)
So when you write rules for pseudo-class (before, after, hover, active etc.), to refer to the outer selector (only one level higher), put the ampersand like this:
.link {
color: blue;
&:hover {
color: green;
}
}
So, your SCSS code can be rewritten as:
$color-background-default: white;
$color-foreground-default: black;
$color-background-disabled: #d3d3d3;
$color-foreground-disabled: #808080;
$color-background-mouseover: #00a7dc;
$color-foreground-mouseover: white;
$color-background-mousedown: #00467F;
$color-foreground-mousedown: white;
.Tab
{
background-color: $color-background-default;
color: $color-foreground-default;
&:hover
{
background-color: $color-background-mouseover;
color: $color-foreground-mouseover;
}
&:active
{
background-color: $color-background-mousedown;
color: $color-foreground-mousedown;
border-color: $color-background-mousedown;
}
}
You're looking for the sass ampersand.
.Tab {
:hover {
...
}
}
...should be:
.Tab {
&:hover {
...
}
}
& means: "current selector". You use &:hover to specify
#{currentSelector}:hover.
Without the ampersand, it results into #{currentSelector} :hover and that's the way you want it to work for constructs like
.a {
.b {
...
}
}
... which parses as .a .b {...}.
A more ample explanation here.
Note: the ampersand also allows specifying a prefix to current selector. For example:
.a {
.b {
prop: value;
.c & {
prop: otherValue;
}
}
}
will parse into:
.a .b { prop: value; }
.c .a .b { prop: otherValue; }

SCSS, how to #extend Nested ampersand "prefix"?

The nested ampersand prefix doesn't get expanded with #extend
.firstClass{
color: green;
&-a{
color: red;
}
}
.secondClass{
#extend .firstClass;
}
The expected output would be
.firstClass, .secondClass{
color: green;
}
.firstClass-a, .secondClass-a{
color: red;
}
But the actual output doesn't have the .secondClass-a at all.
.firstClass, .secondClass{
color: green;
}
.firstClass-a{
color: red;
}
I found this is an intended behavior to use #extend https://github.com/sass/sass/issues/2154
But is there a workaround that can extend nested ampersand prefix?
Maybe the versions I worked on were older but I don't believe it was possible. You could change your properties to a mixin as such:
#mixin classStyle {
color: green;
&-a{
color: red;
}
}
.firstClass {
#include classStyle;
}
.secondClass {
#include classStyle;
}

A better way to write these SASS rules

I need to overwrite some Bootstrap rules using SASS:
.open>.btn-default.dropdown-toggle{
background-color: transparent;
color: red;
&:focus, &:hover{
background-color: transparent;
color: red;
}
&:active:focus{
outline: 0;
}
}
Is there a better way to write this? Without repeating background-color and color?
You could extend a placeholder class, similar to a mixin, but the output CSS is cleaner. This would be the recommended approach for smaller things. A placeholder class starts with % and doesn't get output in CSS as a single class, but groups all rules that use it so it doesn't get repeat.
%red-transparent {
background-color: transparent;
color: red;
}
.open>.btn-default.dropdown-toggle{
#extend %red-and-transparent;
&:focus, &:hover{
#extend %red-and-transparent;
}
}
Results in this css
.open > .btn-default.dropdown-toggle, .open > .btn-default.dropdown-toggle:focus, .open > .btn-default.dropdown-toggle:hover {
background-color: transparent;
color: red;
}
You could use a mixin like this:
#mixin red-and-transparent {
background-color: transparent;
color: red;
}
And use it like this:
.open>.btn-default.dropdown-toggle{
#include red-and-transparent;
&:focus, &:hover{
#include red-and-transparent;
}
}
But for 2 properties used twice, I wouldn't bother with this and just leave it how you have it now.

SCSS selector pick

I just started to using sass/scss and i have a small issue. Let's assume this code:
.button {
color:#c00;
&:hover {
color:#000;
}
}
Everything is awesome and works as it supposed to. But.. Let's say I want to do different hovers depending of tag. So, if the tag is a span to show a color and if the tag is a a to show another color.
Is this possible without repeating some part of the selector?
Thanks!
No. Remember that in the end everything compiles to CSS.
The way to do it would be the following:
.button {
.green {
color:green;
&:hover { color:black; }
}
.red {
color:red;
&:hover { color:black; }
}
}
You would need to add a class though.
You could use the mixin approach but it's going to be more verbose.
I would do it like this:
.button {
color: red;
&:hover { color: black; }
}
span.button:hover { color: green; }
a.button:hover { color: blue; }
Have a play yourself here: http://tinkerbin.com/CBuHSGfV

Resources