SCSS: Select where no parent has class - css

I have hit a use case where I would like to only apply styling to an element if none of its parents has a specific class.
<body>
<h2>I should have styles</h2>
<div class="myClass">
<h1>I should have styles</h1>
<h2>I should not have styles</h2>
<div>
<h2>I should not have styles</h2>
</div>
</div>
<div>
<h2>I should have styles</h2>
</div>
</body>
I have tried a few things, none of them pretty or functional.
*:not(.myClass) h2{
...
}
This clearly doesn't work because there will almost be a parent that doesn't have the class.
*:not(.myClass) > h2{
...
}
This is not better. It only targets the first parent of the element we want to style.
*:not(.myClass){
& > *:not(.myClass){
& > *:not(.myClass){
& > *:not(.myClass){
& > *:not(.myClass){
& > h2{
...
}
}
}
}
}
}
This will sort of work. It selects correctly if no parents in 5 levels has the class, but if the class is one parent further up, it breaks, and it is not the prettiest thing in the world.
But is there a simpler solution for "Apply this style if no parent has class X"?

It's hard to know exactly what the solution for you is without seeing more of your infrastructure, but there is a potential solution:
h2:not(.myClass *),
h1 {
color: red;
}
<body>
<h2>I should have styles</h2>
<div class="myClass">
<h1>I should have styles</h1>
<h2>I should not have styles</h2>
<div>
<h2>I should not have styles</h2>
</div>
</div>
<div>
<h2>I should have styles</h2>
</div>
</body>

Related

CSS selector, Match element that doesn't match given selector

I'm trying to match element that dose not match given selector using css.
Given the markup below, I'm trying to select only the first ".color"
<div uid="unique-id-1">
<div> <div class="color"></div> </div>
<div uid="unique-id-2">
<div class="color"></div>
</div>
</div>
I tried [uid="unique-id-1"] .color:not([uid="unique-id-1"] [uid] .color) which did not work obviously, but I think it will help to understand what I am looking for.
Thanks in advance!
If you're only going to apply the selector to this limited combination of elements (i.e. there aren't any other .colors in the page that could potentially be affected by this), then
[uid="unique-id-1"] > div:not([uid]) > .color
Do consider renaming the attribute to data-uid if your application allows, so as to make it clearer that this is an app-specific and non-standard uid attribute.
That seems simple:
[uid="unique-id-1"]>:first-child .color {
color: red;
}
<div uid="unique-id-1">
<div>
<div class="color">A</div>
</div>
<div uid="unique-id-2">
<div class="color">B</div>
</div>
</div>
That being said, uid as an attribute name makes your HTML invalid, so you should rename that to data-uid:
[data-uid="unique-id-1"]>:first-child .color {
color: red;
}
<div data-uid="unique-id-1">
<div>
<div class="color">A</div>
</div>
<div data-uid="unique-id-2">
<div class="color">B</div>
</div>
</div>

How to select all a elements from a p class?

