<select> 和 :after 在 WebKit 中的 CSS 问题

Posted

技术标签:

【中文标题】<select> 和 :after 在 WebKit 中的 CSS 问题【英文标题】:problem with <select> and :after with CSS in WebKit 【发布时间】: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 - 这是不正确的,页面的作者应该完全控制页面样式的所有方面。浏览器制造商试图阻止某些元素的样式,因为它们可能被用来误导用户,这不会有效,因为几乎有无数种方法可以欺骗系统或产生误报。 Pseudo elements and SELECT tag的可能重复 【参考方案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 年,还是一样” ...

以上是关于<select> 和 :after 在 WebKit 中的 CSS 问题的主要内容,如果未能解决你的问题,请参考以下文章

添加父标签时如何使用append() after() before()

jquery如何在select中一个指定的 option后追加另一个option

jquery after()和append()区别

伪类before和after

after伪类 和overflow清楚浮动

认识:before和:after伪类