Hide all except first child of an element using pure css - html

I am trying to hide every other child after first child of classa class element.
div.classa {
display:none;
}
div.classa:first-child {
display:block !important;
}
<div class="content">
<h3>abc</h3>
<div class="classa">some content</div>
<h3>xyz</h3>
<div class="classa">more content</div>
<h3>header3</h3>
<div class="classa">another content</div>
</div>
How to achieve this using pure css.

Check out here https://jsfiddle.net/32vw04jg/1/
<div class="content">
<div>
<h3>abc</h3>
<div class="classa">some content</div>
</div>
<div>
<h3>xyz</h3>
<div class="classa">more content</div>
</div>
<div>
<h3>header3</h3>
<div class="classa">another content</div>
</div>
</div>
.content > div:not(:first-child) {
display: none;
}

If you want to support IE8, then your only option is general sibling selector:
div.classa ~ .classa {
display: none;
}
<div class="content">
<h3>abc</h3>
<div class="classa">some content</div>
<h3>xyz</h3>
<div class="classa">more content</div>
<h3>header3</h3>
<div class="classa">another content</div>
</div>

The problem in your code is that you want to hide the first .classa, but the first .classa isn't the first child in .content, the h3 is the first child.
So as an alternative to the :not() pseudo class, you could use nth-of-type(n+2). It will select all elements with the same type, except the first one.
div.classa:nth-of-type(n+2) {
display:none;
}
<div class="content">
<h3>abc</h3>
<div class="classa">some content</div>
<h3>xyz</h3>
<div class="classa">more content</div>
<h3>header3</h3>
<div class="classa">another content</div>
</div>

You can do it like that:
<div class="content">
<h3>abc</h3>
<div class="classa">some content1</div>
<h3>xyz</h3>
<div class="classa">more content2</div>
<h3>header3</h3>
<div class="classa">another content3</div>
</div>
Css:
.content > .classa:not(:nth-of-type(2)) {
display:none;
}

If I can understand correctly the question the goal here is to hide every child (h3 and div.classa) with the exception of the first h3 and the div.classa next to it.
The easiest way to accomplish it is a combination of the :first-of-type and the ~ (general siblings) selectors.
div.classa:first-of-type ~ * { display:none; }
<div class="content">
<h3>abc</h3>
<div class="classa">some content</div>
<h3>xyz</h3>
<div class="classa">more content</div>
<h3>header3</h3>
<div class="classa">another content</div>
</div>

You can try the :not pseudo class — https://developer.mozilla.org/en-US/docs/Web/CSS/:not
See this answer

There is new CSS3's :first-of-type for your case:
Demo
.content h3, .content div{
display:none;
}
.content .classa:first-of-type{
display : block;
}

.content > *{ display: none;}
.content > *:first-child{ display: block !important; }

Related

Not adding a css property to a last child inside a nested div- CSS

