只有一个子元素时删除伪元素 [英] Remove a pseudo-element when there is only one child element

查看:109
本文介绍了只有一个子元素时删除伪元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用占用容器最后一个槽的不可见伪元素( :: after )。但是如果只有一个元素,我想把它放在中心位置。

所以为了做到这一点,我需要在这种情况下删除伪元素。



如果有可能,我该怎么做?

.main {background:#999;保证金:0汽车;宽度:500px;显示:flex; flex-wrap:wrap; justify-content:space-between;}。box {background:#7ab9d7;颜色:#555; height:30px;宽度:30%; margin-bottom:30px; text-align:center; font-size:30px; padding-top:120px;}。main :: after {height:0;宽度:30%; content:;}

< div class =主> < div class =box> 1< / div>< / div>

PS 示例来自



如果一个div - 看起来像这样




如果父母中有一个孩子,内容如何不显示在内容之后


没有CSS方法(今天,但是有一天它可能有一个父选择器)根据flex项目的数量去除伪项,即使它是一个孩子,一个弹性项目,它仍然不能通过其他任何东西显式定位。






一个简单的解决方法是应该使用与 transform 当只有1个元素时,这里使用 only-child 选择器。

可以使用 position:relative;左:50%,但 margin-left 少一行



这将适用于任何数量的元素,无论其大小如何。

div class =snippetdata-lang =jsdata-hide =truedata-console =truedata-babel =false>

  .main {background:#999;保证金:0汽车;宽度:500px;显示:flex; flex-wrap:wrap; justify-content:space-between;}。box {background:#7ab9d7;颜色:#555; height:30px;宽度:30%; margin-bottom:30px; text-align:center; font-size:30px; padding-top:120px;}。main :: after {height:0;宽度:30%; content:;}。main div:only-child {/ *添加规则* / 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>






根据评论更新,其中如果有2个项目,则它们也应该居中。

为了能够用现有的标记/ CSS来完成,我们还需要使用 :: before pseudo。

用一对聪明的

这个工作就是这样的,当使用1或2个项目时,使用自动保证金,并使用顺序属性将项目放置在 :: after ,现在是100%宽,并将项目推到一个新的行,并在那里他们不会受到任何伪。



对于3项或更多,他们将定位在两个伪现在之前, :: before 现在将作为t他在最初的解决方案中做了 :: after ,并在最后一行保留了对齐项。

小提琴演示

Stack snippet



.main {background:#999;保证金:0汽车;宽度:500px;显示:flex; flex-wrap:wrap; justify-content:space-between;}。box {background:#7ab9d7;颜色:#555; height:30px;宽度:30%; margin-bottom:30px; text-align:center; font-size:30px; padding-top:120px;}。main :: before {height:0;宽度:30%;内容:; order:1;}。main :: after {height:0;宽度:100%;内容:; order:2;} / * new rules * /。main div:only-child,/ * if if only only * /。main div:first-child:nth-​​last-child(2)+ div {/ * if 2, 2nd * / order:3; margin-left:auto; (2){/ * if 2,the 1st * / order:3; margin-left:auto;}

< div class = 主 > < 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>

I use an invisible pseudo-element (::after) that occupies the last slot in the container. But if there is only one element, I'd like to position it in the center.

So in order to do it I need to "remove" the pseudo-element in that case.

How do I do it if it's possible?

.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: "";
}

<div class="main">
  <div class="box">1</div>
</div>

P.S. Example was taken from here but decreased number of children to 1.

P.S. P.S. If many divs - looks like this

If one div - looks like this

解决方案

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>

这篇关于只有一个子元素时删除伪元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