ChatGPT解决这个技术问题 Extra ChatGPT

我可以在输入字段上使用 :before 或 :after 伪元素吗?

我正在尝试在 input 字段上使用 :after CSS 伪元素,但它不起作用。如果我将它与 span 一起使用,它可以正常工作。

<style type="text/css">
.mystyle:after {content:url(smiley.gif);}
.mystyle {color:red;}
</style>

这有效(将笑脸放在“buu!”和“更多”之前)

<span class="mystyle">buuu!</span>a some more

这不起作用 - 它仅将 someValue 着色为红色,但没有笑脸。

<input class="mystyle" type="text" value="someValue">

我究竟做错了什么?我应该使用另一个伪选择器吗?

注意:我无法在 input 周围添加 span,因为它是由第三方控件生成的。

如果您完全无法控制 HTML,请尝试更改 inputborder-color。我觉得它更引人注目。

T
TylerH

:before 和 :after 在容器内渲染

并且 不能包含其他元素。

伪元素只能在容器元素上定义(或者说只支持)。因为它们的呈现方式是 within 容器本身作为子元素。 input 不能包含其他元素,因此不受支持。另一方面,也是表单元素的 button 支持它们,因为它是其他子元素的容器。

如果你问我,如果某些浏览器确实在非容器元素上显示这两个伪元素,那是一个错误和非标准一致性。规范直接谈到元素内容...

W3C 规范

如果我们仔细阅读 the specification,它实际上是说它们被插入 inside 一个包含元素:

作者使用 :before 和 :after 伪元素指定生成内容的样式和位置。正如它们的名字所示,:before 和 :after 伪元素指定了元素文档树内容之前和之后的内容位置。 'content' 属性与这些伪元素一起指定插入的内容。

看?元素的文档树内容。据我了解,这意味着在容器内。


+1 比公认的答案好得多。感谢您对标准本身的清晰解释。 [required]::before { content "*"; color: red; } 就这么多:P
提示:如果您仅遇到像 <input type="submit" value="Send"/> 这样的提交输入的问题,请改用 <button type="submit">Send</button>。演示文稿是相同的,但 <button> 是一个容器,因此支持 :before:after
<hr /> 呢?我以为它不是容器元素,但它可以呈现 :after:before jsfiddle.net/Uf88j/1
@deathlock:这确实很有趣。我会说它一定是某种异常,我不会依赖它跨浏览器或跨版本工作...... HR 不是容器元素,因此不应允许伪元素。甚至 W3C standard 都表示它允许 no 内容。如果您检查 void elementcan see这些元素在任何情况下都不应该有任何内容。伪元素是内容,因此预计未来的浏览器版本将无法显示它们。
:before 和 :after 在容器内渲染” :before 和 :after 伪元素来自“内容之前和之后”。不是“在容器的开头或结尾”。 规范没有提到容器。对于像 ph1 这样的标签,内容在标签内,因此之前/之后也会出现在标签内。对于像 inputhr 这样的元素,:before 和 :after 仍然会出现在内容之前或之后,但不涉及容器(尤其是对于 input)。 input:checked:before 广泛用于指示通过 css 检查的复选框。
T
TylerH

Internet Explorer 7 及更低版本的任何元素均不支持 :after:before

它也不适用于替换元素,例如表单元素(输入)和图像元素。

换句话说,纯 CSS 是不可能的。

但是,如果使用 jquery,您可以使用

$(".mystyle").after("add your smiley here");

API docs on .after

用 javascript 附加您的内容。这将适用于所有浏览器。


Alex,我使用的是 IE8 和最新的 FF,所以 IE7 不是问题。我正在寻找任何关于 :after 限制的文档,但找不到它。 w3.org/TR/CSS2/generate.html 声明,它被插入到文档树中的当前节点之后,因此它应该适用于两种情况。
除非您只是为自己使用而构建页面,否则大部分互联网仍然使用这些浏览器。 w3c 规范说是的;但众所周知,浏览器实现了自己对规范的解释。在输入上使用 :after 只能在 Opera 9+ 中使用,但不能在 IE、FF、safari 或 chrome 中实现,因为它们在内部构建 DOM 的方式——同样,它不能用纯 CSS 完成。
我不确定 4 月份是否是这种情况,但 Webkit 确实支持 :after,尽管它不支持输入的 :before:after
据我了解 W3C :after:before 伪元素,它们只能放在容器元素上。为什么?因为它们被附加在该特定元素的内部中。 input 不是容器。 button 例如,因此您可以戴上它们。按预期工作。规范实际上说:在一个元素的文档树内容之前和之后它明确地说CONTENT。所以一个元素必须是一个容器。
下一个答案要好得多.. 给出实际理由而不是谈论 IE 7(谁在乎)和 jQuery(坏主意)
M
Matt