I want to add certain property to a specific <div>, here's my structure:
<div class="container">
<div class="parent">
<div class="child1">
<div class="child2">
</div>
<div class="parent">
<div class="child1">
<div class="child2">
</div>
<div class="parent">
<div class="child1">
</div>
</div>
Now I'm trying to apply css border property on class="child1" except for the last div that has only class="child1". I tried:
.container {
& > div.child1:not(:last-child) {
border-right: none;
}
}
But this doesn't work. Any ideas around?
.container .parent:not(:last-child) .child1{
border-right: none;
}
You should select the last parent and in your case you're using ">" which selects a direct child of the container
Your selector is wrong. You do not need the first > as the child divs are not DIRECT children of the container
.container {
width: 80%;
}
.container .child1:not(:last-child) {
border-right: 3px solid red;
}
.parent {
margin-bottom: 1em;
<div class="container">
<div class="parent">
<div class="child1">Child 1</div>
<div class="child2">Child 2</div>
</div>
<div class="parent">
<div class="child1">Child 1</div>
<div class="child2">Child 2</div>
</div>
<div class="parent">
<div class="child1">Child 1</div>
</div>
</div>
Answer:
You're trying to tell CSS to:
find parents which have multiple children
then find specific child in each of these parent(s)
As of 2020, this is not supported by pure CSS, and the answer is ironically from 2009. Read this, this, and this.
Other Workarounds:
A) By jQuery (or similar solution by JS)
// Find all parents
$('.parent').each(function() {
// Find all children of this parent
var $children = $(this).find('div[class^="child"]');
if($children.length > 1) {// if has 2 or more children
$children.css('borderRight', 'none');
// -- or --
$children.addClass('my_child_no_border_class');
} else {// Has 1 or 0 children
$children.css('borderRight', '1px solid red');
// -- or --
$children.addClass('my_child_border_class');
}
});
If you prefer adding classes, make sure to create CSS classes .my_child_border_class and .my_child_no_border_class
B) By HTML & CSS
Add special classes for children with border and no border:
<!-- HTML -->
<div class="container">
<div class="parent">
<div class="child1 noborder">
<div class="child2">
</div>
<div class="parent">
<div class="child1 noborder">
<div class="child2">
</div>
<div class="parent">
<div class="child1 withborder">
</div>
</div>
<!-- CSS -->
.noborder {
border-right: none;
}
.withborder {
border-right: 1px solid red;
}
C) By CSS
/* All child1 get this css */
.parent > child1 {
border-right: none;
}
/* then we override last parent's child1 with different css */
.parent:last-child > child1 {
border-right: 1px solid red;
}
Conclusion:
There might be other workarounds, but not pure CSS solution.
You can target the last parent and child1 like this.
.parent {
padding: 1rem;
background-color: deepskyblue;
}
.child1 {
height: 3rem;
background-color: aqua;
}
.parent:last-child > .child1 {
background-color: lime;
}
<div class="container">
<div class="parent">
<div class="child1"></div>
<div class="child2"></div>
</div>
<div class="parent">
<div class="child1"></div>
<div class="child2"></div>
</div>
<div class="parent">
<div class="child1"></div>
</div>
</div>
you can add a nother class to the last div or an id so you can target it as follow:
<div class="container">
<div class="parent">
<div class="child1"></div>
<div class="child2"></div>
</div>
<div class="parent">
<div class="child1"></div>
<div class="child2"></div>
</div>
<div class="parent">
<div class="child1 last-child" id="child"></div>
</div>
</div>
and css property as follow:
.last-child {
border-right: none;
}

How to select last div in a container div?

I would like to select with CSS and apply some background color ONLY on the row number 3.
But I have a limitation that I cannot use a css selector which select using a class name.
Could you please point me out to solve this issue? Thanks!
<div class="root">
<div class="row">1
</div>
<div class="row">2
</div>
<div class="row">3
</div>
</div>
You can use
.root>div:last-child {
background: green;
}
<div class="root">
<div class="row">1
</div>
<div class="row">2
</div>
<div class="row">3
</div>
</div>
Use
.root div:last-child {
background: red;
}
.root div:nth-child(1) {
color:red;
}
<div class="root">
<div class="row">1
</div>
<div class="row">2
</div>
<div class="row">3
</div>
</div>
If you plan to select row 3, and decide to add more rows you can use nth-child(3)
div.root:last-child will select every children.
Try this Instead:
div.root div:last-child{
background: green;
}
You can do it in different ways:
.root div.row:last-child {
background:red;
}
.root div.row:last-of-type {
background: green;
}
.root div.row:nth-last-child(1) {
background: yellow;
}
<div class="root">
<div class="row">1
</div>
<div class="row">2
</div>
<div class="row">3
</div>
</div>

Is it possible to select a specific <div> when another <div> which is not a parent is :hover in CSS3 only?

