【问题标题】:Pseudo elements and SELECT tag伪元素和 SELECT 标签
【发布时间】:2014-02-01 22:07:52
【问题描述】:

select 标签是否允许使用:after 选择器在其后创建伪元素?

我在 Mac 上尝试过 Chrome、Safari 和 Firefox,但似乎无法正常工作。

【问题讨论】:

标签: css html-select pseudo-element


【解决方案1】:

好吧,看起来select 标签不允许:after:before 伪,因为它们是由每个供应商定制的,所以很难修改它们,这是因为它们不允许@987654327 @ 或 :after 上的伪元素。

对于看到此内容的每个人,有一个不错的选择,即使用 jQuery 创建自定义 select 元素并进行最少的修改……创建一个选择,然后使用 jQuery 对其进行编辑:

// Iterate over each select element
$('select').each(function() {
  // Cache the number of options
  var $this = $(this),
    numberOfOptions = $(this).children('option').length;

  // Hides the select element
  $this.addClass('s-hidden');

  // Wrap the select element in a div
  $this.wrap('<div class="select"></div>');

  // Insert a styled div to sit over the top of the hidden select element
  $this.after('<div class="styledSelect"></div>');

  // Cache the styled div
  var $styledSelect = $this.next('div.styledSelect');

  // Show the first select option in the styled div
  $styledSelect.text($this.children('option').eq(0).text());

  // Insert an unordered list after the styled div and also cache the list
  var $list = $('<ul />', {
    'class': 'options'
  }).insertAfter($styledSelect);

  // Insert a list item into the unordered list for each select option
  for (var i = 0; i < numberOfOptions; i++) {
    $('<li />', {
      text: $this.children('option').eq(i).text(),
      rel: $this.children('option').eq(i).val()
    }).appendTo($list);
  }

  // Cache the list items
  var $listItems = $list.children('li');

  // Show the unordered list when the styled div is clicked (also hides it if the div is clicked again)
  $styledSelect.click(function(e) {
    e.stopPropagation();
    $('div.styledSelect.active').each(function() {
      $(this).removeClass('active').next('ul.options').hide();
    });
    $(this).toggleClass('active').next('ul.options').toggle();
  });

  // Hides the unordered list when a list item is clicked and updates the styled div to show the selected list item
  // Updates the select element to have the value of the equivalent option
  $listItems.click(function(e) {
    e.stopPropagation();
    $styledSelect.text($(this).text()).removeClass('active');
    $this.val($(this).attr('rel'));
    $list.hide();
    /* alert($this.val()); Uncomment this for demonstration! */
  });

  // Hides the unordered list when clicking outside of it
  $(document).click(function() {
    $styledSelect.removeClass('active');
    $list.hide();
  });
});
body {
  padding: 50px;
  background-color: white;
}

.s-hidden {
  visibility: hidden;
  padding-right: 10px;
}

.select {
  cursor: pointer;
  display: inline-block;
  position: relative;
  font: normal 11px/22px Arial, Sans-Serif;
  color: black;
  border: 1px solid #ccc;
}

.styledSelect {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background-color: white;
  padding: 0 10px;
  font-weight: bold;
}

.styledSelect:after {
  content: "";
  width: 0;
  height: 0;
  border: 5px solid transparent;
  border-color: black transparent transparent transparent;
  position: absolute;
  top: 9px;
  right: 6px;
}

.styledSelect:active,
.styledSelect.active {
  background-color: #eee;
}

.options {
  display: none;
  position: absolute;
  top: 100%;
  right: 0;
  left: 0;
  z-index: 999;
  margin: 0 0;
  padding: 0 0;
  list-style: none;
  border: 1px solid #ccc;
  background-color: white;
  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
  -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}

.options li {
  padding: 0 6px;
  margin: 0 0;
  padding: 0 10px;
}

