css - 选中时输入单选按钮以定位外部标签
css - Input radio button to target outter label when checked
我在 codepen 上找到了以下代码,它可以正常工作并且看起来很棒!
.switch-field {
display: flex;
margin-bottom: 36px;
overflow: hidden;
}
.switch-field input {
position: absolute !important;
clip: rect(0, 0, 0, 0);
height: 1px;
width: 1px;
border: 0;
overflow: hidden;
}
.switch-field label {
background-color: #e4e4e4;
color: rgba(0, 0, 0, 0.6);
font-size: 14px;
line-height: 1;
text-align: center;
padding: 8px 16px;
margin-right: -1px;
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px rgba(255, 255, 255, 0.1);
transition: all 0.1s ease-in-out;
}
.switch-field label:hover {
cursor: pointer;
}
.switch-field input:checked + label {
background-color: #a5dc86;
box-shadow: none;
}
.switch-field label:first-of-type {
border-radius: 4px 0 0 4px;
}
.switch-field label:last-of-type {
border-radius: 0 4px 4px 0;
}
<form class="form">
<div class="switch-field">
<input type="radio" id="radio-three" name="switch-two" value="yes" checked/>
<label for="radio-three">One</label>
<input type="radio" id="radio-four" name="switch-two" value="maybe" />
<label for="radio-four">Two</label>
<input type="radio" id="radio-five" name="switch-two" value="no" />
<label for="radio-five">Three</label>
</div>
</form>
但不幸的是,我生成的 HTML 布局如下(标签内的输入):
<form class="form">
<div class="switch-field">
<label for="radio-three">
<input type="radio" id="radio-three" name="switch-two" value="yes" checked/>
One</label>
<label for="radio-four">
<input type="radio" id="radio-four" name="switch-two" value="maybe" />
Two</label>
<label for="radio-five">
<input type="radio" id="radio-five" name="switch-two" value="no" />
Three</label>
</div>
</form>
我想知道是否可以仅使用 CSS 来调整此 class 以使其工作,或者是否需要 JS。
.switch-field input:checked + label {
background-color: #a5dc86;
box-shadow: none;
}
非常感谢!
是的,将 .switch-field input
替换为 .switch-field label input
。
x1 x2 x3 ... xn—1 xn
形式的选择器(space 分隔)表示 xn
是 xn−1
的后代,依此类推。
唯一的 CSS 可能的解决方案
pseudo-selector :focus-within
。如果一个元素有任何具有焦点的子元素,则该父元素将应用样式。因此,用户检查的单选按钮将触发焦点事件,并在这样做时激活具有 :focus-within
的 CSS 规则集,这是以下示例中的标签。
.switch-field label:focus-within {
background-color: #a5dc86;
box-shadow: none;
}
<form class="form">
<div class="switch-field">
<label for="radio-three">
<input type="radio" id="radio-three" name="switch-two" value="yes" checked/>
One</label>
<label for="radio-four">
<input type="radio" id="radio-four" name="switch-two" value="maybe" />
Two</label>
<label for="radio-five">
<input type="radio" id="radio-five" name="switch-two" value="no" />
Three</label>
</div>
</form>
下面是如何通过 javascript
实现所需功能的示例
var checkboxes = document.querySelectorAll("input[type=radio]");
var labels = document.querySelectorAll("label");
labels[0].classList.add("checkedLabel");
checkboxes.forEach(function(checkbox) {
checkbox.addEventListener('change', function(e) {
Array.from(labels).forEach(function(el) {
el.classList.remove('checkedLabel');
});
this.parentElement.classList.add("checkedLabel");
})
})
.checkedLabel {
background-color: #a5dc86;
box-shadow: none;
}
<form class="form">
<div class="switch-field">
<label for="radio-three">
<input type="radio" id="radio-three" name="switch-two" value="yes" checked/>
One</label>
<label for="radio-four">
<input type="radio" id="radio-four" name="switch-two" value="maybe" />
Two</label>
<label for="radio-five">
<input type="radio" id="radio-five" name="switch-two" value="no" />
Three</label>
</div>
</form>
你应该使用 JS。
当输入元素在标签内时,我们不需要元素上的 id 和标签上的 'for' 属性,但当它在标签外时,我们需要它。
<label>
Foo
<input name="foo" type="checkbox" />
</label>
根据您的 HTML 代码,要更改标签的样式,需要 selector 影响父级,这目前是不可能的。
为什么? https://css-tricks.com/parent-selectors-in-css/
<input id="foo" name="foo" type="checkbox" />
<label for="foo">Foo</label>
因此,对于 select :checked 输入的标签,我们需要标签是相邻的,而不是父标签。
但是在你的代码中,HTML的标签和输入是隐式连接的。所以我认为解决方案是使用JS。
let form = document.querySelector("form");
form.addEventListener("change", (event) => {
let target = event.target;
let targetParent = target.parentElement;
if (
target.type === "radio" &&
targetParent &&
targetParent.tagName.toLowerCase() === "label"
) {
let prior = form.querySelector('label.checked input[name="' + target.name + '"]');
if (prior) {
prior.parentElement.classList.remove("checked");
}
targetParent.classList.add("checked");
}
}, false);
.switch-field {
display: flex;
margin-bottom: 36px;
overflow: hidden;
}
.switch-field input {
position: absolute !important;
clip: rect(0, 0, 0, 0);
height: 1px;
width: 1px;
border: 0;
overflow: hidden;
}
.switch-field label {
background-color: #e4e4e4;
color: rgba(0, 0, 0, 0.6);
font-size: 14px;
line-height: 1;
text-align: center;
padding: 8px 16px;
margin-right: -1px;
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px rgba(255, 255, 255, 0.1);
transition: all 0.1s ease-in-out;
}
.switch-field label:hover {
cursor: pointer;
}
.switch-field label.checked {
background-color: #a5dc86;
box-shadow: none;
}
.switch-field label:first-of-type {
border-radius: 4px 0 0 4px;
}
.switch-field label:last-of-type {
border-radius: 0 4px 4px 0;
}
<form class="form">
<div class="switch-field">
<label class="checked">
<input type="radio" name="switch-two" value="yes" checked />
One
</label>
<label>
<input type="radio" name="switch-two" value="maybe" />
Two
</label>
<label>
<input type="radio" name="switch-two" value="no" />
Three
</label>
</div>
</form>
我在 codepen 上找到了以下代码,它可以正常工作并且看起来很棒!
.switch-field {
display: flex;
margin-bottom: 36px;
overflow: hidden;
}
.switch-field input {
position: absolute !important;
clip: rect(0, 0, 0, 0);
height: 1px;
width: 1px;
border: 0;
overflow: hidden;
}
.switch-field label {
background-color: #e4e4e4;
color: rgba(0, 0, 0, 0.6);
font-size: 14px;
line-height: 1;
text-align: center;
padding: 8px 16px;
margin-right: -1px;
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px rgba(255, 255, 255, 0.1);
transition: all 0.1s ease-in-out;
}
.switch-field label:hover {
cursor: pointer;
}
.switch-field input:checked + label {
background-color: #a5dc86;
box-shadow: none;
}
.switch-field label:first-of-type {
border-radius: 4px 0 0 4px;
}
.switch-field label:last-of-type {
border-radius: 0 4px 4px 0;
}
<form class="form">
<div class="switch-field">
<input type="radio" id="radio-three" name="switch-two" value="yes" checked/>
<label for="radio-three">One</label>
<input type="radio" id="radio-four" name="switch-two" value="maybe" />
<label for="radio-four">Two</label>
<input type="radio" id="radio-five" name="switch-two" value="no" />
<label for="radio-five">Three</label>
</div>
</form>
但不幸的是,我生成的 HTML 布局如下(标签内的输入):
<form class="form">
<div class="switch-field">
<label for="radio-three">
<input type="radio" id="radio-three" name="switch-two" value="yes" checked/>
One</label>
<label for="radio-four">
<input type="radio" id="radio-four" name="switch-two" value="maybe" />
Two</label>
<label for="radio-five">
<input type="radio" id="radio-five" name="switch-two" value="no" />
Three</label>
</div>
</form>
我想知道是否可以仅使用 CSS 来调整此 class 以使其工作,或者是否需要 JS。
.switch-field input:checked + label {
background-color: #a5dc86;
box-shadow: none;
}
非常感谢!
是的,将 .switch-field input
替换为 .switch-field label input
。
x1 x2 x3 ... xn—1 xn
形式的选择器(space 分隔)表示 xn
是 xn−1
的后代,依此类推。
唯一的 CSS 可能的解决方案
pseudo-selector :focus-within
。如果一个元素有任何具有焦点的子元素,则该父元素将应用样式。因此,用户检查的单选按钮将触发焦点事件,并在这样做时激活具有 :focus-within
的 CSS 规则集,这是以下示例中的标签。
.switch-field label:focus-within {
background-color: #a5dc86;
box-shadow: none;
}
<form class="form">
<div class="switch-field">
<label for="radio-three">
<input type="radio" id="radio-three" name="switch-two" value="yes" checked/>
One</label>
<label for="radio-four">
<input type="radio" id="radio-four" name="switch-two" value="maybe" />
Two</label>
<label for="radio-five">
<input type="radio" id="radio-five" name="switch-two" value="no" />
Three</label>
</div>
</form>
下面是如何通过 javascript
实现所需功能的示例var checkboxes = document.querySelectorAll("input[type=radio]");
var labels = document.querySelectorAll("label");
labels[0].classList.add("checkedLabel");
checkboxes.forEach(function(checkbox) {
checkbox.addEventListener('change', function(e) {
Array.from(labels).forEach(function(el) {
el.classList.remove('checkedLabel');
});
this.parentElement.classList.add("checkedLabel");
})
})
.checkedLabel {
background-color: #a5dc86;
box-shadow: none;
}
<form class="form">
<div class="switch-field">
<label for="radio-three">
<input type="radio" id="radio-three" name="switch-two" value="yes" checked/>
One</label>
<label for="radio-four">
<input type="radio" id="radio-four" name="switch-two" value="maybe" />
Two</label>
<label for="radio-five">
<input type="radio" id="radio-five" name="switch-two" value="no" />
Three</label>
</div>
</form>
你应该使用 JS。
当输入元素在标签内时,我们不需要元素上的 id 和标签上的 'for' 属性,但当它在标签外时,我们需要它。
<label>
Foo
<input name="foo" type="checkbox" />
</label>
根据您的 HTML 代码,要更改标签的样式,需要 selector 影响父级,这目前是不可能的。 为什么? https://css-tricks.com/parent-selectors-in-css/
<input id="foo" name="foo" type="checkbox" />
<label for="foo">Foo</label>
因此,对于 select :checked 输入的标签,我们需要标签是相邻的,而不是父标签。
但是在你的代码中,HTML的标签和输入是隐式连接的。所以我认为解决方案是使用JS。
let form = document.querySelector("form");
form.addEventListener("change", (event) => {
let target = event.target;
let targetParent = target.parentElement;
if (
target.type === "radio" &&
targetParent &&
targetParent.tagName.toLowerCase() === "label"
) {
let prior = form.querySelector('label.checked input[name="' + target.name + '"]');
if (prior) {
prior.parentElement.classList.remove("checked");
}
targetParent.classList.add("checked");
}
}, false);
.switch-field {
display: flex;
margin-bottom: 36px;
overflow: hidden;
}
.switch-field input {
position: absolute !important;
clip: rect(0, 0, 0, 0);
height: 1px;
width: 1px;
border: 0;
overflow: hidden;
}
.switch-field label {
background-color: #e4e4e4;
color: rgba(0, 0, 0, 0.6);
font-size: 14px;
line-height: 1;
text-align: center;
padding: 8px 16px;
margin-right: -1px;
border: 1px solid rgba(0, 0, 0, 0.2);
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px rgba(255, 255, 255, 0.1);
transition: all 0.1s ease-in-out;
}
.switch-field label:hover {
cursor: pointer;
}
.switch-field label.checked {
background-color: #a5dc86;
box-shadow: none;
}
.switch-field label:first-of-type {
border-radius: 4px 0 0 4px;
}
.switch-field label:last-of-type {
border-radius: 0 4px 4px 0;
}
<form class="form">
<div class="switch-field">
<label class="checked">
<input type="radio" name="switch-two" value="yes" checked />
One
</label>
<label>
<input type="radio" name="switch-two" value="maybe" />
Two
</label>
<label>
<input type="radio" name="switch-two" value="no" />
Three
</label>
</div>
</form>