CSS: Selecting a group of parents - html

For the following generated HTML:
<div id="parent1">
<div class="child" />
</div>
<div id="parent2">
<div class="child" />
</div>
<div id="parent3">
<div class="child" />
</div>
I would like to select .child from #parent1 and #parent2 like:
#parent1 .child, #parent2 .child { Do stuff... }
However, this can become messy. Is it possible to select a group of parents like this?
(#parent1, #parent2) .child { Do stuff... }

Selectors L4 draft introduces :matches(). It allows you to do
:matches(#parent1, #parent2) .child
Note it's an experimental feature, and browsers haven't implemented it yet. However, some support :-moz-any or :-webkit-any, which behave like :matches.
:-moz-any(#parent1, #parent2) .child {
color: blue;
}
:-webkit-any(#parent1, #parent2) .child {
color: blue;
}
:matches(#parent1, #parent2) .child {
color: blue;
}
<div id="parent1">
<div class="child">Child</div>
</div>
<div id="parent2">
<div class="child">Child</div>
</div>
<div id="parent3">
<div class="child">Child</div>
</div>

In this case you can use the [attribute^=value] (begin with) or [attribute*=value] (contain) syntax.
HTML:
<div id="parent1">
<div class="child">child</div>
</div>
<div id="parent2">
<div class="child">child</div>
</div>
<div id="anotherParent">
<div class="child">child</div>
</div>
CSS:
[id^=parent] .child {
color: red;
}
DEMO: https://jsfiddle.net/lmgonzalves/eh5saf1k/
But I think it's better to asign the same class simply.

What you're looking for is nesting, and you'll need to use SASS or SCSS for that: http://jsfiddle.net/soy3tdmy/
#parent1, #parent2 {
.child {
color: red;
text-decoration: underline;
}
}

Related

How to reposition HTML element to a different part of hierarchy based on the breakpoint?

This is some html and css that uses flexbox to position an element (colored in yellow). In a large breakpoint it appears in one place but in a small breakpoint it needs to be in a different part of the hierarchy. So it's not as simple as just repositioning its order but actually moving it to a different place.
How can I do this using just CSS and flexbox? If that's not possible then I could use CSS grid. Would prefer not to have to use javascript unless there's no other way.
.one {
background-color: lightgray;
}
.two {
background-color: red;
}
.three {
background-color: blue;
}
.element {
background-color: yellow;
}
<h1>large breakpoint</h1>
<div>
<div style="display:flex">
<div class="one">
<div>one</div>
</div>
<div class="element">
possible position 1
</div>
<div class="two">two</div>
<div class="three">three</div>
</div>
</div>
<h1>small breakpoint</h1>
<div>
<div style="display:flex">
<div class="one">
<div>one</div>
</div>
<div class="two">two</div>
<div class="three">three</div>
</div>
<div class="element">
possible position 2
</div>
</div>
Pretty sure you can achieve what you want with the order property. Here's an example where an element is in a different order than the order in which it was declared.
You can set the order property in each breakpoint to match your needs.
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.item {
border: 0.025em solid black;
padding: 1em;
}
#special-item {
order: 3;
width: 100%;
background-color: yellow;
}
<h1>Large breakpoint</h1>
<div class="container">
<div class="item">One</div>
<div class="item">Two</div>
<div class="item">Three</div>
<div class="item">Four</div>
</div>
<h1>Small breakpoint</h1>
<div class="container">
<div class="item">One</div>
<div id="special-item" class="item">Two</div>
<div class="item">Three</div>
<div class="item">Four</div>
</div>

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>

CSS targetting last child container of class

