Condensing CSS class rules - css

I have code like:
#header button active:hover, #footer button active:hover {
color: purple;
}
Instead of having to list all the sub-classes/elements when only #header/#footer are different, is it possible to do something like:
(#header|#footer) button active:hover {
color: purple;
}

Yeah there's a matches pseudo class, but if you're hoping it will save you some typing it still needs vendor prefixes you'd have to duplicate and the support isn't great.
:matches(#header, #footer) button active:hover {
color: purple;
}
:-webkit-any(#header, #footer) button active:hover {
color: purple;
}
:-moz-any(#header, #footer) button active:hover {
color: purple;
}
So as you can see it ends up being more verbose than just adding the comma and another selector at the moment.

Related

What is the proper way of nesting related CSS lines?

I am trying to nest these lines of code together, I have tried the following but it does not work, is there any other way to have both the button and a tag changed by hovering the button through a single piece of code ?
.about-right button:hover {
background: #91c8ff;
& .a {
color: #151515;
}
}
Here is the orginal code:
.about-right button:hover {
background: #91c8ff;
}
.about-right button:hover a {
color: #151515;
}

How to reference SCSS sibling?

Assuming that I have the following HTML:
<div class="navigation__item">
<span class="navigation__item__icon"></span>
</div>
I want to apply some rules to an icon, when hovering an item, which can be described with the following CSS:
.navigation__item__icon {
color: black;
}
.navigation__item:hover .navigation__item__icon {
color: white;
}
I can achieve this using the following SCSS:
.navigation__item {
&:hover {
.navigation__item__icon { <-- here
color: white;
}
}
&__icon {
color: black;
}
}
Here, is there any way to avoid writing navigation__item? Something like "parent rule \ element".
I like Sass for logical structure so that if I want to rename the whole navigation block with elements, I can simply change navigation class name in the root, and everything is renamed. This case breaks this advantage.
Update: Actually, I have found a way to do this without using {} braces. & can be repeated more than once:
.navigation__item {
&:hover &__icon {
color: white;
}
&__icon {
color: black;
}
}
It is great, but it doesn't make much sense if I have many rules and rules for &:hover itself. The question is still open - is this possible to access sibling element definition from within the {} block.
In Stylus there is a Partial reference but I don't know anything similar in SASS. One solution could be using a variable for the parent selector:
.navigation__item {
$selector: &;
&:hover {
#{$selector}__icon {
color: white;
}
}
&__icon {
color: black;
}
}
Is usefull is you change navigation__item class for another.
EDIT: I had used a wrong example, it's OK now.

Is there a way to fall back to a non-pseudo-class style in CSS?

If I have a blue div that someone else owns the code for
.stuff {
background-color: blue;
}
And I want it to be red on hover
.stuff:hover {
background-color: red;
}
But then I want to be able to add a class for it to go back to its non-pseudo-class state:
.stuff.otherclass:hover {
background-color: unset; /* Want blue in this case */
}
Is there a CSS option of going back to a pre-pseudo-class state?
Codepen demo:
http://codepen.io/anon/pen/EyEWww
The only way to roll back the cascade is using the revert keyword, but it rolls back to another origin.
There is no way to make the 2nd value in the output of the cascade become the cascaded value, ignoring the winner.
Instead, you can modify your selector and use the :not() pseudo class:
.stuff {
background-color: blue;
}
.stuff:not(.otherclass):hover {
background-color: red;
}
Or, alternatively, take advantage of .stuff.otherclass:hover having more specificity than .stuff:hover
.stuff, .stuff.otherclass:hover {
background-color: blue;
}
.stuff:hover {
background-color: red;
}

Using :extend() in LESS with pseudo-elements

