纯CSS方式取消隐藏一个下拉菜单(或任何HTML元素)当选择在前面的下拉菜单中选择一个选项,一定 [英] Pure CSS way to unhide a drop-down menu (or any HTML element) when a certain option in a preceding drop-down menu is selected
问题描述
这里的服务器端开发人员使用了一些CSS.
Server-side dev here, dabbling in a bit of CSS.
我正在尝试使用下拉菜单中的 selected
选项来显示另一个下拉菜单.尽管有多个公开的JS解决方案可以解决此问题,但这里的挑战是在CSS的完全支持下,完全没有JS的帮助.
I'm trying to use a selected
option within a drop-down menu to display another drop-down. Whilst there are several publicly available JS solutions to such a problem, the challenge here is to do it purely in CSS, without any JS help.
当前,我尝试编写CSS,当使用 option
时,将 display:block
添加到隐藏元素( select
元素)中在前面的 select
元素中选择了
value ="1"
.
Currently, I've tried to write CSS that adds display:block
to a hidden element (a select
element) when option
with value="1"
is selected
within a preceding select
element.
不用说它没有用.获得有关如何完成此类事情的专家意见(带有说明性示例)将是很棒的.
Needless to say it hasn't worked. It would be great to get expert opinion on how to accomplish this sort of a thing (with an illustrative example).
另一方面,如果不可能,那么获得一个说明性示例,说明该问题的另一种纯CSS解决方案(如果存在的话).
On the other hand, if it's not possible, it would be great to get an illustrative example of an alternative CSS-only solution to the problem (if it exists).
我正在尝试什么:
body{
background: #f0f3f4
}
.second{
display:none
}
select#first option[value="1"]:selected ~ .second{
display: block
}
<select id="first" style="width:95%;padding:6px 0;border:1px solid #3cb7dd;border-radius:5px;text-align:center;color:#1f8cad" class="cm mt sp mbl" name="turl">
<option selected disabled hidden>Selector 1</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<div class="second">
<select style="width:95%;padding:6px 0;border:1px solid #3cb7dd;border-radius:5px;text-align:center;color:#1f8cad" class="cm mt sp mbl" name="turl">
<option selected disabled hidden>Selector 2</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
</div>
p.s.浏览器兼容性是一个考虑因素,因此,如果建议的解决方案遵循受良好支持的CSS/HTML,那将是一个很好的选择.
p.s. browser-compatibility is a consideration, so it would be great if a suggested solution adheres to well-supported CSS/HTML.
推荐答案
使用显而易见的方法总结问题:< option>
元素支持:checked
,但是邻接选择器( a + b
, a〜b
)不支持匹配的后续元素,除非它们在同一父级中,因此不能使用.
To summarize the issue with the obvious approach: <option>
elements support :checked
, but adjacency selectors (a + b
, a ~ b
) do not support matching subsequent elements unless they are in the same parent, therefore this cannot be used.
但是,复选框和单选按钮可以与标签位于不同的容器中,可以将其用于CSS内的许多状态"情况-我们只需要将某种伪造的<< select>
中带有标签,然后将其< input>
放到外面,然后我们就可以照常通过〜
进行匹配!
However, checkboxes and radiobuttons can be in a different container from their label, which can be utilized for plenty of "state" situations inside CSS - we just need to stitch together some sort of fake <select>
with labels inside it, and put their <input>
s outside, and then we can match via ~
as usual!
body {
font: 15px sans-serif;
}
/* a slightly janky custom dropdown */
.select {
margin: 0.5em 0;
line-height: 30px;
height: 25px;
width: 200px;
border: 1px solid #ddd;
/* it's a flexbox purely so that we can use `order` on the active element to move it to the top of the list */
display: flex;
flex-direction: column;
}
/* restyle labels to look vaguely like options */
.select label {
position: relative;
display: block;
line-height: 25px;
height: 25px;
padding: 0 0.5em;
background: white;
}
/* hide labels in out-of-focus dropdowns [except the active one] */
.select:not(:focus) label {
display: none;
/* this is to prevent clicking the current item instead of activating the dropdown */
pointer-events: none;
/* this is to override background from the multi-rule below */
background: white!important;
}
.select:focus label {
z-index: 100;
/* and then allow clicking them once it actually has focus */
pointer-events: all;
}
.select:focus label:hover {
background: #08f!important; /* ditto */
color: white;
}
/*
here's the catch: you can't just display:none the radiobuttons,
as then your dropdown will not lose focus and thus will not
close upon changing the active item.
So we just move them somewhere far away
*/
input.option {
position: absolute;
left: -999999px;
}
/*
this allows the correct label to be shown inside
a dropdown when it is not open.
please don't write these by hand
*/
#s1_1:checked ~ .select label[for="s1_1"],
#s1_2:checked ~ .select label[for="s1_2"],
#s1_3:checked ~ .select label[for="s1_3"],
#s2_1:checked ~ .select label[for="s2_1"],
#s2_2:checked ~ .select label[for="s2_2"]{
display: block;
background: #f0f0f0;
/*
makes the selected element show up on the top of the options list,
otherwise it's a bit disorienting
*/
order: -1;
}
/* and finally, the actual selector */
#s1_2:not(:checked) ~ #s2 { display: none };
<input class="option" type="radio" name="s1" id="s1_1" checked/>
<input class="option" type="radio" name="s1" id="s1_2"/>
<input class="option" type="radio" name="s1" id="s1_3"/>
<div class="select" tabindex="1">
<label for="s1_1">Option 1</label>
<label for="s1_2">Option 2 [!]</label>
<label for="s1_3">Option 3</label>
</div>
Some text after
<input class="option" type="radio" name="s2" id="s2_1" checked/>
<input class="option" type="radio" name="s2" id="s2_2"/>
<div class="select" tabindex="2" id="s2">
<label for="s2_1">Option 1</label>
<label for="s2_2">Option 2</label>
</div>
这篇关于纯CSS方式取消隐藏一个下拉菜单(或任何HTML元素)当选择在前面的下拉菜单中选择一个选项,一定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!