SCSS selector pick - css

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

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

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

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

SCSS selection with "&". Advanced trick

I have a button class .btn and want to select only when it is with a link. What to add to a so I will get a.btn using SCSS and my code bellow?
SCSS:
.btn {
background: red;
a {
background: blue;
}
}
I want to get this in css:
.btn {
background: red;
}
a.btn {
background: blue;
}
Logical will be to do this a&. But it gives an error. a & and & a is giving a different result.
I know that this can be done with #at-root a#{&} but it is too ugly =) Is there a pretty way?
.btn {
background: red;
#at-root a#{&} {
background: blue;
}
}
This should work:
a {
&.btn {
background: blue;
}
}
.btn {
background: red;
}
You can't write that in a single block. In case if that's what you are trying to do.
Since .btn& is not a valid scss, it seems that #at-root a#{&} is your only option.

SCSS append to root selector from child

I know in SCSS I can do this:
.foo {
color: blue;
a {
color: red;
.bar & { color: green; }
}
}
And get this:
.foo { color: blue; }
.foo a { color: red; }
.bar .foo a { color: green; }
But is there a way to append that selector, to result in:
.foo { color: blue; }
.foo a { color: red; }
.foo.bar a { color: green; }
Note this is a simple example, in my use case the rule is nested much deeper than this.
The & only works one level up. In your code example, you wouldn't be able to get the code you expect. You'll need to handle it in a different way.
.foo {
color: blue;
a {
color: red;
}
&.bar {
a {
color:green;
}
}
}
Apparently this only renders with phpsass compiler, so it is compiler specific.
Just get rid of your space before the &:
.foo {
color: blue;
a {
color: red;
.bar& { color: green; }
}
}
Compiles to:
.foo {
color: blue;
}
.foo a {
color: red;
}
.bar.foo a {
color: green;
}
Note that .foo.bar and .bar.foo are equivalent selectors (they both make a selection only if both classes are on the item), so the order does not matter in such a case. Now, whether this could work in a more deeply nested structure (which you state you have) all depends on what you are trying to target, but essentially this would add a class to the outmost level (your .foo equivalent) no matter how deep the structure.
There is a way to PREPEND that selector.
.foo {
color: blue;
a {
color: red;
#at-root .bar#{&} { color: green; }
}
}
This would compile to:
.foo { color: blue; }
.foo a { color: red; }
.bar.foo a { color: green; }
The #at-root rule causes everything proceeding it to be emitted at the root instead of using regular nesting.
You can qualify a selector by putting & to the right of the intended parent of the selector. Wrapping it in #{} allows you to escape the space.
If you use both, you can PREPEND the root parent selector.. but unfortunately, you are unable to append it.
You're having an XY problem. You need to override the color of a, but instead of asking for an optimal way to do that, you invent some weird construction and ask why it is not working.
The matter is that you don't need to put a inside .foo to override the color. An a gets it's color not from .foo directly, but from a's own color property.
By default color is set to inherit, which naturally inherits from parent. So to override a's color, you change it's color property from inherit to whatever you want. To do that, you don't need to put parent into the selector!
UPD: As cimmanon has corrected me below, the color of a is not inherited from parent, it uses its own default value instead.
So an optimal solution would be this:
.foo {
color: blue; }
a {
color: red;
.foo.bar & {
color: green; } }
Also, the fact that you want to override exactly for .foo.bar a indicates that you're overcomplicating things.
You only need .foo.bar a if you need to handle four different situations: a, .foo a, .bar a and .foo.bar a. Do you really have that much different colors for the links? Why?
Most certainly you could refactor your HTML structure, make it more semantic and be happy with code like this:
a {
color: red; }
#header {
color: blue; }
.cart-item
& a {
color: green; } }
With this code, the link can only be two different colors: green for cart items and red for everything else.
If you do have a good reason to have many colors, consider using a mixin:
#mixin link-with-color($color: red) {
a {
color: $color; } }
#header {
#include link-with-color(blue); }
.cart-item {
#include link-with-color(green); }

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.

Resources