Not sure this is possible with CSS only. Any help is appreciated.
My HTML looks like this:
<div class="row invoice with-tax">
<div class="mobile-body-header mobile"><strong>Items</strong></div>
<div class="invoice-item">
<div class="item-filler"></div>
<div class="quantity">2</div>
<div class="amount-mobile total">$13,336.60</div>
<div class="item-number">ABC123</div>
<div class="title"><span class="quantity-mobile">2 x </span>Dance classes and tutoring for upcoming Michael Jacksons</div>
<div class="amount-item-ex">$153.00</div>
<div class="amount-subtotal">$306.00</div>
<div class="amount-tax">$30.60</div>
<div class="amount-total total">$13,336.60</div>
<div class="item-filler"></div>
</div>
<div class="invoice-item">
<div class="item-filler"></div>
<div class="quantity">2</div>
<div class="amount-mobile total">$13,336.60</div>
<div class="item-number">ABC123</div>
<div class="title"><span class="quantity-mobile">2 x </span>Dance classes and tutoring for upcoming Michael Jacksons</div>
<div class="amount-item-ex">$153.00</div>
<div class="amount-subtotal">$306.00</div>
<div class="amount-tax">$30.60</div>
<div class="amount-total total">$13,336.60</div>
<div class="item-filler"></div>
</div>
....
</div>
I am trying to remove the border-bottom of the final div with class title in the last div with class invoice-item. These are essentially rows of div elements that can vary in numbers (as it is and invoice I am working on).
I have tried unsuccessfully the examples below. Although I can see it working in the Fiddle from #Steve below it is not removing the last border when placed inside the rest of the CSS. And I can confirm the border is set just above per the examples below.
div.invoice-item > div.title {
border-bottom: 2px dotted red;
}
div.invoice-item:last-child > div.title {
border: none !important;
}
also
div.invoice-item > div.title {
border-bottom: 2px dotted red;
}
div.invoice > div.invoice-item:last-child > div.title {
border: none !important;
}
also
div {
border-bottom: 1px solid red;
}
div.invoice-item:last-of-type > div.title {
border: none;
}
Since it's an e-mail template, there are some clients that doesn't support :last-child. Instead of using :last-child, try to add a new Class to the div that you want to select.
Try div.invoice-item:last-of-type > div.title { border: none; }
UPDATE
Since there's an unknown CSS evil, here's a trick that might work:
div.invoice-item:last-of-type > div.title.title { border: none !important; }
div {
border-bottom: 1px solid red;
}
/* div.invoice-item:last-of-type > div.title {
border: none;
} */
div.invoice-item:last-of-type > div.title.title {
border: none !important;
}
<div class="row invoice with-tax">
<div class="mobile-body-header mobile"><strong>Items</strong>
</div>
<div class="invoice-item">
<div class="item-filler"></div>
<div class="quantity">2</div>
<div class="amount-mobile total">$13,336.60</div>
<div class="item-number">ABC123</div>
<div class="title"><span class="quantity-mobile">2 x </span>Dance classes and tutoring for upcoming Michael Jacksons</div>
<div class="amount-item-ex">$153.00</div>
<div class="amount-subtotal">$306.00</div>
<div class="amount-tax">$30.60</div>
<div class="amount-total total">$13,336.60</div>
<div class="item-filler"></div>
</div>
<div class="invoice-item">
<div class="item-filler"></div>
<div class="quantity">2</div>
<div class="amount-mobile total">$13,336.60</div>
<div class="item-number">ABC123</div>
<div class="title"><span class="quantity-mobile">2 x </span>Dance classes and tutoring for upcoming Michael Jacksons</div>
<div class="amount-item-ex">$153.00</div>
<div class="amount-subtotal">$306.00</div>
<div class="amount-tax">$30.60</div>
<div class="amount-total total">$13,336.60</div>
<div class="item-filler"></div>
</div>
....
</div>

Expanding the classes - CSS/HTML convention

I have the simple table generated by js and I'd like to change some properties of columns and rows like background color, width statically. I can extend the row and col classes directly in CSS file or do it in html.
Example (CSS approach):
HTML:
<div class="table">
<div class="row">
<div class="col">
<div class="row">
<div class="foo"></div>
<div class="col"></div>
</div>
</div>
</div>
</div>
CSS:
...
.col, .foo {
display: table-row;
height: 20px; }
.foo { background: red; width: 100px; }
...
Example (html approach):
HTML:
<div class="table">
<div class="row">
<div class="col">
<div class="row">
<div class="col foo"></div>
<div class="col"></div>
</div>
</div>
</div>
</div>
CSS:
...
.col {
display: table-row;
height: 20px; }
.foo { background: red; width: 100px; }
...
In my opinion the second approach is more convenient for dynamically changing elements rather then static ones. However the first one obscures the structure of the html which can cause some problems with understanding the javascript. My question is which approach would be better in this case?