<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 三角形,该三角形的颜色与在悬停/聚焦期间发生变化的边框颜色相同。
这里最重要的部分如下:
<select>
和<div class="after">
进入同一个grid-area
(我命名为select
)。这会将空 div 置于选择之上。
给<select>
和appearance
的none
。这将删除所有浏览器默认样式。
在内联方向的末尾添加<select>
和额外的填充,为空样式腾出空间。
将空 div 对齐到末尾。
在内联方向的末尾给空的 div 一个额外的边距,这与您想要的 <select>
填充相匹配
给空的 div 一个 pointer-events
或 none
,这样点击就会通过它到达 <select>
元素。
除此之外,您可以对空 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】:根据我的经验,它根本不起作用,除非您愿意将您的 <select>
包装在一些包装器中。但是您可以做的是使用背景图像 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+25BE
BLACK 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()