CSS :not for selector on the same level - css

I have this html, sometimes stars--done is not there but I want to alter the CSS.
<div class="stars stars--done">
<i></i>
<i></i>
<i></i>
<i></i>
<i></i>
</div>
Currently I have this
.stars {
&:hover {
i {
//do somehting
}
}
}
I only want to make the <i> do something if the parent does not match .stars--done
.stars {
&:not('.stars--done'):hover {
i {
//do somehting
}
}
}

.stars {
&:not('.stars--done'):hover {
i {
…
This will compile to
.stars:not('.stars--done'):hover i { …
which is not what you want. Remove the quotes:
.stars {
&:not(.stars--done):hover {
i {
…

Dont stringify the selector, this is not Jquery. Simply remove the ''.
.stars {
&:not(.stars--done):hover {
i {
//do somehting
}
}
}
Ps you can also write:
.stars {
&:hover:not(.stars--done) {
i {
//do somehting
}
}
}

Related

Less multiple classes rules using parent selector

I have the following HTML structure:
<div class="block">
<div class="block--is-disabled block--is-focused">Block</div>
</div>
And some LESS code:
// LESS
.block {
&--is-disabled {
// some styles
}
&--is-focused {
// some styles
}
}
Is it possible to apply styles like .block--is-disabled.block--is-focused using LESS parent selectors? The only thing I've reached is:
// LESS
.block {
&--is-focused & {
&--is-disabled {
// some styles
}
}
}
With the following CSS output:
.block--is-focused .block--is-disabled {
// some styles
}
But what I need to get is the next CSS:
.block--is-disabled.block--is-focused {
// some styles
}
You can do it like this:
.block {
&--is-focused&--is-disabled {
...
}
}

Sass: Proper way to nest element within modifier with the same block name?

The HTML (which I am unable to alter) looks like:
<div class="cta">
<div class="cta--red">
<div class="cta__inner">
</div>
</div>
</div>
I need to target the content within this - specific to the red, inner cta.
I can do this with:
.cta {
&--red{
.cta {
&__inner {
}
}
}
}
But is there a cleaner way of writing this? (note: my company insists on having each element and modifier on a line break)
I seem to recall something like:
.cta {
&--red & {
&__inner {
}
}
}
but can't quite remember what it's called.
The desired CSS output is: .cta--red .cta-inner {}
You can cache the parent selector:
.cta {
$this: &;
&--red {
// -> .cta--red
& #{$this}__inner {
// -> .cta--red .cta__inner
}
}
}
A more clean option, in my opinion:
.cta {
// -> .cta
.cta--red {
// -> .cta .cta--red
.cta__inner {
// -> .cta .cta--red .cta__inner
}
}
}
Did you try?
.cta {
&--red {
}
&__inner {
}
}

Use unknown values as selectors in Less

Given this markup:
<div class="parent" data-active="typeA">
<div class="child" data-show="typeA">Show only when parent=typeA</div>
<div class="child" data-show="typeB">Show only when parent=typeB</div>
<div class="child" data-show="typeC">Show only when parent=typeC</div>
</div>
I'm trying to write a globally applicable LESS rule that only displays a child when its data-show attribute matches the parent's data-active attribute.
Something like this:
.parent {
.child { display:none; }
&[data-active="?"] .child[data-show="?"] { display:block; }
}
...where ? should not be a fixed value, but a condition that applies no matter the value, as long as they are the same.
Any ideas?
As LESS gets compiled to CSS and there is no generic approach for doing this in CSS, I only come up with a solution that requires you to know every possible type.
.parent {
.child { display: none; }
&[data-active="typeA"] {
.child[data-show="typeA"] { display: block; }
}
&[data-active="typeB"] {
.child[data-show="typeB"] { display: block; }
}
&[data-active="typeC"] {
.child[data-show="typeC"] { display: block; }
}
}
Depending on your preferences and to avoid redundancy you could also define a function for adding the different types.
.parent {
.child { display: none; }
.addType("typeA");
.addType("typeB");
.addType("typeC");
}
.addType(#type) {
&[data-active="#{type}"] {
.child[data-show="#{type}"] { display: block; }
}
}
And if you want to make this even more generic, you could define an array of types and call .addType for each of the types like this:
#types: "typeA", "typeB", "typeC";
.parent {
.child { display: none; }
.-(#i: length(#types)) when (#i > 0) {
#type: extract(#types, #i);
.addType(#type);
.-((#i - 1));
} .-;
}
.addType(#type) { /* see above */ }

parent selector in less

Normally in less to reference a parent selector is:
.parent {
.grand-pa & {
/* this rules will apply to: .grand-pa .parent {....}
background: grey;
}
}
What I'm trying to do is something similar. example code HTML:
<div class="panel panel-parent">
<div class="panel-child">
{{content}}
</div>
</div>
Less code:
.panel {
.panel-child {
// some rules
&.panel-parent & { //<=== IS IT POSSIBILE SOMETHING LIKE THIS??
// .panel.panel-parent .panel-child{...}
}
}
}
The only solution I have found is to repeat .panel-child:
.panel {
&.panel-parent .panel-child { //<=== Workaround
// .panel.panel-parent .panel-child{...}
}
.panel-child {
// some rules
}
}
}
The order of classes of the same element does not actually matter, i.e. .panel.panel-parent is equal to .panel-parent.panel (both will match <div class="panel panel-parent">), thus you can get what you need with just:
.panel {
.panel-child {
a: a;
.panel-parent& {
b: b;
}
}
}
instead.

Multiple two-class selectors in Sass

Having multiple two-class selectors for a single declaration block, is it possible to simplify the following (i.e. not having to repeat the body tag):
body.shop, body.contact, body.about, body.faq {background-color:#fff;}
try this:
body{
&.shop, &.contact, &.about, &.faq {
background-color:#fff;
}
}
In this case we can use #each directive:
$pages: shop, contact, about, faq;
body {
#each $page in $pages {
&.#{$page} {
background-color:#FFF;
}
}
}
sassmeister.com
body {
&.shop, &.contact {
// Styles here...
}
}
If you are using sass compiled by the node, that may do.
body {
.shop, .contact, .about, .faq {
background-color:#FFFFFF;
}
}
Parent child relationship in sass
parent_tag {
.child {
// rules here
}
}

Resources