How to not display ::after content if one child in parent?
There is no CSS way (today, but with a parent selector it might some day) to remove the pseudo based on the amount of flex items, even if it is a child and act as a flex item, it still can't be explicit targeted with anything else than through its parent.
A simple workaround would be to use a left margin combined with transform
when there is only 1 element, here using the only-child
selector.
One could use position: relative; left: 50%
as well, though margin-left
is one line less
This will work with any number of elements, regardless their size.
Stack snippet
.main {
background: #999;
margin: 0 auto;
width: 500px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.box {
background: #7ab9d7;
color: #555;
height: 30px;
width: 30%;
margin-bottom: 30px;
text-align: center;
font-size: 30px;
padding-top: 120px;
}
.main::after {
height: 0;
width: 30%;
content: "";
}
.main div:only-child { /* added rule */
margin-left: 50%;
transform: translateX(-50%);
}
<div class="main">
<div class="box">1</div>
</div>
<br>
<div class="main">
<div class="box">1</div>
<div class="box">1</div>
</div>
<br>
<div class="main">
<div class="box">1</div>
<div class="box">1</div>
<div class="box">1</div>
<div class="box">1</div>
</div>
<br>
Updated based on a comment, where, if there is 2 items, they as well should be centered.
To be able to accomplish that with the existing markup/CSS, we also need to make use of the ::before
pseudo.
With a couple of clever CSS selectors, we can count if there is 1 or 2 elements.
This work like that, when 1 or 2 items, auto margin is used, and with the order
property the items are positioned after the ::after
, which now is 100% wide and will push the items to a new row, and there they will not be affected by either pseudo.
For 3 items or more, they will positioned before both pseudo's, where the ::before
now will act as the ::after
did in the initial solution, and left align items on the last row.
Fiddle demo
Stack snippet
.main {
background: #999;
margin: 0 auto;
width: 500px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.box {
background: #7ab9d7;
color: #555;
height: 30px;
width: 30%;
margin-bottom: 30px;
text-align: center;
font-size: 30px;
padding-top: 120px;
}
.main::before {
height: 0;
width: 30%;
content: "";
order: 1;
}
.main::after {
height: 0;
width: 100%;
content: "";
order: 2;
}
/* new rules */
.main div:only-child, /* if 1 only */
.main div:first-child:nth-last-child(2) + div { /* if 2, the 2nd*/
order: 3;
margin-left: auto;
margin-right: auto;
}
.main div:first-child:nth-last-child(2) { /* if 2, the 1st */
order: 3;
margin-left: auto;
}
<div class="main">
<div class="box">1</div>
</div>
<br>
<div class="main">
<div class="box">1</div>
<div class="box">2</div>
</div>
<br>
<div class="main">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
</div>
<br>
<div class="main">
<div class="box">1</div>
<div class="box">2</div>
<div class="box">3</div>
<div class="box">4</div>
<div class="box">5</div>
</div>