css :target on children - css

Suppose we have this html
<div class="a">
<div>...</div>
...
<div id="b">xyz</div>
</div>
<div class="a">
<div>...</div>
...
<div id="c">abc</div>
</div>
Applying some style on #b upon targeting it in url is easy to do with the css :target selector.
Is it possible to apply some some style on the parent div with class="a" as well?

No, since you would need a CSS parent selector for that. Nothing in CSS2 and CSS3 has been specified for that. CSS4 does have (a somewhat) parent selector (called the subject selector) using the ! symbol, but no browser supports it (yet).

You can add an extra id to your <div class="a"> and make it:
<div class="a" id="abc">
...and still use the :target.

No, CSS cascades (CSS = Cascading Style Sheets), it doesn't go up.
You will need to explicitly apply styling to the parent element.
You would be better doing something like #otinanai suggested and adding a class to your child divs. e.g.
HTML
<div class="a">
<div>...</div>
...
<div class="aItem" id="b">xyz</div>
</div>
<div class="a">
<div>...</div>
...
<div class="aItem" id="c">abc</div>
</div>
CSS
.a {
border: 1px solid #000;
}
.aItem {
color: #999;
}
So you will use classes to consistently style your elements. Otherwise you will have to write CSS for D, E, F G through to Z, and only use the ID's for bookingmarking/URL purposes.

Related

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 do i style two same class divs differently?