I would like to code a simple alert component that has color variations as well as font icon variations. The icons are coded with :before. I can write it fine in in vanilla CSS but I want to do it in LESS as compact as possible and I am stuck with using :extend() which I rarely used :(
.base-alert {
color: red;
...
&:before {
content: 'base-icon-unicode';
...
}
}
In vanilla CSS the code for the variation classes would be like:
.alert-warning {
color: red;
}
.alert-warning:before {
content "warning-icon-unicode";
}
But then the HTML should be class="base-alert alert-warning". I would like to code the variation classes in LESS, using :extend() so in HTML I would only write class="alert-warning" or class="alert-succes" and so on. Something like:
.alert-warning {
&:extend(.base-alert);
color: orange;
&:before {
content "warning-icon-unicode";
}
}
But it the :before doesn't apply anymore.
It seems like you are looking for the following:
.alert-warning:extend(.base-alert all) {
color: orange;
&:before {
content: "warning-icon-unicode";
}
}
This basically just extends .alert-warning from .base-alert using the all keyword. Then the content value for the pseudo-element is changed to warning-icon-unicode and the color is changed to orange.
Based on your comment about extending to multiple classes, I guess you could use the following, which will essentially just alias the selector:
.alert-warning, .alert-warning2 {
&:extend(.base-alert all);
color: orange;
&:before {
content: "warning-icon-unicode";
}
}
Alternatively, depending on your preferences, you could also use the following, which will produce the same desired results.
.alert-warning:extend(.base-alert all),
.alert-warning2:extend(.base-alert all) {
color: orange;
&:before {
content: "warning-icon-unicode";
}
}
..this will work the same as well:
.alert-warning:extend(.base-alert all) {
color: orange;
&:before {
content: "warning-icon-unicode";
}
}
.alert-warning2:extend(.alert-warning all) {}

Scoping CSS / Prepend selector with LESS

I have a chunk of CSS that I want to "scope" to a specific block of HTML. I'm generating a unique ID and then setting it on the block of HTML and then would like to wrap the chunk of CSS with the same ID so that those selectors can't match sibling or parent elements. I don't know the contents of the chunk of CSS. Given a chunk of CSS:
.container {
background-color: black;
}
.container .title {
color: white;
}
.container .description {
color: grey;
}
I need it to come out like this:
.theme0 .container, .theme0.container {
background-color: black;
}
.theme0 .container .title, .theme0.container .title {
color: white;
}
.theme0 .container .description, .theme0.container .description {
color: grey;
}
Is there any way to do this with LESS? The first selector is easy, just wrap the CSS chunk with '.theme0 {' + cssChunk + '}'. But I haven't been able to figure out a way to prepend '.theme0' to all of the selectors without the space.
EDIT:
So I should clarify that our intentions are to build such a system into our build process / dependency system. We're attempting to scope a chunk of css to a react component. We have a couple different approaches we're trying out, this is just one of them. Point is, the CSS and HTML we're trying to scope could be anything, we have no control or knowledge of it. The first pattern can easily be achieved by prepending .uniqueID { and appending }. This gives .uniqueID .someSelector {}. I'm wondering if it's possible to do a similar thing but get .uniqueID.someSelector {}? Ideally without having to write the original chunk of CSS with knowledge of our scoping system.
Assuming the component styles are in a separate CSS file, i.e.:
// component.css
.container {
background-color: black;
}
.container .title {
color: white;
}
.container .description {
color: grey;
}
The wrapper code could be:
.theme0 {
#import (less) "component.css";
&.container:extend(.theme0 .container all) {}
}
in less you can nest selectors for selecting inside that element like:
.theme {
color: black;
.container {
color: blue;
}
}
This wil generate:
.theme {
color:black;
}
.theme .container {
color:blue;
}
Creating elements that are connected is easy enof:
.test#badge will select a class test width an id badge
In less this is dont with the & symbol. (this selects the starting property)
.test {
color: blue;
&#badge {
color:black;
}
}
Compiles to:
.test {
color: blue;
}
.test#badge {
color: black;
}
And for the final selector:
To get the output of .test, .container use the function: .test:extends(.container);
.test {
color: black;
&:extends(.conatiner);
}
.container {
color: pink;
}
Compiles to:
.test {
color: black;
}
.test, .container {
color: pink;
}
You can even extend multiple ones in a single line:
.test:extends(.oclas, .tclss);
and its wil work as abose only for both classes. So outputed selectors would be .test, .oclass and .test, .tclass

Resources