I am trying to find a way to include the parents styles within nested styles. In the code below, I want to include the width and box-sizing that are set on .random-div in the two nested styles too, so that .random-div--large would have width, box-sizing and padding all set.
.random-div {
width: 100%;
box-sizing: border-box;
&--large {
padding: 65px 45px;
}
&--small {
padding: 25px 15px;
}
}
I've tried extending the parent class within the nested ones but that includes all of the other nested styles too. Is there any way to just include the parent styles?
You can use the #extend rule without using a placeholder, just reference the parent class you want to extend:
.random-div {
width: 100%;
box-sizing: border-box;
&--large {
#extend .random-div;
padding: 65px 45px;
}
&--small {
#extend .random-div;
padding: 25px 15px;
}
}
This will compile to:
.random-div, .random-div--small, .random-div--large {
width: 100%;
box-sizing: border-box;
}
.random-div--large {
padding: 65px 45px;
}
.random-div--small {
padding: 25px 15px;
}
Note you can't use the parent selector (&) with the #extend rule, so this won't work:
.random-div {
width: 100%;
box-sizing: border-box;
&--large {
#extend &;
padding: 65px 45px;
}
&--small {
#extend &;
padding: 25px 15px;
}
}
Create a placeholder and use that.
%random-div {
width: 100%;
box-sizing: border-box;
}
.random-div {
#extend %random-div;
&--large {
#extend %random-div;
padding: 65px 45px;
}
&--small {
#extend %random-div;
padding: 25px 15px;
}
}
with your bem methodology your div should have both identifier and modifier and should look like this
<div class="random-div random-div--large"></div>
so it will get all three styles.
Related
I saw this code, when i was checking Drupal Omega 4 theme
%container {
#include container;
#include grid-background;
}
what does the '%container' mean?
what is the '%' for?
https://sass-lang.com/documentation/style-rules/placeholder-selectors
Placeholder Selectors: %foo
Sass supports a special type of selector called a “placeholder
selector”. These look like class and id selectors, except the # or .
is replaced by %. They’re meant to be used with the #extend directive;
for more information see #extend-Only Selectors.
On their own, without any use of #extend, rulesets that use
placeholder selectors will not be rendered to CSS.
Example
SCSS SYNTAX
%toolbelt {
box-sizing: border-box;
border-top: 1px rgba(#000, .12) solid;
padding: 16px 0;
width: 100%;
&:hover { border: 2px rgba(#000, .5) solid; }
}
.action-buttons {
#extend %toolbelt;
color: #4285f4;
}
.reset-buttons {
#extend %toolbelt;
color: #cddc39;
}
CSS Output
.action-buttons, .reset-buttons {
box-sizing: border-box;
border-top: 1px rgba(0, 0, 0, 0.12) solid;
padding: 16px 0;
width: 100%;
}
.action-buttons:hover, .reset-buttons:hover {
border: 2px rgba(0, 0, 0, 0.5) solid;
}
.action-buttons {
color: #4285f4;
}
.reset-buttons {
color: #cddc39;
}
SASS
%icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
.error-icon {
#extend %icon;
/* error specific styles... */
}
.info-icon {
#extend %icon;
/* info specific styles... */
}
Output
.error-icon, .info-icon {
transition: background-color ease .2s;
margin: 0 .5em;
}
.error-icon {
/* error specific styles... */
}
.info-icon {
/* info specific styles... */
}
Note
Placeholder selectors have the additional property that they will not show up in the generated CSS, only the selectors that extend them will be included in the output.
More info
http://thesassway.com/intermediate/understanding-placeholder-selectors
Tools
If you want to play around Sass please use - http://sassmeister.com/
It's a placeholder selector. It doesn't do anything on its own but can be extended, like an abstract base class.
I am creating a side navigation panel and I can't seem to figure out how to change colour of the text in link when I hover over it. The background colour changes. It actually worked before I added the animation but I wouldn't want to pass out on the animation.
.sidenav-navigation {
list-style: none;
padding: 1rem;
margin: 0;
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
.sidenav-navigation-items {
width: 100%;
margin-bottom: 0.5rem;
border-radius: 2rem;
cursor: pointer;
.sidenav-navigation-link {
display: flex;
align-items: center;
height: 3rem;
color: white;
text-decoration: none;
.sidenav-navigation-link-icon {
font-size: 22px;
width: 2rem;
min-width: 2rem;
text-align: center;
}
.sidenav-navigation-link-text {
text-align: center;
margin-right: 0.5rem;
animation:fadeIn 0.7s;
}
}
}
}
.sidenav-navigation-items:hover{
.sidenav-navigation-link {
transition: all .1s ease;
border-radius: 0.25rem;
background-color: white;
color: black;
}
}
#keyframes fadeIn{
0%{opacity:0;}
50%{opacity:50%;}
100%{opacity:100%;}
}
Probably white color style has higher priority due to more specific rules. Try to use !important rule with lower prio style.
.sidenav-navigation-items:hover{
.sidenav-navigation-link {
transition: all .1s ease;
border-radius: 0.25rem;
background-color: white;
color: black !important;
}
}
Other option may be changing the way of rules nesting to below:
.sidenav-navigation {
.sidenav-navigation-items {
.sidenav-navigation-link {
color: white;
}
&:hover {
.sidenav-navigation-link {
color: black;
}
}
}
}
it is possible to reuse all properties of another class in scss using the #extend method.
.class1 {
height: 10px;
width: 10px;
}
.class2 {
#extend .class1;
border-color: #000000;
}
Which will result in
.class1, .class2 {
height: 10px;
width: 10px;
}
.class2 {
border-color: #000000;
}
Is it possible, to reuse only custom properties of another class? Something like
.class2 {
#extend .class1.height;
border-color: #000000;
}
Which results in something like this
.class1 {
height: 10px;
width: 10px;
}
.class2 {
height: 10px;
border-color: #000000;
}
Thank you very much.
you can, but for that you need to extend a placeholder rather than a class. you abstract the desired properties to a placeholder, and apply at desired classes:
%custom-height {
height: 10px;
}
.class1 {
#extend %custom-height;
width: 10px;
}
.class2 {
#extend %custom-height;
border-color: #000000;
}
which will result in:
.class1, .class2 {
height: 10px;
}
.class1 {
width: 10px;
}
.class2 {
border-color: #000000;
}
In SASS's class selecter, I want to select parent's sibling.
.bw-textarea {
height: 150px;
padding: 10px;
overflow-y: auto;
background: white;
text-align: left;
width: 100%;
border: 1px solid #eeeeee;
font-size: 12px !important;
color: #666666;
// textarea:disabled & {
// background: #efefef;
// }
}
Compiled above sass code,
.bw-textarea textarea:disabled {
background: #efefef;
}
But I want to show result like this css code...
How to select like this in sass?
textarea.bw-textarea:disabled {
background: #efefef;
}
You gotta use #root in this case. It's pretty simple
This link will give a clear idea about this selector
.bw-textarea {
#at-root textarea#{&}:disabled{
background: cyan;
}
}
This will compile to
textarea.bw-textarea:disabled {
background: cyan;
}
See this PEN
This is what your looking for:
.bw-textarea {
height: 150px;
padding: 10px;
overflow-y: auto;
background: white;
text-align: left;
width: 100%;
border: 1px solid #eeeeee;
font-size: 12px !important;
color: #666666;
&:disabled {
background: #efefef;
}
}
Check out this SO answer for a lil more idea on the nested pseudo selectors
Sass parent selector and hover?
And of course check the sass docs
https://sass-lang.com/documentation/file.SASS_REFERENCE.html
Given the following Sass:
div.test {
display: inline-block;
background-color: #ffffff;
color: #000000;
&:before {
& {
&:hover {
border: 1px solid salmon;
}
}
width: 25px;
height: 25px;
content: "";
}
}
The resulting CSS compiles to:
div.test {
display: inline-block;
background-color: #ffffff;
color: #000000;
}
div.test:before {
width: 25px;
height: 25px;
content: "";
}
div.test:before:hover {
border: 1px solid salmon;
}
What I am attempting to do is generate div.test:hover:before (the current output is before:hover).
NOTE: I am able to generate the expected CSS by using the following Sass:
div.test {
display: inline-block;
background-color: #ffffff;
color: #000000;
&:hover {
&:before {
border: 1px solid salmon;
}
}
&:before {
width: 25px;
height: 25px;
content: "";
}
}
However I would like to know if it is possible using the first nested approach or some modification of it.
The goal was to avoid having to repeat &:before if there was such a way to do so using Sass syntax. I am also OK with knowing it isn't possible.
While initially the plan was to have '&' available in SassScript as a string that could be manipulated so that you could insert values wherever you wanted, those plans have been abandoned for 3.3 due to complication. Unfortunately you'll have to wait a while to be able to do this. At the moment '&' is immutable and just means "whatever the selector chain up to this point is".
EDIT (2020.02.15):
it is now technically possible to achieve this with recent versions of dart-sass:
#use "sass:selector";
#mixin unify-parent($child) {
#at-root #{selector.unify(&, $child)} {
#content;
}
}
div.test {
display: inline-block;
background-color: #ffffff;
color: #000000;
&:before {
width: 25px;
height: 25px;
content: "";
#include unify-parent(":hover") {
border: 1px solid salmon;
}
}
}
Sources:
https://sass-lang.com/blog/the-module-system-is-launched
https://sass-lang.com/documentation/style-rules/parent-selector#advanced-nesting