在 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: flex
和 flex-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 填充颜色