How can I select all a elements inside a p element that have a specific class name?
<div>
<p class="myClass">
This is
<div>
random
</div>
</p>
</div>
Remove the div inside the p tag:
<div>
<p class="myClass">
random
</p>
</div>
Then if you want to select all the a tags inside a p tag which you gave a class. You can do the following:
.myClass a {
}
May be you aren't able to target anchor tag(s) due to that div. Do you need that div before the anchor tag? Please refer to the code snippet below:
.myClass a {
color: green;
}
<div>
<p class="myClass">
This is
random
</p>
</div>
div *[href]
{
// css rules...
}
<div>
<p class="myClass"> This is
<div>
random
</div>
</p>
</div>
you can give a specific class name to a and call it like:
<a class="myA's" href="#">random</a>
CSS
a.myA's{
#do something
}
And in your case it should be:
.myClass > a{
#doSmthg
}
<p> can only contain inline elements,See here.
so,remove div inside p:
p.myClass a {
color: red;
}
<div>
<p class="myClass">
This is<br>
random
</p>
</div>
You need to change the <p> to <div> then use this
.myClass > div a { ... }`
or remove <div> inside the <p> and try this
p.myClass a { ... }

Checking if data attribute is set at parent div css / less and using it for the child divs as well

I have div tag for which a data-type attribute is associated. I want to apply different styles depending on data-type is set or no.
<div data-type="type1">Hello, World!</div>
Can I check if this attribute data-type is set or no in css/less ? This question is solved with this.
But, if I apply this data-type attribute only to the parent div, can I use this attribute for all the child div tags as well.
For instance,
<div data-type=`type1`>
<div id="newDiv"> </div>
</div>
In my CSS, I want to apply different styles for #newDiv depending on whatever type (data-type) is set to its parent. I don't want to specify the data-type attribute to the child div as well. How do we do this in CSS ?
You can use :not([data-type]) to select any element that does not have the attribute data-type set regardless of the values used.
Basic working example:
div:not([data-type]) {
color: red;
}
<div data-type="type1">Hello, World!</div>
<div>Hello, World!</div>
Alternatively, you can do the opposite and use [data-type] to select anything with the data-type attribute set regardless of the value
Working example:
div[data-type] {
color: red;
}
<div data-type="type1">Hello, World!</div>
<div>Hello, World!</div>
If you want to target a child div whose parent div has the data-type attribute set the you can use something like this:
div[data-type]>h1 {
color: red;
}
<div data-type="type1">Hello, World!
<h1> How are you?!</h1>
</div>
<hr>
<div>Hello, World!
<h1> How are you?!</h1>
</div>
This also can be reveresed based on your selector preference to target the child elements of parent elements which do not have the data-type attribute set.
div:not([data-type])>h1 {
color: red;
}
<div data-type="type1">Hello, World!
<h1> How are you?!</h1>
</div>
<hr>
<div>Hello, World!
<h1> How are you?!</h1>
</div>
If you have more complex structures you can make use of the wildcard * selector to build selectors that match very broad patterns. The letters represent the depth of the tree on which the element resides with aaa being a direct child and bbb being a grandchild...etc
Basic Example:
[data-type] * h1,
[data-type] h1 {
color: red;
}
<div data-type="type1">
<h1> aaa</h1>
</div>
<hr>
<div>
<h1> aaa</h1>
</div>
<hr>
<div id="test" data-type="type1">
<div>
<h1> bbb</h1>
<div>
<h1> ccc</h1>
</div>
</div>
<h1 class="wow"> aaa</h1>
<div>
<h1 class="wow"> bbb</h1>
</div>
</div>
<hr>
<div id="test">
<h1 class="wow"> aaa</h1>
<div>
<div>
<h1> ddd</h1>
</div>
<h1 class="wow"> ccc</h1>
</div>
</div>
If you find a pattern in your data-type value, yes, you can:
/* 1. Attribute value starts with "type" */
div[data-type^="type"] {
/* Styles */
}
/* 2. Attribute value contains "type" */
div[data-type*="type"] {
/* Styles */
}
Works for: type1, typex, typeaskdasd, etc...
Works for: abctypexyz, typexyz, etc...

How can I style .class-0, .class-1, .class-2 with a common selector?

I want to style the following CSS classes; is there any short styling technique for this?
.test-0 { }
.test-2 { }
.test-3 { }
/* etc. */
I am looking for something like:
.test-%d% { }
I want to dynamically create many test-* classes with different numbers and common styles.
Update
here is my actual situation
<input type="button" value="click" class="button_class" />
<h1 class="ui-widget-header">Question - 1 </h1>
<div class="ui-widget-content">
<div id="form_container-0">
<div class="placeholder">Add your form fields here</div>
<div style="clear: both;"></div>
</div>
</div>
When user click the above button then same structure will clone and append to the end of the form
so the form will be as
<h1 class="ui-widget-header">Question - 1 </h1>
<div class="ui-widget-content">
<div id="form_container-0">
<div class="placeholder">Add your form fields here</div>
</div>
<div id="form_container-1">
<div class="placeholder">Add your form fields here</div>
</div>
</div>
the css class form_container-[%d] will be created dynamically by jquery.
so i want to add style to this class.
also it would be great if you share optimised code for cloning the structure with
different ID.
Please do let me know if you still have doubt.
thanks
You can use an attribute selector.
div[class*='test-'] {...}
I think #Ed W have the right solution BUT I have an extra idea while is not straight forward is shorter than what you have. And will help to make different testing that is waht I think you want... fiddel http://jsfiddle.net/ncubica/2sj9W/
css
.test-1,
.test-2,
.test-3,
.test-4,
.test-5{
color:#F60;
display:block;
}
.test-5{
color:blue
}
html
<span class="test-1">One</span>
<span class="test-2">Two</span>
<span class="test-3">Three</span>
<span class="test-4">Four</span>
<span class="test-5">Five</span>
span five will be in blue color... so you can override the class you want to test and play with it.
Also you can use selectors like
HTML
<div>
<span>I'm pink</span>
<span>I'm pink</span>
<span>I'm pink</span>
<span>I'm pink</span>
<span class="test-1">I'm red</span>
</div>
CSS
div > span{
color:pink;
display:block;
}
div > span.test-1{
color:red;
}
and the last span will be red. I hope this help.
My two cents...

Select multiple DIVs based in ID , excluding mutiple child DIVs

I need help selecting the following DIVs based on IDs but excluding some of the children DIVs in two different types of pages using a single style.css file:
PAGE1:
...
<div id="main">
<div id="post"> selected </div>
</div>
...
PAGE2:
...
<div id="main">
<div id="maincontent"> selected </div>
<div id="singlepost">
<div id="post"> selected </div>
<div id="comments"> excluded </div>
</div>
<div id="sidebar"> excluded </div>
</div>
....
I have tried with:
#main > :not(#sidebar), #singlepost > :not(#comments) a {
color: rgb(88, 134, 76) !important;
}
(!important overrides some inline CSS I cannot change)
The result is bad because Chrome only recognizes #main > :not(#sidebar), and ignores #singlepost > :not(#comments) a, thus turning all text into this color, not just links, and only excluding <div id="sidebar">, not <div id="comments?>.
I also tried:
#singlepost > :not(#comments) a {
color: rgb(88, 134, 76) !important;
}
#main > :not(#sidebar) a {
color: rgb(88, 134, 76) !important;
}
Now everything works as intended but <div id="comments"> is not excluded.
Please help,
Dan
Try to overwrite your style for #comments using !important for a certain property.
You can use the class name:
<div id="main">
<div id="maincontent" class="selected"> selected </div>
<div id="singlepost" class="selected">
<div id="post" class="selected-items"> selected </div>
<div id="comments" class="notSeleted-item"> excluded </div>
</div>
<div id="sidebar" class="notSelected"> excluded </div>
</div>
you would use the class, like this:
.selected {/*your style*/}
.selected-item a{/*your style*/}
Can't you just do
#maincontent, #post {
color: rgb(88, 134, 76);
}
example
Since you're using ids.
Another way would be to create a class for them. example

Resources