SASS / SCSS hover when using &__* syntax to reach parent selector - css

Yes yes, I had a hard time trying to define my question.
The general case is like this:
in sass/scss I have a button with some variants:
.button {
/* generic button styles here */
&__icon {
color: green;
}
}
And now I wish to use some hover styles on this, per variant. But because I use the &__* I can't seem to grasp how to do this without rewriting the parent class name.
.button {
/* generic button styles here */
&__icon {
color: green;
}
&:hover {
.button__icon {
color: red;
}
}
}
^^ this works but is pretty manual
Is there a way in sass that allows to access the parent class and get something like:
&:hover {
&__icon {
color:red;
}
}
But this time the &__icon should reference the parent.
The html to this would look somewhat like this:
<button type="button" class="button">
[name]
<span class="button__icon">+</span>
</button>

.button {
$root: &;
&__icon {
color: green;
}
&:hover #{$root}__icon {
color: red;
}
}
or
.button {
$root: &;
&__icon {
color: green;
#{$root}:hover & {
color: red;
}
}
}

Related

make focused button look like non-focussed button

Within a specific div, I want to make focused buttons to look exactly like non-focused buttons.
Is there a way I can express that in sass/scss?
Something similar to this:
.myDiv {
> button {
&:focus {
#extend &:not(&:focus)
}
}
}
Alternatively, can I disable all rules that are applied only because of the definition for pseudo-class :focus ?
You can simply overwrite the default styling by doing this below
.myDiv {
> button {
&:focus {
outline: none;
}
}
}
If you needed to use extend, you could do something like this
%no-focus {
outline: none;
}
.myDiv {
> button {
&:focus {
#extend %no-focus;
}
}
}
However, I advise you read this article from the a11y project - which explains why in terms of it's not good to un-style :focus'd elements in terms of accessibility.
You could use placeholder selectors. Something along the lines of this:
%button {
color: red;
}
button {
#extend %button;
&:focus {
color: green;
}
}
.myDiv {
> button:focus {
// Extend from %button again, thus overriding through specificity.
#extend %button;
}
}
Here, I explain simply. Please see the code below.
HTML:
<div class="mydiv">
<button>My Button</button>
</div>
SCSS:
* {
outline: none;
}
.mydiv {
button {
border: 1px solid #000;
&:focus {
border:1px solid #ccc;
}
}
}

How to extend in scss from parent (in case of BEVM)

I try to understand BEVM+SCSS philosophy.
I don't know how to extend V from BE in this case.
What I want to achieve:
.block {
&__element {
background-color: black;
&--variation-a {
#extend &__element; //won't work
color: red;
}
&--variation-b {
#extend &__element; //won't work
color: green;
}
}
}
What I want to avoid:
.block {
&__element {
background-color: black;
&--variation-a {
#extend .block__element; //work but ugly
color: red;
}
&--variation-b {
#extend .block__element; //work but ugly
color: green;
}
}
}
The only way I've found it's to have a kind of %element { ... } aside and extends from it, but it's not exactly what I want.
You can use variables. $b to store block name and $e to store element name.
Sassmeister demo.
.block {
$b: &;
&__element {
$e: #{$b}__element;
background-color: black;
&--variation-a {
#extend #{$e};
color: red;
}
&--variation-b {
#extend #{$e};
color: green;
}
}
}
But it's bad practice to nest element styles by modifier. Modifier must only override styles.

Compass (SASS) rule with pseudo class

Is it possible to generate css rule for element for normal state and some other pseudo state like this:
.heading-link, .heading-link:hover {
color: red;
}
with
.heading-link {
color: $state-info-text;
&:hover {
color: $state-info-text;
}
}
I got
.heading-link {
color: #538DA7;
}
.heading-link:hover {
color: #538DA7;
}
What is not as expected, plus I have to write rule for color twice.
You can use the parent selector (&) by itself, in addition to other selectors inside nested blocks.
DEMO
$state-info-text: #538DA7;
.heading-link {
&, &:hover {
color: $state-info-text;
}
}
Compiles to
.heading-link, .heading-link:hover {
color: #538DA7;
}
Yes. You can use Sass's built in #extend function for this.
$state-info-text: red;
.heading-link {
color: $state-info-text;
&:hover {
#extend .heading-link;
}
}
Gives the output:
.heading-link, .heading-link:hover {
color: red;
}

CSS-Less class extend class with pseudo class

I was wondering how I could do something like the following with less css:
.btn {
color : black;
}
.btn:hover {
color : white;
}
.btn-foo {
.btn;
&:hover {
.btn:hover;
}
}
Of-course this is just an example, what need to point is if there is any way to extend the pseudo-class in order to avoid re-type the properties of :hover pseudo class everywhere I need them. I know I could create a mixin for that but I'm wondering if I could avoid it.
Thanks
UPDATE:
If you can't modify external files just redefine the selectors, and add missing states:
.btn {
// not adding anything here, won't affect existing style
&:hover {
// adding my own hover state for .btn
background: yellow;
...
}
}
// this will make your foo button appear as in external style
// and have the :hover state just as you defined it above
.btn-foo {
.btn;
}
Better now? :)
You don't need pseudo class. It will just work :)
Try this:
.btn {
background: yellow;
&:hover { // define hover state here
background: green;
}
}
button {
.btn;
}
Each <button class='btn'> element you create will inherit whatever was defined, including hover state. I think it's one of the main amazing features of LESS.
Hope this helps.
In Less 1.4.0(1.4.1?)
This:
.btn {
color : black;
}
.btn:hover {
color : white;
}
.btn-foo:extend(.btn all) {
}
Expands to this:
.btn,
.btn-foo {
color: black;
}
.btn:hover,
.btn-foo:hover {
color: white;
}
Be cautious though, this:
.btn {
color : black;
}
.btn:hover {
color : white;
}
.abc .btn {
margin: 2px;
}
.btn-foo:extend(.btn all) {
}
Will output this:
.btn {
color : black;
}
.btn:hover {
color : white;
}
.abc .btn {
margin: 2px;
}
.btn-foo:extend(.btn all) {
}
I have not looked into SASS more than half an hour, but I believe the later case is its default (or only) #extend behavior.

SCSS selector pick

I just started to using sass/scss and i have a small issue. Let's assume this code:
.button {
color:#c00;
&:hover {
color:#000;
}
}
Everything is awesome and works as it supposed to. But.. Let's say I want to do different hovers depending of tag. So, if the tag is a span to show a color and if the tag is a a to show another color.
Is this possible without repeating some part of the selector?
Thanks!
No. Remember that in the end everything compiles to CSS.
The way to do it would be the following:
.button {
.green {
color:green;
&:hover { color:black; }
}
.red {
color:red;
&:hover { color:black; }
}
}
You would need to add a class though.
You could use the mixin approach but it's going to be more verbose.
I would do it like this:
.button {
color: red;
&:hover { color: black; }
}
span.button:hover { color: green; }
a.button:hover { color: blue; }
Have a play yourself here: http://tinkerbin.com/CBuHSGfV

Resources