So basically I've got a setup that spits out the code in the following fashion..
<div class="parent">
<div class="subparent">
<div class="TARGETCLASS"></div>
</div>
<div class="subparent">
<div class="TARGETCLASS"></div>
</div>
</div> //close for the parent class
Now what I'm trying to do is to style "TARGETCLASS" that comes above one way and the "TARGETCLASS" that comes second in another way. I tried n-th child, but unable to achieve the result I'm looking for. There's no way to add additional classes or ID to the existing "TARGETCLASS" class. Otherwise I wouldn't be posting this question :)
Also, the "subparent" class also is same. for both the targetclass classes. That's the issue
Thanks in advance for taking your time to answer this question for me.
Cheers!
Looks like you've got some mal-formed tags in your html. And nth-child should work just fine. Also, make sure you place the nth-child selector on the subparent class, and not TARGETCLASS. It's common to mis-place the child selector. Try this:
<div class="parent">
<div class="subparent">
<div class="TARGETCLASS">
first-child
</div>
</div>
<div class="subparent">
<div class="TARGETCLASS">
second-child
</div>
</div>
</div>
<style>
.parent .subparent .TARGETCLASS {
background-color:#f00;
}
.parent .subparent:nth-child(1) .TARGETCLASS {
background-color:#0f0;
}
</style>
fiddle: https://jsfiddle.net/8ejxokuj/
I would use nth-of-type selector like so:
.parent{}
.parent > .subparent {} //targets both subparents
.parent > .subparent:nth-of-type(2) {} //targets the second subparent
.parent > .subparent:nth-of-type(2) > .TARGETCLASS{} //targets the child of the second subparent
The nth-of-type() selector enables you to style a specific element amongst a series, in this case we targeted the second .subparent then specified the child we needed.
I hope this helps!
It seems, it is working by the nth child.
it is about how childrens are called. Not like "Ask parent to find nth child, but ask child, how far is he from parent"
.parent .subparent:nth-child(1) {background: #FEE; color:RED;}
.parent .subparent:nth-child(2) {background: #EEF; color:blue;}
<div class="parent">
<div class="subparent">
<div class="TARGETCLASS">aaa</div>
</div>
<div class="subparent">
<div class="TARGETCLASS">bbb</div>
</div>
//close for the parent class
</div>

CSS Select Sibling of An Element with A Specific Sub-Element?

The snippet below is a part of a much larger structure with many .step elements.
I need to match all .stepText elements that are next to .stepTitleAndImages ul.standard
In other words, match all .stepText elements that have .step parent that has .stepTitleAndImages child that has .stepImages.standard child
<div class="step">
<div class="stepTitleAndImages">
<h3 class="stepTitle"></h3>
<ul class="stepImages standard"></ul>
<div class="clearer"></div>
</div>
<div class="stepText "></div> **HOW TO SELECT ALL ELEMENTS LIKE THIS ONE?**
<div class="clearer"></div>
</div>
<div class="step">
<div class="stepTitleAndImages">
<h3 class="stepTitle"></h3>
<ul class="stepImages medium"></ul>
<div class="clearer"></div>
</div>
<div class="stepText "></div>
<div class="clearer"></div>
</div>
PS: I cannot modify the HTML. Cannot use anything other than pure CSS.
Just use this for selecting first case
.step:nth-child(1) .stepText {
... Your CSS here
}
For second one use
.step:nth-child(2) .stepText {
... Your CSS here
}
For selecting both use
.step .stepText {
... Your CSS here
}
Then you should require jquery for that
Selecting Parents sibling is not possible only with pure CSS yet, You can achieve this by a single line of jquery:
$('ul.standard').parent().siblings(".stepText").css(...your CSS here);
This cannot be done with your HTML structure and with pure CSS. The closest solution to your problem, changing the HTML structure and with pure CSS, would be to move the standard class to its parent tag:
<div class="stepTitleAndImages standard">
<h3 class="stepTitle"></h3>
<ul class="stepImages"></ul>
<div class="clearer"></div>
</div>
This would allow you to use the adjacent sibling selector (+), which matches the second selector if it's the direct next sibling of the first, like this:
.stepTitleAndImages.standard + .stepText {
/* Styles */
}
A more flexible approach would be to use the general sibling selector which would match any sibling preceded by the first selector, not only the direct next one:
.stepTitleAndImages.standard ~ .stepText {
/* Styles */
}
The :has pseudo-class is in development by Mozilla, but it hasn't hit any stable browsers yet. With it, and with your HTML structure, you could go:
.stepTitleAndImages:has(.standard) + .stepText {
/* Styles */
}
Unfortunately, currently you can't solve this in any other way with CSS (and with your HTML structure) only.

How to get different class selectors using nth-child in css

I have these codes
<div class="test">
<div class="tag1"></div>
<div class="tag1"></div>
<div class="tag1"></div>
<div class="tag2"></div>
<div class="tag2"></div>
<div class="tag2"></div>
</div>
Now I want to get second child of .tag2 selector.
I try this code and it's not working, but when I use .tag1 it's working.
.test .tag2:nth-child(2) {
background-color: #000;
}
How can i fix this?
:nth-child works on elements, not on other selectors. Here your .tag2 element is the 4th element in the list.
When browsers begin to implement the Selectors Level 4 standards we'll be able to achieve this using the :nth-match structural pseudo-class selector, but unfortunately that's quite a way off yet.
A Potential CSS Solution (Markup-dependant)
If your markup will always be that the first .tag2 will only ever follow .tag1 and the second .tag2 will only ever follow .tag2, you can fake it with this:
.tag1 + .tag2 + .tag2 {
background-color: #000;
}
This selects the .tag2 element which immediately follows a .tag2 element which immediately follows a .tag1 element.
A JavaScript Solution
If you can't do that then you'll have to go for a JavaScript solution instead (or implement something on the back-end which generates the content).
The below example pulls all .tag2 elements within your .test container, then grabs the 2nd one ([1] here, remember the 0 index: [1] = 2nd), then applies the style to that element.
You'll need to add in some checks to ensure this element exists before applying the style.
document.querySelector('.test').querySelectorAll('.tag2')[1].style.background = '#000'
<div class="test">
<div class="tag1">tag1</div>
<div class="tag1">tag1</div>
<div class="tag1">tag1</div>
<div class="tag2">tag2</div>
<div class="tag2">tag2</div>
<div class="tag2">tag2</div>
</div>
I know your question isn't tagged with JavaScript, but a good solution with JS is as follows:
var alltagtwos = document.getElementsByClassName("tag2");
alltagtwos[1].className += " secondel";
.tag2.secondel {
background-color: #000;
color: #fff;
}
<div class="test">
<div class="tag1">tag1 - 1</div>
<div class="tag1">tag1 - 2</div>
<div class="tag1">tag1 - 3</div>
<div class="tag2">tag2 - 1</div>
<div class="tag2">tag2 - 2</div>
<div class="tag2">tag2 - 3</div>
</div>
What I've done here is add all elements with the class .tag2 into an array-like object using getElementsByClassName. I then select the second element which has the class .tag2 (index starts at zero, so I've select [1]) and appended another class to it (.secondel) which I've then styled with CSS.

CSS first-child not working as expected

I am using the following CSS to try and remove the left-border on the first child div of any element with the class called, "tblRow"
.tblRow div:first-child{
border-left: none;
}
<div class="tbl">
<div class="tblRow">
<div class="tblCell">Lower limit QTY</div>
<div class="tblCell">Upper Limit</div>
<div class="tblCell">Discount</div>
</div>
<div class="tblRow">
<div class="tblCell">1</div>
<div class="tblCell">5</div>
<div class="tblCell">25%</div>
</div>
</div>
This only removes the left-border from the first child div in the first row. It does not remove it in the second row. Any ideas?
I generally only use the :first-child and :nth-child psuedo selectors when I have little or no control over the elements or they are populated dynamically where I cannot rely on an order. Additionally, since :nth-child is CSS3, you can't rely on complete browser compatibility. If you can do without this psuedo selector, my advise is to create a secondary class for this purpose.
.tblCell.firstCell{
border-left: none;
}
<div class="tbl">
<div class="tblRow">
<div class="tblCell firstCell">Lower limit QTY</div>
<div class="tblCell">Upper Limit</div>
<div class="tblCell">Discount</div>
</div>
<div class="tblRow">
<div class="tblCell firstCell">1</div>
<div class="tblCell">5</div>
<div class="tblCell">25%</div>
</div>
</div>
It seems to work on the fiddle, so you probably have a (hidden) text node somewhere there. Therefore I suggest using .tblRow div:first-of-type { ... }, if possible from browser support point-of-view.

Resources