Is it possible to select a specific <div> when another <div> which is not a parent is :hover?
All that in HTML5/CSS3 only, without JS.
<section>
<div id=first></div>
</section>
<section>
<div class=second></div>
</section>
As an example, i want <div class=second> to show when <div id=first> is :hover.
This is possible, but only if the two elements have the same parent.
Using the element1 ~ element2 selector. For example:
HTML:
<div class="first">
<!-- content -->
</div>
<span class="example-element"></span>
<div class="second">
<!-- content -->
</div>
CSS:
.first:hover ~ .second {
/* styles */
}
If you need to select an element that does not have the same parent, you need to use javascript.
this is two ways to achive that, with click adding an a tag or with hover that its a little tricky
.second{
display:none;
}
#second:target {
display:block;
}
#first a{
text-decoration:none;
color:black;
}
.disp1:hover + .disp2{
display:block;
}
.disp2{
display:none;
}
<section>
<div id="first"><a href="#second" >div one</a></div>
</section>
<section>
<div id="second" class="second">div two</div>
</section>
<div class="disp1">first div</div>
<div class="disp1 disp2">second div</div>

First-child and last-child in separate containers

Can I apply the first-child and last-child pseudo elements to the divs with the same class that are in different sub-containers? In the example below, div with the classes "box selected" are all stored under "1st-container", but there are 2 additional containers on the way:
<div class="1st-container">
<div class="2nd-container">
<div class="3rd-container">
<div class="box selected"> // this div should have first-child pseudo elements
<div class="box">
</div>
</div>
<div class="2nd-container">
<div class="3rd-container">
<div class="box selected">
<div class="box">
<div class="box">
<div class="box">
</div>
</div>
<div class="2nd-container">
<div class="3rd-container">
<div class="box selected"> // this div should have last-child pseudo
<div class="box">
</div>
</div>
</div>
Is that doable with pure css?
You can't do what you've described, because in both cases, "box selected" is the first child of its parent. You could take a different approach, though. For example, you could target those two divs like so:
.2nd-container:first-child .selected,
.2nd-container:last-child .selected
{}
As pointed out, replace the 2 with a non-digit, as that won't work. I was distracted by the main question. :-)
Firstly, you cannot use numbers to start classes or id's.
Secondly, you just need to do a find on the first and last child of the second element in and you should be able to find the elements you need.
.box {
height: 20px;
width: 400px;
background: blue;
}
.box.selected {
background: red;
}
.two-container:first-child .box.selected,
.two-container:last-child .box.selected {
background: green;
}
<div class="one-container">
<div class="two-container">
<div class="three-container">
<div class="box selected">// this div should have first-child pseudo elements</div>
<div class="box"></div>
</div>
</div>
<div class="two-container">
<div class="three-container">
<div class="box selected"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
<div class="two-container">
<div class="three-container">
<div class="box selected">// this div should have last-child pseudo</div>
<div class="box"></div>
</div>
</div>
</div>
with JS it looks easier than CSS:
var selected = document.querySelectorAll('.one-container .box.selected');
selected[0].style.background = selected[selected.length-1].style.background='green';
FIDDLE

Selecting the last general sibling

I have a bunch of divs with class B following a div with class A:
<div class="B"></div>
<div class="A"></div>
<div class="A"></div>
<div class="A"></div>
<div class="B"></div>
<div class="A"></div>
I'm trying to apply a CSS rule to the last A after each B. I tried
.B ~ .A:last-of-type
but that didn't work. Is this possible?
You can't currently do this with css. The :last-of-type pseudo class works with element types such as span div etc - not with classes
Being that:
1) There is no currently no previous sibling selector
2) You can't change the structure of your markup and
3) You don't know in advance how many .A divs you have after each .B div ...
... you're out luck, CSS currently can't do this.
You can use :last-of-type selector in this case.
.A:last-of-type {
/*apply styling */
}
In your case I recommend you to group them in divs. http://jsfiddle.net/GtLWJ/
This works.
<div class="sec1">
<div class="head">Set</div>
<div class="sub">Item 1</div>
<div class="sub">Item 2</div>
<div class="sub">Item 3</div>
</div>
<div class="sec1">
<div class="head">Set</div>
<div class="sub">Item 1</div>
</div>
CSS:
.head {
font-weight: 800;
}
.sec1 .sub:last-of-type {
border-bottom: 1px solid #000;
}