.options li:hover {
  background-color: #39f;
  color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<select id="selectbox1">
  <option value="">Select an option&hellip;</option>
  <option value="aye">Aye</option>
  <option value="eh">Eh</option>
  <option value="ooh">Ooh</option>
  <option value="whoop">Whoop</option>
</select>

<select id="selectbox2">
  <option value="">Month&hellip;</option>
  <option value="january">January</option>
  <option value="february">February</option>
  <option value="march">March</option>
  <option value="april">April</option>
  <option value="may">May</option>
  <option value="june">June</option>
  <option value="july">July</option>
  <option value="august">August</option>
  <option value="september">September</option>
  <option value="october">October</option>
  <option value="november">November</option>
  <option value="december">December</option>
</select>

http://jsfiddle.net/tovic/ZTHkQ/

【讨论】:

  • 有多个插件也可以做到这一点jquery-plugins.net/tag/select-list
  • 是的,但是其中哪一个带有轻松编辑其设计的选项。几乎所有这些都带有自己的预装设计,总体上看起来不错,但在您需要完全控制的情况下则不然。稍后,您需要覆盖所有 css 样式才能根据需要设置样式。这就是我粘贴找到的代码的原因,因此您可以随意设置样式。
  • 更多信息在这里:*.com/questions/8621127/…
【解决方案2】:

这是我使用的折衷方案。 http://jsfiddle.net/pht9d295/3/

<div class="select-wrapper">
    <select>
        <option>United Kingdom</option>
        <option>Canada</option>
        <option>United States</option>
    </select>
</div>

和 CSS

body {
    background-color: #f6f6f6;
    padding: 10px;
}
.select-wrapper {
    background-color: #FFF;
    display: inline-block;
    position: relative;
}
.select-wrapper:after {
    content:"\f078";
    font-family:'FontAwesome';
    position: absolute;
    top: 13px;
    right: 10px;
    z-index: 5;
    pointer-events: none;
 }
select {
    padding: 10px 40px 10px 10px;
    -webkit-appearance: none;
    -ms-appearance: none;
    -moz-appearance: none;
    appearance: none;
    border: 1px solid #bbb;
    background-color: transparent;
    border-radius: 0;
    position: relative;
    cursor: pointer;
    z-index: 10;
}

【讨论】:

  • 您必须将pointer-events: none; 添加到after 伪元素,否则当您单击FontAwesome 图标时,选择组合框不会出现。
  • 我也使用 Chris Coyier 的 CSS 三角技巧来做到这一点:css-tricks.com/snippets/css/css-triangle - 那么你甚至不需要字体图标。
  • @caroso1222 - 你的评论也很棒,对于那些不想走javascript路线的人来说,如下。 pointer-events: none 是关键!
  • 我不认为在 IE 中将 FontAwesome 字符代码添加到 content 属性中。
【解决方案3】:

这是我使用font-awesome 编写的现代解决方案。我不确定它对跨浏览器的友好程度。为简洁起见,省略了供应商扩展。

HTML

<fieldset>
    <label for="color">Select Color</label>
    <div class="select-wrapper">
        <select id="color">
            <option>Red</option>
            <option>Blue</option>
            <option>Yellow</option>
        </select>
        <i class="fa fa-chevron-down"></i>
    </div>
</fieldset>

SCSS

fieldset {
    .select-wrapper {
        position: relative;

        select {
            appearance: none;
            position: relative;
            z-index: 1;
            background: transparent;

            + i {
                position: absolute;
                top: 40%;
                right: 15px;
            }
        }
    }

如果您的选择元素具有已定义的背景颜色,那么这将不起作用,因为此 sn-p 实质上是将雪佛龙图标放在选择元素后面(以允许单击图标顶部仍启动选择操作)。

但是,您可以将 select-wrapper 的样式设置为与 select 元素相同的大小,并为其背景设置样式以达到相同的效果。

查看我的CodePen 的工作演示,该演示使用常规标签和“占位符”标签以及其他清理样式(如边框和宽度)在深色和浅色主题选择框上显示这段代码。

【讨论】: