【问题标题】:problem with <select> and :after with CSS in WebKit<select> 和 :after 在 WebKit 中的 CSS 问题
【发布时间】:2011-04-01 18:01:58
【问题描述】:

我想用伪 :after 在选择框上添加一些样式(以设置我的选择框有 2 个部分且没有图像)。这是 HTML:

<select name="">
  <option value="">Test</option>
</select>

而且它不起作用。我不知道为什么,也没有在 W3C 规范中找到答案。这是 CSS:

select {
  -webkit-appearance: none;
  background: black;
  border: none;
  border-radius: 0;
  color: white;
}

select:after {
  content: " ";
  display: inline-block;
  width: 24px; height: 24px;
  background: blue;
}

这是正常的还是有窍门的?

【问题讨论】:

  • 我想这是不可能的,不应该是可能的,否则会很容易改变表单的内容。想象一下简单的 CSS 改变某物的显示价格。它可能被显示为比实际价格便宜,从而诱使人们以超出预期的价格购买东西。 (或者当然,如果有人可以访问页面/用户样式表的 CSS,那么他们可能会以其他方式做同样的事情......)
  • @Synetech - 这是不正确的,页面的作者应该完全控制页面样式的所有方面。浏览器制造商试图阻止某些元素的样式,因为它们可能被用来误导用户,这不会有效,因为几乎有无数种方法可以欺骗系统或产生误报。

标签: html css select


【解决方案1】:

您可以使用 CSS 网格代替包装元素并将图标(或其他)放置在与选择相同的单元格中:

.select-field {
  display: grid;
  grid-template:
    "label"
    "select"
    / max-content;
}

.label {
  grid-area: label;
}

.select {
  appearance: none;
  background: white;
  border: 1px solid var(--border-color);
  grid-area: select;
  padding-block: 0.5ex;
  padding-inline: 1ch calc(1ch + 1em);
}

.after {
  align-self: center;
  border-block-start: 0.5em solid var(--border-color);
  border-inline: 0.5em solid transparent;
  block-size: 0;
  grid-area: select;
  inline-size: 0;
  justify-self: end;
  margin-inline-end: 1ch;
  pointer-events: none;
}

.select,
.select + .after {
  --border-color: silver;
}

.select:hover,
.select:hover + .after {
  --border-color: grey;
}

.select:focus,
.select:focus + .after {
  --border-color: rebeccapurple;
}
<div class="select-field">
  <label for="my-select" class="label">Select One</label>

  <select id="my-select" class="select">
    <option value="foo">Foo</option>
    <option value="bar">Bar</option>
    <option value="baz">Baz</option>
  </select>
  
  <div class="after"></div>
</div>

在这里,我使用了一个空的 div 并将其设置为 CSS 三角形,该三角形的颜色与在悬停/聚焦期间发生变化的边框颜色相同。

这里最重要的部分如下:

  • &lt;select&gt;&lt;div class="after"&gt; 进入同一个grid-area(我命名为select)。这会将空 div 置于选择之上。
  • &lt;select&gt;appearancenone。这将删除所有浏览器默认样式。
  • 在内联方向的末尾添加&lt;select&gt; 和额外的填充,为空样式腾出空间。
  • 将空 div 对齐到末尾。
  • 在内联方向的末尾给空的 div 一个额外的边距,这与您想要的 &lt;select&gt; 填充相匹配
  • 给空的 div 一个 pointer-eventsnone,这样点击就会通过它到达 &lt;select&gt; 元素。

除此之外,您可以对空 div 做任何事情。它甚至不必为空。例如。如果需要,您可以在其中放置一个 svg 图标。

【讨论】:

    【解决方案2】:

    如果无法修改标记怎么办?

    这是一个不需要包装器的解决方案:它在背景图像中使用 SVG。 您可能需要使用HTML entity decoder 来了解如何更改填充颜色。

    -moz-appearance: none;
    -webkit-appearance: none;
    appearance: none;
    
    background-image: url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%23000000%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E');
    background-repeat: no-repeat;
    background-position: right .7em top 50%;
    background-size: .65em auto;
    

    来自CSS-Tricks

    【讨论】:

    • 这是一个不错的技巧。超级烦人,我们仍然无法在 2020 年选择样式。
    【解决方案3】:
    <div class="select">
    <select name="you_are" id="dropdown" class="selection">
    <option value="0" disabled selected>Select</option>
    <option value="1">Student</option>
    <option value="2">Full-time Job</option>
    <option value="2">Part-time Job</option>
    <option value="3">Job-Seeker</option>
    <option value="4">Nothing Yet</option>
    </select>
    </div>
    

    设置样式的选择为什么不在选择之外添加一个 div。

    然后在 CSS 中设置样式

    .select{
        width: 100%;
        height: 45px;
        position: relative;
    }
    .select::after{
        content: '\f0d7';
        position: absolute;
        top: 0px;
        right: 10px;
        font-family: 'Font Awesome 5 Free';
        font-weight: 900;
        color: #0b660b;
        font-size: 45px;
        z-index: 2;
    
    }
    #dropdown{
        -webkit-appearance: button;
           -moz-appearance: button;
                appearance: button;
                height: 45px;
                width: 100%;
            outline: none;
            border: none;
            border-bottom: 2px solid #0b660b;
            font-size: 20px;
            background-color: #0b660b23;
            box-sizing: border-box;
            padding-left: 10px;
            padding-right: 10px;
    }
    

    【讨论】:

    • 点击 :after 元素不会激活选择
    【解决方案4】:

    根据我的经验,它根本不起作用,除非您愿意将您的 &lt;select&gt; 包装在一些包装器中。但是您可以做的是使用背景图像 SVG。例如

        .archive .options select.opt {
        -moz-appearance: none;
        -webkit-appearance: none;
        padding-right: 1.25EM;
        appearance: none;
        position: relative;
        background-color: transparent;
        background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1.1' height='10px' width='15px'%3E%3Ctext x='0' y='10' fill='gray'%3E%E2%96%BE%3C/text%3E%3C/svg%3E");
        background-repeat: no-repeat;
        background-size: 1.5EM 1EM;
        background-position: right center;
        background-clip: border-box;
        -moz-background-clip: border-box;
        -webkit-background-clip: border-box;
    }
    
        .archive .options select.opt::-ms-expand {
            display: none;
        }
    

    由于 IE,请注意正确的 URL 编码。你必须使用charset=utf8(不仅仅是utf8),不要使用双引号(“)来分隔SVG属性值,使用撇号(')来简化你的生活。URL编码s(%3E)。如果您要打印任何非 ASCII 字符,您必须获取它们的 UTF-8 表示(例如 BabelMap 可以帮助您),然后以 URL 编码形式提供该表示 - 例如对于▾(U+25BEBLACK DOWN-指向小三角形)UTF-8 表示为\xE2\x96\xBE,在 URL 编码时为%E2%96%BE

    【讨论】:

    • 这是一个不错且优雅的解决方案
    • 这是一个出色、简单、优雅的解决方案,不需要额外的 HTML,这正是我所寻找的!谢谢!这应该是 IMO 选择的答案。
    • 这是我一直在寻找的答案。我遇到的唯一问题是我似乎只能将填充更改为“黑色”或“白色”或“灰色”之类的词。当我尝试像'#fff'甚至只是#fff之类的东西时,它就会消失。
    • 完美。这是我需要的
    【解决方案5】:

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

    附:这是我今年早些时候发布的另一个重复问题的答案。

    【讨论】:

      【解决方案6】:

      此解决方案类似于 sroy 的解决方案,但使用 css 三角形而不是 web 字体:

      .select-wrapper {
        position: relative;
        width: 200px;
      }
      .select-wrapper:after {
        content: "";
        width: 0;
        height: 0;
        border-left: 5px solid transparent;
        border-right: 5px solid transparent;
        border-top: 6px solid #666;
        position: absolute;
        right: 8px;
        top: 8px;
        pointer-events: none;
      }
      select {
        background: #eee;
        border: 0 !important;
        border-radius: 0;
        -webkit-appearance:none;
        -moz-appearance:none;
        appearance:none;
        text-indent: 0.01px;
        text-overflow: "";
        font-size: inherit;
        line-height: inherit;
        width: 100%;
      }
      select::-ms-expand {
        display: none;
      }
      <div class="select-wrapper">
        <select>
          <option value="1">option 1</option>
          <option value="2">option 2</option>
          <option value="3">option 3</option>
        </select>
      </div>

      【讨论】:

        【解决方案7】:

        我一直在寻找相同的东西,因为我选择的背景与箭头颜色相同。如前所述,尚无法在选择元素上使用 :before 或 :after 添加任何内容。我的解决方案是创建一个包装器元素,在其上添加以下内容:代码之前。

        .select-wrapper {
            position: relative;
        }
        
        .select-wrapper:before {
            content: '\f0d7';
            font-family: FontAwesome;
            color: #fff;
            display: inline-block;
            position: absolute;
            right: 20px;
            top: 15px;
            pointer-events: none;
        }
        

        这是我的选择

        select {
            box-sizing: border-box;
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            width: 100%;
            padding: 10px 20px;
            background: #000;
            color: #fff;
            border: none;
            -webkit-appearance: none;
            -moz-appearance: none;
            appearance: none;
        }
        
        select::-ms-expand {
            display: none;
        }
        

        我已将 FontAwesome.io 用于我的新箭头,但您可以使用其他任何您想要的东西。显然这不是一个完美的解决方案,但根据您的需要,它可能就足够了。

        【讨论】:

        • 这在视觉上是完美的。但是您无法单击该图标并选择元素不会打开:/有什么建议吗?
        • 指针事件:无;应该注意这一点。我上面的代码有问题。我会将上面的任何 sass 更改为 css 以消除任何混乱。
        • 使用哪个伪选择器(之前和之后)有关系吗?
        • 你可以使用其中一个
        • 这是一个很好的解决方案,但是在实施它时我发现由于某种原因:之前有效,而不是:之后。我不知道为什么。
        【解决方案8】:

        这篇文章可能对http://bavotasan.com/2011/style-select-box-using-only-css/有帮助

        他正在使用带有类的外部 div 来解决此问题。

        <div class="styled-select">
          <select>
            <option>Here is the first option</option>
            <option>The second option</option>
          </select>
        </div>
        

        【讨论】:

          【解决方案9】:

          面临同样的问题。也许这可能是一个解决方案:

          <select id="select-1">
              <option>One</option>
              <option>Two</option>
              <option>Three</option>
          </select>
          <label for="select-1"></label>
          
          #select-1 {
              ...
          }
          
          #select-1 + label:after {
              ...
          }
          

          【讨论】:

          • 您能否添加使标签位于选择元素顶部所需的样式?
          【解决方案10】:

          我没有对此进行广泛的检查,但我的印象是这(还没有?)可能,因为运行浏览器的操作系统生成 select 元素的方式,而不是浏览器本身。

          【讨论】:

          • 现在是 2019 年,还是一样
          • 现在是 2020 年了,还是一样
          • 现在是 2021 年了,还是一样
          • 现在是 2021 年了,我记得 IE6 有过这种问题。依赖于 SELECT 的操作系统实现。必须使用 IFRAME 来确保 SELECT 被模态 div 隐藏。请记住伙计们……开发人员通过重用这一操作系统组件节省了数小时的工作时间。小时和小时。
          • 必填“现在是 2022 年,还是一样” ...
          猜你喜欢
          • 2014-04-27
          • 2013-03-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-12-08
          • 2013-09-15
          • 2011-12-09
          相关资源
          最近更新 更多