我想在我的网络应用程序中创建一个自定义样式的选择元素。但是,我担心我应该使用的方法。设置默认选择的样式为我提供了一些选项,但我无法完全设置弹出菜单的样式,这是有问题的。我可以用来进行此自定义选择的另一种方法是使用我自己的 JavaScript 创建它;但是,从语义上讲,它将不再是选择元素,并且例如,它不会在表单中被识别。如何使用自己的自定义样式创建选择元素,同时保持其语义正确?
也许我应该将其放在标签上,但是如何确保选择功能在语义上是正确的?我可以设置它的样式,甚至可以从原始选择元素中获取它,并显示用 JavaScript 制作的自定义下拉列表,然后该下拉列表将切换原始选择。然而,这不是浏览器能够识别的东西。或者也许我错了,并且没有任何影响,因为我认为如果可以通过JavaScript切换选择,我可以这样做来解决表单无法识别选择的问题。
从语义上讲,
<select>
元素可以替换为一组单选按钮 - <input type="radio">
(* 代表带复选框的<select multiple>
),这显然可以作为表单元素正常工作,包括支持键盘选项卡和箭头键。
请参阅下面的代码片段,我正在使用包含
<fieldset>
以及相应的 <input type="radio">
元素的 <label>
。const toggleSelect = e => {
const E = e.target.closest('fieldset.select label');
E && E.closest('fieldset.select').classList.toggle('open');
}
document.addEventListener('click', toggleSelect);
const logData = e => e.preventDefault(console.log(Object.fromEntries(new FormData(e.target))));
* {box-sizing:border-box}
.select {
position: relative;
display: inline-flex;
flex-flow: column;
height: 1.75em;
overflow: hidden;
margin:0; padding: 0;
border: 0;
&:after {
content: '\25bc';
position: absolute;
top:.25em; right:.5em;
z-index:1;
pointer-events:none;
}
&.open {
height:auto;
margin-bottom: -100%;
label:first-of-type~label {position:static !important}
}
input {
position: absolute; top:.25em;
z-index: -1;
opacity: 0;
}
label {
padding: .25em 1.5em .25em .5em;
line-height: 1.25;
background: #eee;
&:first-of-type {position:static}
img {width:1.25em; height:1.25em; vertical-align:middle}
}
label:hover, input:focus+label, input:checked+label {background:#ad7}
label:first-of-type ~ input:checked+label {
position: absolute; top:0;
width: 100%;
}
}
<form onsubmit="logData(event)">
<select name="native-select">
<option value="1">option 1</option>
<option value="2"><img src="https://graph.facebook.com/1841494189551870/picture?type=large"></option>
<option value="3">option 3</option>
<option value="4">option 4</option>
</select>
<hr>
<fieldset class="select">
<input name="custom-select" id="option-1" type="radio" value="1" checked>
<label for="option-1">option 1</label>
<input name="custom-select" id="option-2" type="radio" value="2">
<label for="option-2"><img src="https://graph.facebook.com/1841494189551870/picture?type=small"></label>
<input name="custom-select" id="option-3" type="radio" value="3">
<label for="option-3">option <i>3</i></label>
<input name="custom-select" id="option-4" type="radio" value="4">
<label for="option-4">option 4</label>
</fieldset>
<hr>
<p>Submit to see the resulting data.</p>
<button>Submit</button>
</form>