SCSS: Add element to existing rule - html

I have some rules nested inside each other, and I'd like to add another unrelated element to one of the rules.
For example if I have
#element1{
display: block;
.sub-element1 {
background: yellow;
.sub-element2 {
color: red;
}
}
}
and then I'd like to add another element (#element2) to use same rules as .sub-element2, so compiled code would look like this:
#element1{
display:block
}
#element1 .sub-element1 {
background:yellow
}
#element1. sub-element1 .sub-element2, #element2 {
color: red;
}
Is it possible?

You could use a mixin. You can add rules to a mixin, then include the mixins where you want them:
#mixin redcolor {
color:red;
}
Then simply include this mixin in any selector:
.subelement2, #element2 {
#include redcolor;
}
More on mixins here:
http://sass-lang.com/guide

Use #extend.
#element2 {
#extend .sub-element2
}
The output created by this will however also copy the selector chain, so this would be the output:
#element1. sub-element1 .sub-element2, #element2 {
color: red;
}
Perhaps that is what you want, but I can imagine it's not.
In this case you'll need to write an #extend only selector. It works much like an #include, except it generates the compact output you outline in your question. You could do it many ways, this is one of them:
%red {
color: red;
}
#element1{
display: block;
.sub-element1 {
background: yellow;
.sub-element2 {
#extend %red;
}
}
}
#element2 {
#extend %red;
}
Here's a link to it in the official docs.

Related

Adding a modifier class to parent/root selector in nested SCSS to modify styling

In a nested group of SCSS, is it possible to move up a level and apply a modifier class to the parent to overwrite styling?
For example, I have the following SCSS where an image is added to the before/after classes. I need to change the images on a different .btn-- styling. So essentially compiled the CSS would look a bit like .btn--ghost .label:before, .btn--ghost .after {}.
There is more styling to this but I've just stripped it out for this example so it's not a wall of code.
.btn--arrow {
.label {
&:before,
&:after {
background: url(../img/icon-arrow--white.svg) no-repeat 0 0;
}
&.btn--ghost & {
&:before,
&:after {
background: url(../img/icon-arrow.svg) no-repeat 0 0;
}
}
}
}
I have successfully achieved this with the SCSS outside of the .label, so directly under .btn--arrow (below) but out of curiosity and better understanding I'd be interested to know if it's achievable in the first example I gave.
.btn--arrow {
.label {
&:before,
&:after {
background: url(../img/icon-arrow--white.svg) no-repeat 0 0;
}
}
&.btn--ghost {
.label {
&:before,
&:after {
background: url(../img/icon-arrow.svg) no-repeat 0 0;
}
}
}
}
I have tried moving the & around and using stuff like #at-root but without any success.
Thanks in advance!
You can qualify a selector by putting & to the right of the intended parent of the selector. Wrapping it in #{} allows you to place it directly beside that parent.
The #at-root rule causes everything proceeding to be emitted at the root instead of using regular nesting.
If you use both and the #{}, I think you can achieve what you are looking for.
.flashlight {
.light {
background: yellow;
#at-root .dead-battery#{&} {
background: transparent;
}
.daytime &{
background: transparent;
}
}
}
This would compile to:
.flashlight .light {
background: yellow;
}
.dead-battery.flashlight .light {
background: transparent;
}
.daytime .flashlight .light {
background: transparent;
}

Using CSS Modules with Modernizr (class names)

Modernizr adds classes to the document's <html> tag, e.g. <html class="no-touchevents">.
In my code, I used to write something like this.
.style { background: green; }
.no-touchevents .style { background: red; }
So the element would be green (OK) if the touch is supported and red (error) if it's not. Now with CSS modules, my .style class is defined in a single file and gets transformed into something like this.
.xR23A { background: green; }
.hjTT7 .xR23A { background: red; }
If I wrap my class in a :global clause, it should remain unchanged if I understand it correctly. However, this will apply to every nested class, so I will remain with this.
.xR23A { background: green; }
.no-touchevents .style { background: red; }
How do I solve this to arrive to the desired solution? This is what I am after.
.xR23A { background: green; }
.no-touchevents .xR23A { background: red; }
you should be able to use the paren version of global to only hoise the modernizr portion.
i.e.
.style { background: green; }
:global(.no-touchevents) .style { background: red; }

SCSS + BEM style children structure when parent has modificator

Please is possible to set scss for element inside --rounded ? I do not wanna use .box__something, but I need to modify children that is depend on parent modifier
<div class="box">
<div class="box__something">Hello</div>
</div>
<div class="box box--rounded">
<div class="box__something">Hi</div>
</div>
.box {
&__something {
background: blue;
}
&--rounded {
background: green;
.box__something { // <<< Is some better selector?
background: pink;
}
}
}
Sass doesn't have any great built-in solutions to solve your issue, this is a problem that has been explored many times. You can however acheive the result you are after in a slightly un-elegant manner by using the & helper to join the classes that you wish to join. I have included a live example here.
While this does work, you must realise that if you want to style the .box--rounded class directly you must have it inside it's own class as illustrated below, you cannot use it with the trailing & class that we have placed &__something on.
I recommend you play around with my sassmeister gist and see what results you can come up with.
.box {
&__something {
background: blue;
}
&--rounded {
background: green;
}
&--rounded & {
&__something {
background: pink;
}
}
}
I hope this has solved your issue.
The modifier should be used not on the parent, and the child element .box__something
If I understand your problem correctly, I feel your pain! As soon as you nest a nested property & changes to the parent.
You can however cache the original class name as a variable like this:
$box: box;
.#{$box} {
.#{$box}__something {
background: blue;
}
.#{$box}--rounded {
background: green;
.#{$box}__something { // <<< Is some better selector?
background: pink;
}
}
}
The only problem with the method above is that you end up with a larger volume of compiled CSS. This renders to:
.box .box__something {
background: blue;
}
.box .box--rounded {
background: green;
}
.box .box--rounded .box__something {
background: pink;
}
To reduce the size of the output you could combine & with the variable method like so:
.box {
$box: &;
&__something {
background: blue;
}
&--rounded {
background: green;
#{$box}__something {
background: pink;
}
}
}
This renders to:
.box__something {
background: blue;
}
.box--rounded {
background: green;
}
.box--rounded .box__something {
background: pink;
}
That way you can change the class name in the variable and everything gets updated, I also think it reads a bit better.

CSS Selectors - How to apply a defined class on the selector's event

How can I apply a class properties to a class which has selectors in pure CSS? Example:
.one{color:red;}
.two{color:blue;}
.two:hover{ /*Apply class ".one" to class ".two" when the event is triggered */}
quite simple:
.two {
color: blue;
}
.one, .two:hover {
color: red;
}
Hope this helps!
If you ever did port over to SASS you could do it a little cleaner like:
.one {
color: blue;
}
.two {
color: red;
&:hover {
#extend .one;
}
}

Can I apply a :hover pseudo selector with the LESS css markup?

In LESS I can apply two rules like this to affect text styling of links to hide underline unless hovered:
.read-more
{
a
{
text-decoration:none;
}
a:hover
{
text-decoration:hover;
}
}
But I feel like I should also be able to define two rules like this:
.reverseHover
{
text-decoration:none;
}
.reverseHover:hover
{
text-decoration:hover;
}
And then use a mixin to get both rules:
.read-more{
a
{
.reverseHover;
}
}
Without having to explicitly do something like this:
.read-more{
a{
.reverseHover;
}
a.reverseHover:hover
{
.reverseHover;
}
}
Is that possible?
You can reference the parent selector using &. You can even use a parent selector in a mixin. Documentation is found at lesscss.org. Below is the solution.
.reverseHover {
text-decoration:none;
&:hover { text-decoration:underline; }
}
.read-more
{
a
{
.reverseHover
}
}