Using SASS to extend selectors with elements - sass

I'm working on an SCSS stylesheet, and I have a rule that looks something like this:
.footer-link-row {
color: red;
ul& {
padding: 0;
}
}
I want the ul& line compile to the selector ul.footer-link-row. However, this selector returns a compiler error, and using a &ul compiles to .footer-link-row ul. What's the correct way to select something like this?
--Added--
To clarify, the eventual CSS I want out of this is:
.footer-link-row {
color: red;
}
ul.footer-link-row {
padding: 0;
}

You want something like the following:
ul {
padding: 0;
.footer-link-row {
color: red;
}
}
The ampersand is used to require that both selectors match
a { text-decoration: none;
&:hover { border-width: 1px }
}
// compiles to
a {
text-decoration: none;
}
a:hover {
border-width: 1px;
}
If you want the ul.footer-link-row try
ul {
&.footer-link-row {
padding: 0;
}
.footer-link-row {
color: red;
}
}
Your clarification indicates that you need two scopes.
ul {
&.footer-link-row {
padding: 0;
}
}
.footer-link-row {
color: red;
}

Related

One shared selector between multiple classes

How to apply the same focus state to multiple different classes?
Problem:
.btn {
&.error {
border-color: red;
}
&.primary {
border-color: green;
}
&:focus {
border-color: blue;
// this is not applied but i don't want to
// declare the same style to both classes
}
}
I understand this would be one option, but it is also not the prettiest option as i need to list them separately here
.btn {
&.error {
border-color: red;
}
&.primary {
border-color: green;
}
&.primary:focus, &.error:focus {
border-color: blue;
}
}
Are there any better ways?
Using & again in the nested rule is a good way for your purpose.
.btn {
&.error {
border-color: red;
}
&.primary {
border-color: green;
}
&.primary, &.error {
&:focus{
border-color: blue;
}
}
}

how to simply style in scss so that multiple elements will use same style

I am new to sass.
Here is my code in scss. Just wondering if this can be simplified further i.e i dont want to repeat the style color, text-decoration and transition.
a {
color: inherit;
text-decoration: none;
transition: all 0.3s;
}
div.menu-item-click {
&:hover, &:focus {
color: inherit;
text-decoration: none;
transition: all 0.3s;
}
}
Note exactly that use case is covvered better by ReSedano.
You cand do it using mixins:
#mixin mixinName {
color: inherit;
text-decoration: none;
transition: all 0.3s;
}
a {
#include mixinName;
}
div.menu-item-click {
&:hover, &:focus {
#include mixinName;
}
}
Also here is example with variables:
#mixin icon($width) {
width: $width;
stroke: currentColor;
}
.icon {
#include icon(25px);
}
And here is example with body
#mixin desktop ($xl: null) { // look here is default Value!
#media (min-width: if($xl, $xl, $screen-desktop)) {
#content; // here is true magic
}
}
.page {
#include desktop { // you may ignore variable because we have default
padding: 30px;
}
}
For this, maybe it is better using a placeholder with #extend directive (the output is less verbose than using a mixin):
%my-class {
color: inherit;
text-decoration: none;
transition: all 0.3s;
}
a {
#extend %my-class;
}
div.menu-item-click {
&:hover, &:focus {
#extend %my-class;
}
}
The output is:
a, div.menu-item-click:hover, div.menu-item-click:focus {
color: inherit;
text-decoration: none;
transition: all 0.3s;
}

Prevent combination of multiple selectors

I'm trying to group all my vendor-specific stuff into a placeholder selector like this:
%search-bar-placeholder {
color: red;
}
.search-bar::-webkit-input-placeholder {
#extend %search-bar-placeholder;
}
.search-bar:-moz-placeholder {
#extend %search-bar-placeholder;
}
.search-bar::-moz-placeholder {
#extend %search-bar-placeholder;
}
.search-bar:-ms-input-placeholder {
#extend %search-bar-placeholder;
}
And then it compiles to this:
.search-bar::-webkit-input-placeholder, .search-bar:-moz-placeholder, .search-bar::-moz-placeholder, .search-bar:-ms-input-placeholder {
color: red; }
How can I make sure Sass doesn't put all the selectors together ? Like this:
.search-bar::-webkit-input-placeholder {
color: red;
}
.search-bar:-moz-placeholder {
color: red;
}
.search-bar::-moz-placeholder {
color: red;
}
.search-bar:-ms-input-placeholder {
color: red;
}
When looking at Extend/Inheritance at sass-lang.com it seems that the selectors will always be comma separated. Even if you add another property, it will keep the shared properties in the comma separated list, and add another selector just for that overridden value.
The way I achieved what you want is by using a mixin. Though it's not really the purpose of a mixin, it does get the job done. Your style is still centralized and you can print it out in each selector using a one liner too.
#mixin placeholder-properties() {
color: red;
font-weight: bold;
}
.search-bar::-webkit-input-placeholder {
#include placeholder-properties();
}
.search-bar:-moz-placeholder {
#include placeholder-properties();
}
.search-bar::-moz-placeholder {
#include placeholder-properties();
}
.search-bar:-ms-input-placeholder {
#include placeholder-properties();
}
The result will the following.
.search-bar::-webkit-input-placeholder {
color: red;
font-weight: bold;
}
.search-bar:-moz-placeholder {
color: red;
font-weight: bold;
}
.search-bar::-moz-placeholder {
color: red;
font-weight: bold;
}
.search-bar:-ms-input-placeholder {
color: red;
font-weight: bold;
}
Here's a fiddle.

Appending to class name via nesting with attribute selector

I have the following sass:
.list {
&__button{
cursor:pointer;
display: block;
padding: 4px;
border:1px solid $color4;
outline: none;
&__square {
border: 1px solid $color1;
width:12px;
height:12px;
}
&__text {
padding-right: 5px;
color: red;
}
}
&__button[state-selected="true"] {
.list__button__text {
color : $color1;
}
}
}
I have to use the full name of the class to get this part to work:
&__button[state-selected="true"] {
.list__button__text {
color : $color1;
}
}
Is there any way to simplify this part? Something like:
&__button[state-selected="true"] {
&__text {
color : $color1;
}
}
But this gives an error: Invalid parent selector for "&__text": ".list__button[state-selected="true"]".

Make one variable double the value of the other with SASS

Im using SASS. I need on value to be double another value so the logic is this:
.one {
padding: 'value';
}
.two {
padding: 'value times 2';
}
So it could be this:
.one {
padding: 2px;
}
.two {
padding: 4px;
}
Or this:
.one {
padding: 10px;
}
.two {
padding: 20px;
}
How can I write this?
If you want a value you can reuse, you need a variable.
$my-padding: 1em;
.one {
padding: $my-padding;
}
.two {
padding: $my-padding * 2;
}

Resources