在 CSS 中更改使用 ::before 和 ::after 创建的元素的顺序

Posted

技术标签:

【中文标题】在 CSS 中更改使用 ::before 和 ::after 创建的元素的顺序【英文标题】:Changing the order of elements created using ::before and ::after in CSS 【发布时间】:2021-12-30 08:07:45 【问题描述】:

我试图将我的问题简化为以下内容:

.wrapper 
  position: relative;
  display: inline-flex;
  min-height: 1.5rem;
  border: 1px solid black;
  margin-right: 1rem;
  padding-right: 1.5rem;


.input 
  position: absolute;
  z-index: -1;
  opactiy: 0;


.label-wrapper 
  margin-left: 2rem;


.label 
  position: relative;
  margin-bottom: 0;


 .label:before 
    position: absolute;
    top: 4px;
    left: -24px;
    display: block;
    width: 20px;
    height: 20px;
    pointer-events: none;
    content: "";
    background-color: #fff;
  

.label:after 
   position: absolute;
   top: 4px;
   left: -24px;
   display: block;
   height: 40px;
   content: "";
   background-repeat: no-repeat;
   background-position: center center;
   background-size: 50% 50%;
<div class="wrapper">
  <input class="input" type="checkbox"></input>
  <label class="label">
    <div class="label-wrapper">
      Option 1
    </div>  
  </label>
</div>

除此之外,我还有以下 CSS(在 StyledComponent 中),当用户单击 .input 中隐藏的 input 时,它会在复选框中添加一个“检查”:

  &[type="checkbox"]:checked ~ label::after 
    background-image: url("$checkboxImage");
    top: -2px;
    left: -29px;
    width: 30px;
    height: 30px;
  

这意味着它的行为应该像一个复选框 - 但是,我想交换我的元素,以便复选框位于文本的右侧而不是左侧,为此我尝试重新排序 input这样它就出现在label 之后,但随后隐藏的输入(处理实际点击行为与 CSS 复选框脱节?谁能指出我如何解决这个问题的方向?

总结: 使用:before & :after 创建一个可视复选框,但该复选框的逻辑实际上是由input 处理的(它是隐藏的) - 如何将可视输入和隐藏输入都移动到文本的右侧?

编辑:

【问题讨论】:

【参考方案1】:

您是否尝试更改元素的从左到右的默认位置? 如果是这种情况,您可以使用文本对齐或浮动。甚至是弹性盒。 另外,将文本放在 span 或其他内容中,以便您可以控制它。

如果我理解正确的话,有很多基于上下文的方法,比如使用绝对定位,或者在输入之前放置标签并关闭它。或类似的东西:

<label class="">
    <span class="">text</span>
    <input class="" type="checkbox" name="order">        
</label>

【讨论】:

基本上只是试图“交换”复选框和标签,以便复选框(和隐藏的输入)位于标签的右侧。【参考方案2】:

display: flexflex-direction: row-reverse 非常简单。

.label-wrapper 
  margin-left: 24px;
  margin-right: 0;
  flex-grow: 1; /* ADDED THIS */


.label 
  position: relative;
  margin-bottom: 0;
  display:flex;
  flex-direction: row;
  flex: 1; /* ADDED THIS */

.label.reverse
  flex-direction: row-reverse;

请看下面的片段:

.wrapper 
  position: relative;
  display: inline-flex;
  min-height: 1.5rem;
  border: 1px solid black;
  margin-right: 1rem;
  padding: 0.5rem;
  width: 200px;


.input 
  position: absolute;
  z-index: -1;
  visibility: hidden;


.label-wrapper 
  margin-left: 24px;
  margin-right: 0;
  flex-grow: 1;


.label.reverse > .label-wrapper 
  margin-left: 0;
  margin-right: 24px;


.label 
  position: relative;
  margin-bottom: 0;
  display:flex;
  flex-direction: row;
  flex: 1;


.label.reverse
  flex-direction: row-reverse;


 .label:before 
 position:absolute;
    display: block;
    width: 20px;
    height: 20px;
    content: "";
    background-color: #fff;
    border: 1px solid black;
    border-radius:4px;
  

.label:after 
   position: absolute;
   display: block;
   height: 20px;
   content: "";
   background-repeat: no-repeat;
   background-position: center center;
   background-size: 80%;


input[type="checkbox"]:checked ~ .label::after 
    background-image: url("https://cdn-icons-png.flaticon.com/512/447/447147.png");
    width: 20px;
    height: 20px;
  
<div class="wrapper">
  <input class="input input1" name="checkbox1" id="checkbox1" type="checkbox">
  <label class="label" for="checkbox1">
    <div class="label-wrapper">
      Option 1
    </div>  
  </label>
</div>


<div class="wrapper">
  <input class="input input2" name="checkbox2" id="checkbox2" type="checkbox">
  <label class="label reverse" for="checkbox2">
    <div class="label-wrapper">
      Option 2
    </div>  
  </label>
</div>

【讨论】:

非常感谢 - 它真的很有帮助。我还有一个问题(我应该在原始问题中概述),但是是否可以将复选框显示到包装器的末尾(所以它位于最右侧)?我通常会使用 flex-end 但显然标签是复选框的来源,这是不可能的? 我没有收到你的问题。它位于包装器的末尾和选项 2 复选框中文本的右侧。你到底想要什么? 想象一下,如果.wrapper 的宽度为 200 像素,我在问如何将复选框定位到包装器的“右端”?已为问题添加了屏幕截图。 当然,我在.label 样式中添加了flex: 1,在.label-wrapper 样式中添加了flex-grow:1。请检查

以上是关于在 CSS 中更改使用 ::before 和 ::after 创建的元素的顺序的主要内容,如果未能解决你的问题,请参考以下文章

[HTML CSS JS]阻止用户使用before元素更改值

在 :before 或 :after CSS 中更改 SVG 填充颜色

更改 :before 和 :after 伪元素的样式? [复制]

浅谈css的伪元素::after和::before

CSS 巧用 :before和:after

CSS:使用带有 css 伪类的图像精灵 :before 和 :after