How useful is Sass's extend-feature? - css

I'm have currently started to learn Sass.
Now, looking on the way 'extend' is explained in the Basics documentation (http://sass-lang.com/guide) and wondering if it is really useful.
I mean: This ...
.message {
border: 1px solid #ccc;
padding: 10px;
color: #333;
}
.success {
#extend .message;
border-color: green;
}
.error {
#extend .message;
border-color: red;
}
.warning {
#extend .message;
border-color: yellow;
}
... compiles to ...
.message, .success, .error, .warning {
border: 1px solid #cccccc;
padding: 10px;
color: #333;
}
.success {
border-color: green;
}
.error {
border-color: red;
}
.warning {
border-color: yellow;
}
I could accomplish the same if I add the class .message to every HTML-element to which I want to apply this styles.
It's no work saved if I write multiple times #extend .message compared to multiple times class="message".
Right?
Or is there something else which I haven't understood?
Then please correct me.

Related

How to write ~ selector in LESS?

How to write this rule in LESS? I've been looking in documentation at http://lesscss.org/, but I did not find anything :(
input.text:focus { border: 1px solid #f00; }
input.text:focus ~ label.placeholder,
input.text:not(:focus):valid ~ label.placeholder { color: #f00; }
I have figured out this, it works, but I do not know how to correctly add the third line into this:
input.text { padding: 15px; background: #fff;
&:focus { border: 1px solid #f00;
~label.placeholder { color: #f00; }
}
}
Do it like below
input.text { padding: 15px; background: #fff;
&:focus,&:not(:focus):valid {
~label.placeholder { color: #f00; }
}
&:focus {
border: 1px solid #f00;
}
}
That will compile into
input.text {
padding: 15px;
background: #fff;
}
input.text:focus ~ label.placeholder,
input.text:not(:focus):valid ~ label.placeholder {
color: #f00;
}
input.text:focus {
border: 1px solid #f00;
}

Include optional psuedo classes in SCSS selector.

If if have something like:
input, select {
&:focus {
border: solid 1px blue;
}
}
.has-error {
input, select {
border: solid 1px red;
}
}
Then an input within a .has-error will still be styled blue, because the input:focus is more specific.
Is there an elegant way to override this?
The best I've got is:
input, select {
&:focus {
border: solid 1px blue;
}
}
.has-error {
input, select, input:focus, select:focus {
border: solid 1px red;
}
}
You need more nesting:
.has-error {
input, select {
&, &:focus {
border: solid 1px red;
}
}
}

Does SASS support element specification as nested selector?

Let's say you have this SASS definition (unreal example):
.class {
margin: 1px;
background: black;
color: white;
&:hover {
color: red;
}
}
a.class {
margin: 1px;
background: black;
color: yellow;
&:hover {
color: blue;
}
}
Now, can we put the a specification of the same class as a nested selector? E.g. something like this (pseudo-code):
.class {
margin: 1px;
background: black;
color: white;
&:hover {
color: red;
}
// Some selector to show that the current class
// should be applied to this element (?)
a.& {
color: yellow;
&:hover {
color: blue;
}
}
}
I have a solution, it's a little bit tricky, but it works fine.
.class {
color: yellow;
&:hover {
color: blue;
}
&[href] {
color: white;
&:hover {
color: red;
}
}
}
You may consider to write a mixin
#mixin sample($color,$hovercolor) {
margin: 1px;
background: black;
color: $color;
&:hover {
color: $hovercolor;
}
}
.class{ #include sample(white,red)}
a{ #include sample(yello,yellow)}
Hope this helps

Use sass extended placeholder with additional classes

I made this sass placeholder for a default button and there should be additional buttons like a success or danger button.
This is my sass placeholder in short:
%button {
border: none;
background-color: $default-color;
cursor: pointer;
color: $default-color-text;
}
%button-danger {
#extend %button;
background-color: $default-color-danger;
color: $default-color-danger-text;
}
%button-success {
#extend %button;
background-color: $default-color-success;
color: $default-color-success-text;
}
Now i want to extend from these buttons and make an element with a class to a button and with additional classes to a danger/success button.
.button {
#extend %button;
&.danger {
#extend %button-danger;
}
&.success {
#extend %button-success;
}
}
The result is
.button.danger, .button.success, .button {
border: none;
background-color: #a0a0a0;
cursor: pointer;
color: #ffffff; }
.button.danger {
background-color: #d9534f;
color: #fff; }
.button.success {
background-color: #5cb85c;
color: #fff; }
Thats correct, but i think of a lot of different buttons and there could be a shorter way like that:
.button { /* only one class in this directive */
border: none;
background-color: #a0a0a0;
cursor: pointer;
color: #ffffff; }
.button.danger {
background-color: #d9534f;
color: #fff; }
.button.success {
background-color: #5cb85c;
color: #fff; }
Is there a way to compile this result, or is that not recommendable?
You can remove the extend from %button-danger and %button-success.
%button {
border: none;
background-color: white;
cursor: pointer;
color: white;
}
%button-danger {
background-color: red;
color: red;
}
%button-success {
background-color: green;
color: green;
}
.button {
#extend %button;
&.danger {
#extend %button-danger;
}
&.success {
#extend %button-success;
}
}

LESS add class with pseudo selector

I use LESS and here is my example:
.arrow{
color: red;
}
.arrow:before{
content: ">";
}
.button{
background: blue;
.arrow;
&:before{
border: 1px solid;
}
}
And this is CSS after parsing:
.button{
background: blue;
color: red;
}
.button:before{
border: 1px solid; // HERE IS NO content: ">" !!!
}
How to add :before pseudo-element from .arrow class to my button?
You can use the extend option like below. It basically applies all properties of the arrow class to the button class also. The all keyword means the child classes are also extended.
LESS:
.button{
background: blue;
&:extend(.arrow all);
&:before{
border: 1px solid;
}
}
Compiled CSS:
.arrow,
.button {
color: red;
}
.arrow:before,
.button:before {
content: ">";
}
I think the Extend feature ought to do the trick:
.button {
&:extend(.arrow all);
background: blue;
&:before {
border: 1px solid;
}
}
See http://lesscss.org/features/#extend-feature

Resources