正确的语义选择样式

问题描述 投票:0回答:1

我想在我的网络应用程序中创建一个自定义样式的选择元素。但是,我担心我应该使用的方法。设置默认选择的样式为我提供了一些选项,但我无法完全设置弹出菜单的样式,这是有问题的。我可以用来进行此自定义选择的另一种方法是使用我自己的 JavaScript 创建它;但是,从语义上讲,它将不再是选择元素,并且例如,它不会在表单中被识别。如何使用自己的自定义样式创建选择元素,同时保持其语义正确?

也许我应该将其放在标签上,但是如何确保选择功能在语义上是正确的?我可以设置它的样式,甚至可以从原始选择元素中获取它,并显示用 JavaScript 制作的自定义下拉列表,然后该下拉列表将切换原始选择。然而,这不是浏览器能够识别的东西。或者也许我错了,并且没有任何影响,因为我认为如果可以通过JavaScript切换选择,我可以这样做来解决表单无法识别选择的问题。

javascript html css drop-down-menu semantics
1个回答
0
投票

从语义上讲,

<select>
元素可以替换为一组单选按钮 -
<input type="radio">
(* 代表带复选框的
<select multiple>
),这显然可以作为表单元素正常工作,包括支持键盘选项卡和箭头键。

请参阅下面的代码片段,我正在使用包含

<fieldset>
以及相应的
<input type="radio">
元素的
<label>

这是可使用任何 CSS/HTML 设置样式和扩展的。在本例中为下拉列表。

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>

© www.soinside.com 2019 - 2024. All rights reserved.