Why does this SCSS result in a no-descending-specificity error? - sass

This small SCSS block
a {
color: red;
&:hover {
color: green;
}
}
i {
a {
text-decoration: none;
}
}
Gives this error
Expected selector "i a" to come before selector "a:hover" no-descending-specificity
But if I reverse the order
i {
a {
text-decoration: none;
}
}
a {
color: red;
&:hover {
color: green;
}
}
The error just reverses too
Expected selector "a" to come before selector "i a" no-descending-specificity

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;
}
}
}

parent, &, intercalation in css attribute

I have the following code:
&__menu {
float: left;
list-style: none none;
padding: $navbar-menu_padding;
[class^=#{&}__item] {
....
}
I'm trying to an interpolation of & - [class^=#{&}__item].
This will fail, with or without interpolation.
There is another option, besides writing the full name of the class ?
You can store parent class name into variable.
Scss:
.block {
$this: &; // Variable
&__item {
color: red;
}
&:hover {
// Using variable instead of full class name
#{$this}__item {
color: green;
}
}
}
Css output:
.block__item {
color: red;
}
.block:hover .block__item {
color: green;
}

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"]".

Using SASS to extend selectors with elements

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;
}

Resources