In LESS I could write something like:
.foo {
color: red;
}
.boo {
.foo();
background: blue;
}
To "include" properties of .foo class into .boo one.
What is the easiest and clean way to obtain a similar beaviour in SCSS?
How about trying like this,
mixins.scss
#mixin flex($x: center, $y: center) {
display: flex;
align-items: $x;
justify-content: $y;
}
custom.scss
.classname {
#include flex(flex-start, space-between);
color: red;
}
Use #include
Related
I want to use one CSS style for two classes with mixin, but when I use mixin the final result will be 2 classes with the same CSS.
I have shared my code example below:
#mixin btnhover {
background-color: $bg-cl-blc;
color: $txt-cl-ff;
}
.btn-base {
font-size: 15px;
&:hover {
#include btnhover;
}
}
.btn-otln {
font-size: 15px;
&:hover {
#include btnhover;
}
}
**OUTPUT CSS**
.btn-base:hover {
background-color: #000;
color: #fff;
}
.btn-otln:hover {
background-color: #000;
color: #fff;
}
This is how Sass works - it allows for better organisation of the code, but this code is then compiled, retaining functionality and not caring about other aspects.
If you really care about how the output code is structured, I would suggest to create a separate style for the classes with the hover effect:
#mixin btnhover {
background-color: #000;
color: #fff;
}
.btn-base {
font-size: 15px;
}
.btn-otln {
font-size: 15px;
}
.btn-base:hover,
.btn-otln:hover {
#include btnhover;
}
But in this approach, the use of mixin (and Sass) is questionable (in this exact case).
Generally, when you use Sass (or any other compiled language), you don't really care about the output CSS.
This won't be your answer, but I want to show you another way to make a mixin
#mixin btnhover($back, $color) {
background: $back;
color: $color;
}
When you use it, you can plug in the values
#include mixin btnhover($bg-cl-blc, $txt-cl-ff)
That way you can use the mixin over and over in different places with different values
Just discovered this recently myself, it's a concept called 'placeholders' in SASS syntax (see example below). I've done my best to apply it to your situation below....
Put this in your .scss file:
$bg-cl-blc: #ff211a;
$txt-cl-ff: #fff;
$btn-base-size: 15px;
%btnhover {
background-color: $bg-cl-blc;
color: $txt-cl-ff;
}
%btn-common {
font-size: $btn-base-size;
}
.btn-base {
#extend %btn-common;
&:hover {
#extend %btnhover;
}
}
.btn-otln {
#extend %btn-common;
&:hover {
#extend %btnhover;
}
}
CSS output will look like this
.btn-otln:hover, .btn-base:hover {
background-color: #ff211a;
color: #fff;
}
.btn-otln, .btn-base {
font-size: 15px;
}
Great article written up on this here:
https://dev.to/kemotiadev/are-sass-mixins-really-that-lightweight-and-what-are-placeholders-119i
I want to make a short-written flex rules using classes in SCSS. I want to write a one time justify-content class block and to use #mixin in order to insert it to the flex options.
How (if possible) can I write a relative variable inside the #mixin that will represents the parent class that the #mixin was included in?
.row {
display: flex;
flex-direction: row;
#include justification;
}
.column {
display: flex;
flex-direction: column;
#include justification;
}
#mixin justification {
&-center {
#extend {parent};
justify-content: center;
}
&-start {
#extend {parent};
justify-content: start;
}
}
What comes instead of {parent}, where 'parent' represents the class where this mixin was included in?
I think you should make a mixin as shown below and give default values in it.
#mixin flex-properties($flex:flex, $justify-content: center, $align-items: center) {
display: $flex;
justify-content: $justify-content;
align-items: $align-items;
}
To use the above mixin & also you can change the default value of its parameters:-
.some-class {
#include flex-properties(flex, space-between, center);
}
YES! I did it!
The key to the answer is to pass the includer's class name to the #mixin as an argument. Like so:
.row {
display: flex;
flex-direction: row;
#include justification(&);
}
.column {
display: flex;
flex-direction: column;
#include justification(&);
}
#mixin justification($class) {
&-center {
#extend #{$class};
justify-content: center;
}
&-start {
#extend #{$class};
justify-content: start;
}
}
It works
Let's say I have the following mixin:
#mixin foo {
color: red;
}
This mixin is imported in a library, so I don't want to touch the source code. I do however want to extend the functionality of the mixin, and add my own styles to it.
So I need a way to create a new mixin with the same name, whilst retaining the original output but allowing me to add new output, something like:
#mixin foo {
color: blue;
}
#mixin foo {
#include foo; // this is the original
font-size: 14px;
}
Of course the above will not do what I want, but is there something I can do?
I've been playing around and came up with this which seems to work:
#mixin foo() {
color: red;
}
%foo {
#include foo;
}
#mixin foo() {
#extend %foo;
font-size: 22px;
}
.foo {
#include foo;
}
You can extend/change code block of a Mixin using #content; while you have lines inside it by default.
#mixin foo(){
background:green;
border:solid 5px black;
#content;
}
div{
width:200px;
height:100px;
&.one{
+foo(){
border:0;
}
}
}
https://jsfiddle.net/Thielicious/hhb09b61/
After converting a lot of redundant crappy css files into scss files, I have a bunch of scss files. I'm pretty sure there is a lot of common css repeated among these files and I would like to extract this code.
As an example, let's say I have this block of scss code (let's call it block A) :
.test {
color: white;
.toto {
background: red;
font-size: 12px;
}
}
And another block (that we'll call block B) :
.test {
color: black;
.toto {
background: blue;
font-size: 12px;
text-align: center;
}
}
I want to be able to extract the following common scss code from block A and B :
.test {
.toto {
font-size: 12px;
}
}
It seems like a simple task to do, but with a large list of long scss files, it's really painful to do it manually. After searching for a while I didn't find any tool for that.
An intermediary solution could be to convert sass code to a multi-dimensionnal associative array and to process arrays to find intersections, but I could not find any simple solution to do that either, so any help would be appreciated.
There are a few approaches but in this instance, I would opt for a variable:
$base-font-size: 12px;
.test {
color: white;
.toto {
background: red;
font-size: $base-font-size;
}
}
.test {
color: black;
.toto {
background: blue;
font-size: $base-font-size;
text-align: center;
}
}
Or you could add a toto mixin with some defaults and use that:
#mixin toto($background: red, $text-align: left, $font-size: 12px) {
.toto {
background: $background;
text-align: $text-align;
font-size: $font-size;
}
}
.test {
color: white;
#include toto();
}
.test {
color: black;
#include toto(blue, center);
}
EDIT: or use extend:
.font-size-12 {
font-size: 12px;
}
.test {
color: white;
.toto {
#extend .font-size-12;
background: red;
}
}
.test {
color: black;
.toto {
#extend .font-size-12;
background: blue;
text-align: center;
}
}
I am trying to learn SASS. I got this snippet working but the generated css is awful in my opinion. I would like all this css to go in te same .container{ }. Not three different as shown below.
SASS:
.container{
#extend %clearfix;
#extend %text-truncate;
#include border-radius(10px);
}
Genereted css:
.container{
...clear fix
}
.container{
...text-truncate
}
.container{
...clear border-radius
}
What I want:
.container{
...clear fix
...text-truncat
...clear border-radius
}
This is the nature of #extend. If you change your extend classes to ordinary classes, the way it works the way it does is revealed.
#mixin my-mixin() {
padding: 1em;
}
.a {
color: red;
}
.b {
border: 1px solid;
}
.foo {
#extend .a;
#extend .b;
#include my-mixin();
}
Compiles to:
.a, .foo {
color: red;
}
.b, .foo {
border: 1px solid;
}
.foo {
padding: 1em;
}
Using an extend only class simply suppresses the name from the output. If your extend classes are not intended for reuse, then they are better suited as a mixin.
See also: https://codereview.stackexchange.com/a/27910/26722