奇怪的是,它适用于某些类型的输入。至少在 Chrome 中,

<input type="checkbox" />

工作正常,与

<input type="radio" />

只是 type=text 和其他一些不起作用。


@ANeves,它对我来说在 Chromium 中有效,但在 Firefox 中无效。
是的,type="submit" 也可以。
B
Blazemonger

Here's another approach(假设您可以控制 HTML):在输入之后添加一个空的 <span></span>,并使用 input.mystyle + span:after 在 CSS 中定位它

.field_with_errors { 显示:内联;红色; } .field_with_errors input+span:after { content: "*" }

标签:
< /span>

我在 AngularJS 中使用这种方法,因为它会自动将 .ng-invalid 类添加到 <input> 表单元素和表单,但不会添加到 <label>


它允许添加悬停动作,例如:input:hover+span:after{color: blue}。点赞。
为什么这个答案的赞成票这么少?我认为理论知识很重要,但这解决了问题。
为了解决问题,不错的选择。
C
CatalinBerta

:before:after 应用在容器内,这意味着您可以将它用于带有结束标记的元素。

它不适用于自闭合元素。

附带说明一下,自动关闭的元素(例如 img/hr/input)也称为“替换元素”,因为它们被各自的内容替换。 “外部对象”缺乏更好的术语。更好的阅读here


V
Veiko Jääger

我使用 background-image 为必填字段创建了红点。

input[type="text"][required] {
  background-image: radial-gradient(red 15%, transparent 16%);
  background-size: 1em 1em;
  background-position: top right;
  background-repeat: no-repeat
}

View on Codepen


这真是太棒了,干得好!
P
Pons Purushothaman

:after:before 等伪元素仅适用于容器元素。像 <input/><img> 等在一个地方开始和结束的元素不是容器元素,因此不支持伪元素。一旦您将伪元素应用于 <div> 之类的容器元素,并且如果您检查代码(见图),您就会明白我的意思。实际上,伪元素是在容器元素内创建的。在 <input><img> 的情况下这是不可能的

https://i.stack.imgur.com/1yUox.png


M
Manngo

这里最大的误解是beforeafter这两个词的含义。它们不是引用元素本身,而是引用元素中的内容。所以 element:before 在内容之前,而 element:after 在内容之后,但两者仍然在原始元素内。

input 元素在 CSS 视图中没有内容,因此没有 :before:after 伪内容。许多其他无效或替换元素也是如此。

没有引用元素外部的伪元素。

在不同的宇宙中,这些伪元素可能被称为其他东西以使这种区别更加清晰。甚至可能有人提出了一个真正在元素之外的伪元素。到目前为止,在这个宇宙中还不是这样。


我可能不明白你的意思,但如果我明白了,伪元素对 hr 有效吗? jsfiddle.net/demetriad/o49yn5hq
@Chris 这对我和其他一些人来说都是一个惊喜。我认为这是一个怪癖。 hr 从 CSS 的角度来看一直是模棱两可的,尽管您在讨论颜色时会看到更多。
U
Unihedron

您不能将伪元素放入输入元素中,但可以放入阴影元素中,例如占位符!

input[type="text"] {   
  &::-webkit-input-placeholder {
    &:before {
      // your code
    }
  }
}

要使其在其他浏览器中运行,请在不同的选择器中使用 :-moz-placeholder::-moz-placeholder:-ms-input-placeholder。无法对选择器进行分组,因为如果浏览器无法识别选择器,则整个语句无效。

更新:上面的代码仅适用于 CSS 预处理器(SASS,LESS...),没有使用预处理器:

