【问题标题】:Changing the order of elements created using ::before and ::after in CSS在 CSS 中更改使用 ::before 和 ::after 创建的元素的顺序
【发布时间】: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 处理的(它是隐藏的) - 如何将可视输入和隐藏输入都移动到文本的右侧?

编辑:

【问题讨论】:

    标签: html css styled-components


    【解决方案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。请检查
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 2020-09-20
    • 2012-12-17
    • 2014-01-28
    • 2011-05-10
    相关资源
    最近更新 更多