testing two classes don't exist with less css - css

I have an element lets say it could have .foo or .bar or both or none as a class:
<div class="foo bar">green</div>
<div class="foo">green</div>
<div class="bar">green</div>
<div class="something-else">red</div>
How can I test that the element doesn't have either class.
I tried something like this, but it doesn't work as expected:
div {
background: green;
&:not(.foo) and &:not(.bar) {
background: red;
}
}
I don't see many examples using less and not(), only 1 in their docs.

To say not to multiple conditions in a CSS selector, you need to chain them together: div:not(.foo):not(.bar)
div {
background: green;
&:not(.foo):not(.bar) {
background: red;
}
}

I was able to do it by nesting two &:not() rules, but I'm not sure this is the best way.
div {
background: green;
&:not(.foo) {
&:not(.bar) {
background: red;
}
}
}

There is always the pure css alternative.
div { background: red; }
div.foo, div.bar { background: green; }

Related

What does `&#my-id` mean in CSS or SASS?

I inherited some CSS code, which is making use of the & character prior to the id name to style it. It looks something like this:
&#my-id {
// Content and attributes
}
There are also other instances of it, such as:
&:before {
// content and attributes
}
and
&:hover {
// content and attributes
}
What do those mean? I can't find a good way to express this in a search, so I can't find anything. My apologies if this is a duplicate.
It refers to the parent selector.
Input:
.parent {
&.child {
color: red;
}
}
Output:
.parent.child { color: red }
It's really helpful if you're writing CSS in BEM format, something like:
.block {
&__element {
width: 100px;
height: 100px;
&--modifier {
width: 200px;
}
}
}
.block__element { width: 100px; height: 100px;}
.block__element--modifier { width: 200px;}
<div class="block__element"></div>
<div class="block__element block__element--modifier"></div>
And finally, all examples I've shared have been concatenating the class names, but you can also use it as a reference, like:
.parent {
& .child {
color: red;
}
}
.parent {
.child & {
color: blue;
}
}
.parent .child { color: red }
.child .parent { color: blue }
Additional references:
http://lesscss.org/features/#parent-selectors-feature
https://blog.slaks.net/2013-09-29/less-css-secrets-of-the-ampersand/
Using the ampersand (SASS parent selector) inside nested selectors
It's a built-in feature of Sass: https://css-tricks.com/the-sass-ampersand/
You can use it when you're nesting selectors and you need a more specific selector, like an element that has both of two classes:
If your CSS looks like this:
.some-class.another-class { }
And you wanted to nest, the Sass equivalent is:
.some-class {
&.another-class {}
}

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

RegEx simple parser of css selectors

I want to add scope to my selectors.
A good way to achieve it in my opinion is to select css selector and return mySelector + oldSelector
For example I have .old { background: black; }, I would transform it into .mySelector .old { background: black; }
Let's say I have this CSS
.a
{
background: red;
}
#b {
background: green;
}
input {
background: blue;
}
[type=custom] {
background: white;
}
I would do .+?{, but it selects not needed parts. Inverse of {.+?} would work, but I don't know how to inverse it. Any ideas ?
I figured out I can use String.match({.+?}) to get all rules and String.split({.+?}) to get selectors in JavaScript.
Also I've found a library to easily parse CSS in JavaScript https://github.com/reworkcss/css

LESS: Extend a previously defined nested selector

I've been trying like a mad man to get the following LESS statement to work, but now i am fearing that it's not gonna happen :/ So I am turning now to you guys in the end for help!
I have the following statement:
.top{
&-first{
background:black;
&-item{
color:white;
}
}
&-second{
background:green;
&-item:extend(.top-first-item){}
}
}
I was hoping for to achive the following output:
.top-first {
background: black;
}
.top-first-item,
.top-second-item{
color: white;
}
.top-second {
background: green;
}
But unfortunately it does not compile that but this instead:
.top-first {
background: black;
}
.top-first-item{
color: white;
}
.top-second {
background: green;
}
LESS currently does not support extending a "concatenated name" selectors (basically, .top &-first &-item is interpreted as three distinct selector elements and never found by extend looking for a single selector).
A workaround for your particular case:
.top {
&-first {
background: black;
}
&-second {
background: green;
}
&-first, &-second {
&-item {
color: white;
}
}
}
Another option is to break the designations into separate classes:
LESS
.top{
&.first{
background:black;
&.item{
color:white;
}
}
&.second{
background:green;
&.item:extend(.top.first.item){}
}
}
CSS Output
.top.first {
background: black;
}
.top.first.item,
.top.second.item {
color: white;
}
.top.second {
background: green;
}
Which of course requires a change in your html designation from class="top-first-item" to class="top first item".
This is obviously something that should be working in LESS. I have a few months ago put an issue on the LESS.js github regarding exactly this.
Link to Github issue
In the mean time, i recommend using seven-phases-max's solution by simply putting the classes together like so:
&-first, &-second {}
But then you cant abstract the second out into another file.
Another solution would to make an "extends.less" file, in which you can have small snippets you find your self using time from time.
Just use 'all' suffix. Example: &:extend(.top-first-item all);

CSS Selectors (or statement, containers, separator, etc)

Are there containers for CSS Selectors?
I'm simply curious if there's a more elegant way to do this without repeating the class:
#div1 .divClass, #div2 .divClass { color:cyan; }
This is what I had in mind, but I don't think there's a way to do it.
#div1,#div2 > .divClass { }
[#div1,#div2] .divClass { }
Short answer: No.
It seems a case where you can add a class for both divs.
<div id="div1" class="sharedClass"></div>
<div id="div2" class="sharedClass"></div>
.sharedClass > .divClass { color: cyan; }
Anyway, this question can have multiple answers. Consider looking at LESS, which extends CSS capabilities. Then you could do something awesome like this:
.divClass {
/* ... */
}
#div1 {
color: red;
border: 1px solid blue;
.divClass;
}
#div2 {
color: cyan;
border: 1px solid green;
.divClass;
}
Sounds like you're looking for a something like LESS, which is a stylesheet language which can be compiled into ordinary CSS. It might not do exactly what you're after in your specific case (but then again, it might, I haven't tried) but it sounds like it would be useful to you.

Resources