input[type="text"]::-webkit-input-placeholder:before { // your code }

好的!请注意,占位符伪元素的属性支持有限:颜色、背景、字间距、字母间距、文本装饰、垂直对齐、文本转换、行高、文本缩进、不透明度。请参阅css-tricks.com/almanac/selectors/p/placeholder
感谢您的提示。请记住,当用户填写输入框时,伪元素内的所有内容都会消失。如果您想要的只是像我一样显示一个 glyphicon-search 而不触及标记,那么这就是一个 UX 问题。
关于为什么这不再有效的一些背景:bugs.chromium.org/p/chromium/issues/detail?id=582301
佚名

纯 CSS 中的工作解决方案:

诀窍是假设在文本字段之后有一个 dom 元素。

/* * 诀窍就在这里:* 这个选择器说“在 * 输入文本 (+) 之后获取第一个 dom 元素,并将其之前的内容设置为 * 值 (:before)。*/ input#myTextField + *:before { content: "👍"; }

(*) 有限的解决方案,但是:

您必须希望有以下 dom 元素,

您必须希望没有其他输入字段跟随您的输入字段。

但在大多数情况下,我们知道我们的代码,所以这个解决方案看起来很高效,100% CSS 和 0% jQuery。


input#myTextField ~ span:before { 好多了,但 span 应该有一个更明确的类,例如 .tick.icon
@Val 该选择器无法正常工作,因为 ~ 选择 每个 前面的元素,但您只想要第一个。
E
Echilon

我发现这篇文章是因为我遇到了同样的问题,这是对我有用的解决方案。与替换输入的值相反,只需将其删除并在其后面绝对放置一个相同大小的跨度,跨度可以使用您选择的图标字体应用 :before 伪类。

<style type="text/css">

form {position: relative; }
.mystyle:before {content:url(smiley.gif); width: 30px; height: 30px; position: absolute; }
.mystyle {color:red; width: 30px; height: 30px; z-index: 1; position: absolute; }
</style>

<form>
<input class="mystyle" type="text" value=""><span class="mystyle"></span>
</form>

+1 - 如果您使用的插件或框架会自动将验证类添加到元素本身而不是父标签,则此解决方案效果很好。
J
Jukka K. Korpela

根据 CSS 2.1 规范中的 note,该规范“没有完全定义 :before 和 :after 与替换元素(例如 HTML 中的 IMG)的交互。这将在未来的规范中更详细地定义。”虽然input不再是真正的替换元素,但基本情况并没有改变::before:after对其的影响是未指定的,一般是没有影响的。

解决方案是找到一种不同的方法来解决您试图以这种方式解决的问题。将生成的内容放入文本输入控件会非常误导:对用户来说,它似乎是控件中初始值的一部分,但它不能被修改——所以它似乎是在开始时强制执行的。控制,但它不会作为表单数据的一部分提交。


这是一个评论,而不是一个答案——一个相当长的评论,但仍然是一个评论。
@Blazemonger,目前还不清楚问题是什么,但无论如何,这个答案解决了与接受的答案相同的问题,但以更正确的方式。将生成的内容用于 input 元素并非不可能,只是未指定且取决于浏览器。
O
Oriol

正如其他人解释的那样,input 有点被替换为 void 元素,因此大多数浏览器不允许您在其中生成 ::before::after 伪元素。

但是,CSS 工作组正在考虑明确允许 ::before::after,以防 input 具有 appearance: none

https://lists.w3.org/Archives/Public/www-style/2016Mar/0190.html

Safari 和 Chrome 都允许在其表单输入中使用伪元素。其他浏览器没有。我们考虑删除它,但使用计数器记录了使用它的页面的约 0.07%,这是我们最大删除阈值的 20 倍。实际上在输入上指定伪元素至少需要在某种程度上指定输入的内部结构,我们还没有设法做到(而且我不相信我们*可以*做到)。但鲍里斯建议,在其中一个错误线程中,允许它出现在外观:无输入 - 基本上只是将它们变成

,而不是“有点替换”元素。


K
Kapunahele Wong

您必须在输入周围使用某种包装器才能使用 before 或 after 伪元素。这是一个小提琴,它在输入的包装器 div 上有一个 before,然后将 before 放在输入内 - 或者至少看起来像它。显然,这是一种解决方法,但在紧要关头有效,并且有助于响应。如果您需要添加一些其他内容,您可以轻松地将其作为之后。

工作小提琴

输入中的美元符号作为伪元素:http://jsfiddle.net/kapunahele/ose4r8uj/1/

的HTML:

<div class="test">
    <input type="text"></input>
</div>

CSS:

input {
    margin: 3em;
    padding-left: 2em;
    padding-top: 1em;
    padding-bottom: 1em;
    width:20%; 
}


.test {
    position: relative;
    background-color: #dedede;
    display: inline;
}

.test:before {
    content: '$';
    position: absolute;
    top: 0;
    left: 40px;
    z-index: 1;
}

不错的技巧,但您可以制作一个风格化的 div 以“继续”输入。看到这个小提琴jsfiddle.net/ose4r8uj/31但你也可以使用引导程序更容易:getbootstrap.com/css/#forms-control-validation寻找“带有可选图标”部分。尽管如此,这与原始问题无关。
仅供参考,对于输入的 :focus , :hover 等没有好处,因为您无法定位父元素
A
Alex Ovchinkin

接下来尝试:

标签[for="userName"] { 位置:相对; } 标签[for="userName"]::after { 内容:'[after]';宽度:22px;高度:22px;显示:内联块;位置:绝对;右:-30px; }


K
Kevin Conroy

如果您尝试使用 :before 和 :after 设置输入元素的样式,那么您可能会尝试模仿 CSS 堆栈中其他 span、div 甚至元素的效果。

正如 Robert Koritnik 的回答所指出的, :before 和 :after 只能应用于容器元素,而输入元素不是容器。

然而,HTML 5 引入了 button 元素,它是一个容器,其行为类似于 input[type="submit|reset"] 元素。

    <style>
    .happy:after { content:url(smiley.gif); }
    </style>

    <form>
    <!-- won't work -->
    <input class="happy" type="submit" value="Submit" />

    <!-- works -->
    <button class="happy">Submit</button>
    </form>

HTML 4 实际上引入了
C
CSSBurner

该问题提到“输入字段”。尽管我相信 OP 指的是 type=text 的输入字段,但 ::after::before 伪内容确实会为几种不同类型的输入字段呈现:

input::before {
    content: "My content" /* 11 different input types will render this */
}    

这是 all 输入类型的 comprehensive demo,清楚地显示了哪些与(在本例中)::before 伪元素兼容。

总而言之,这是可以呈现伪内容的所有输入类型的列表:

复选框颜色日期日期时间本地文件图像月无线电范围时间周


到目前为止,FireFox 都不支持(版本 102)
J
Juan Mendes

:before:after 仅适用于可以具有子节点的节点,因为它们将新节点作为第一个或最后一个节点插入。


c
colorswall

使用 after 和 before 的切换器示例将您的输入包装在 div 块上

.fm-form-control { 位置:相对;边距顶部:25px;边距底部:25.2px; } .fm-switcher { 显示:无; } .fm-switcher:checked + .fm-placeholder-switcher:after { background-color: #94c6e7; } .fm-switcher:checked + .fm-placeholder-switcher:before { left: 24px; } .fm-switcher[disabled] + .fm-placeholder-switcher { 光标:不允许; } .fm-switcher[disabled] + .fm-placeholder-switcher:before { background-color: #cbd0d3; } .fm-switcher[disabled] + .fm-placeholder-switcher:after { background-color: #eaeded;边框颜色:#cbd0d3; } .fm-placeholder-switcher { padding-left: 53px;光标:指针;行高:24px; } .fm-placeholder-switcher:before { 位置:绝对;内容: '';左:0;最高:50%;宽度:20px;高度:20px;边距顶部:-10px;左边距:2px;背景颜色:#2980b9; z指数:2; -moz-transition:所有 0.15 秒缓入出局; -o-transition:所有 0.15s 缓入缓出; -webkit-transition:所有 0.15s 缓入出局;过渡:所有 0.15 秒缓入出;边框半径:12px; } .fm-placeholder-switcher:after { position: absolute;内容: '';左:0;最高:50%;宽度:48px;高度:20px;边距顶部:-12px;背景颜色:#ffffff; z-index:1;边框半径:12px;边框:2px 实心#bdc3c7; -moz-transition:所有 0.15 秒缓入出局; -o-transition:所有 0.15s 缓入缓出; -webkit-transition:所有 0.15s 缓入出局;过渡:所有 0.15 秒缓入出; }


Z
ZygD

我发现你可以这样做:

.submit .btn 输入 { 填充:11px 28px 12px 14px;背景:#004990;边框:无;颜色:#fff; } .submit .btn { 边框:无;颜色:#fff; font-family: 'Open Sans', sans-serif;字体大小:1em;最小宽度:96px;显示:内联块;位置:相对; } .submit .btn:after { content:">";宽度:6px;高度:17px;位置:绝对;右:36px;颜色:#fff;顶部:7px; }

您需要有一个 div 父级来获取填充和 :after。第一个父级需要是相对的,第二个 div 应该是绝对的,这样您就可以设置后面的位置。


佚名

概括

它不适用于 <input type="button">,但它适用于 <input type="checkbox">

小提琴http://jsfiddle.net/gb2wY/50/

HTML:

<p class="submit">
    <input id="submit-button" type="submit" value="Post">
    <br><br>
    <input id="submit-cb" type="checkbox" checked>
</p>

CSS:

#submit-button::before,
#submit-cb::before {
    content: ' ';
    background: transparent;
    border: 3px solid crimson;
    display: inline-block;
    width: 100%;
    height: 100%;
    padding: 0;
    margin: -3px -3px;
}

A
Alexander Gräf

虽然指出 Firefox 行为不允许 ::after 和 ::before 内容用于无法显示任何内容的元素的解释是非常正确的,但它似乎仍然可以很好地使用此规则:

input[type=checkbox] {
    -moz-appearance: initial;
}

由于 ::after 是在不引入更多和不相关的标记(如尾随跨度或标签)的情况下重新设置复选框或单选框的唯一方法,我认为强制 Firefox 允许显示 ::before 和 ::after 内容是可以的,尽管没有是规范。