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

mat*_*tra 648 html css pseudo-element css-content

我试图:afterinput字段上使用CSS伪元素,但它不起作用.如果我使用它span,它可以正常工作.

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

这是有效的(在"buu!"之后和"更多"之前放置笑脸)

<span class="mystyle">buuu!</span>a some more
Run Code Online (Sandbox Code Playgroud)

这不起作用 - 它只用红色调色someValue,但没有笑脸.

<input class="mystyle" type="text" value="someValue">
Run Code Online (Sandbox Code Playgroud)

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

注意:我不能添加span我的input,因为它是由第三方控件生成的.

Rob*_*nik 1249

:before:after在容器内渲染

并且<input>不能包含其他元素.


伪元素只能在容器元素上定义(或者更好地说只支持).因为它们的呈现方式容器本身内作为子元素.input不能包含其他元素因此不受支持.甲button在另一方面这也是一个表格元件支持它们,因为它的其他子元素的容器.

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

W3C规范

如果我们仔细阅读规范,它实际上说它们被插入包含元素中:

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

看到?元素的文档树内容.据我所知,这意味着容器内.

  • +1比接受的答案要好得多.感谢标准本身的清晰解释.对于`[required] :: before {content"*"; 红色; `:P (112认同)
  • 提示:如果您遇到的问题只是提交输入,例如`<input type ="submit"value ="Send"/>`,请使用`<button type ="submit">发送</ button>`代替.演示文稿是相同的,但`<button>`是一个容器,因此支持`:before`和`:after`. (90认同)
  • 怎么样`<hr />`?我认为它不是一个容器元素,但它可以渲染`:after`和`:before` http://jsfiddle.net/Uf88j/1/ (14认同)
  • @deathlock:这确实很有趣.我会说它必定是某种异常,我不会依赖它跨浏览器或交叉版本... HR不是容器元素因此不应该允许伪元素.甚至[W3C标准](http://www.w3.org/TR/html-markup/hr.html)说它允许**不**内容.如果你检查**void element**你[可以看到](http://www.w3.org/TR/html-markup/syntax.html#void-element)这些元素不应该有任何内容在任何情况下.伪元素是内容所以期望未来的浏览器版本无法显示它们. (7认同)
  • "*:before和:在容器内部渲染之后*":之前和之后的伪元素来自"**内容之前和之后**".不是"在容器的开头或结尾".*规范没有提到容器*.对于像'p`和`h1`这样的标签,内容在标签内,所以之前/之后也出现在内部.使用诸如`input`和`hr`之类的元素,:before和:after仍然会出现在内容之前或之后,但是没有涉及容器(特别是对于`input`).input:checked:before广泛用于表示通过css检查的复选框. (5认同)
  • @BoltClock今年阅读后我意识到我一定是高或某事 - 当然输入:检查:之前没有广泛使用,而是附带标签:之前是.我提供了不正确的信息,并且当时似乎相信它.我现在不敢在复选框上使用伪元素. (4认同)
  • @RadGH:评论的第一部分是合理的挑剔,但是1)`input`和`hr`是无效元素的定义,并且不可能有内容2)我很确定:在伪元素之前没有任何内容做你最后的陈述. (3认同)
  • 答案的逻辑是不正确的,正如您可以从CSS 2.1规范的[附录D](http://www.w3.org/TR/CSS2/sample.html)中看到的那样:它有一个规则,选择器`br:之前`.具有EMPTY声明的内容的元素仍然具有内容,它只是空的,并且您可以将事物附加到空字符串.没有禁止"输入:后"; 它只是没有实现,甚至没有很好地定义. (2认同)
  • @Radley Sustaire:[css-content-3](https://drafts.c​​sswg.org/css-content-3/#content-property)现在声明被替换的元素没有:: before或:: after之后,但是并没有说明表单元素是否被视为替换元素(我记得最近的一个对话指出HTML规范说它们实际上没有,这让我感到震惊).使用它的任何人 - 或者更糟糕的是*依赖它 - 不得测试或支持除Chrome以外的任何其他浏览器.当然,这并不奇怪. (2认同)

Ale*_*lex 239

:after并且:before在任何元素上都不支持Internet Explorer 7及更低版本.

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

换句话说,使用纯CSS 是不可能的.

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

$(".mystyle").after("add your smiley here");
Run Code Online (Sandbox Code Playgroud)

关于.after的API文档

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

  • 据我所知W3C`:after`和`:before`伪元素,它们只能放在容器元素上.为什么?因为它们在**内部附加**特定元素.`input`不是容器.例如,`button`就是你可以穿上它们.按预期工作.规范实际上说:*元素的文档树内容之前和之后*它明确地说**内容**.所以元素必须是一个容器. (249认同)
  • -1用于多余的IE版本和无用的jQuery插件 (108认同)
  • 下一个答案是更好的方式..给出实际的理由,而不是谈论IE 7(谁在乎)和jQuery(坏主意) (28认同)
  • 除非您构建的页面仅供您自己使用,否则大部分互联网仍会使用这些浏览器.w3c规范说这是肯定的; 但是你知道浏览器会对规范实施自己的解释.使用:输入之后只能在Opera 9+中使用,但由于它们在内部构建DOM的方式,因此不能在IE,FF,safari或chrome中实现 - 再次使用纯CSS无法完成. (3认同)
  • 我不确定4月是否会出现这种情况,但Webkit确实支持`:after`,尽管它不支持输入上的`:before`或`:after`. (3认同)

val*_*als 59

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

<input type="checkbox" />
Run Code Online (Sandbox Code Playgroud)

工作正常,同样如

<input type="radio" />
Run Code Online (Sandbox Code Playgroud)

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

  • 似乎并非如此,至少在2019年不是这样:https://jsfiddle.net/bq1knxgb/ (2认同)
  • @ANeves,它在 Chromium 中对我有用,但在 Firefox 中不起作用。 (2认同)

Bla*_*ger 40

这是另一种方法(假设您可以控制HTML):<span></span>在输入后添加一个空的右侧,并使用CSS中的目标input.mystyle + span:after

.field_with_errors {
  display: inline;
  color: red;
}
.field_with_errors input+span:after {
  content: "*"
}
Run Code Online (Sandbox Code Playgroud)
<div class="field_with_errors">Label:</div>
<div class="field_with_errors">
  <input type="text" /><span></span> 
</div>
Run Code Online (Sandbox Code Playgroud)

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

  • 为什么这个答案的赞成票这么少?我认为理论知识很重要,但这解决了问题。 (3认同)

Cat*_*rta 37

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

它不适用于自闭元素.

另一方面,自动关闭的元素(例如img/hr/input)也称为"替换元素",因为它们被各自的内容替换."外部对象"缺乏更好的术语.这里有更好的阅读


Vei*_*ger 31

我用它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
}
Run Code Online (Sandbox Code Playgroud)

在Codepen上查看


Sha*_*bus 20

你不能在输入元素中放置一个伪元素,但可以放入阴影元素,就像占位符一样!

input[type="text"] {   
  &::-webkit-input-placeholder {
    &:before {
      // your code
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

input[type="text"]::-webkit-input-placeholder:before { // your code }
Run Code Online (Sandbox Code Playgroud)

  • 太好了!请注意,占位符伪元素具有有限的属性支持:颜色,背景,字间距,字母间距,文本修饰,垂直对齐,文本转换,行高,文本缩进,不透明度.见http://css-tricks.com/almanac/selectors/p/placeholder/ (3认同)
  • 关于此操作不再起作用的一些背景信息:https://bugs.chromium.org/p/chromium/issues/detail?id=582301 (2认同)

小智 15

纯CSS中的工作解决方案:

诀窍是假设文本字段后面有一个dom元素.

/*
 * The trick is here:
 * this selector says "take the first dom element after
 * the input text (+) and set its before content to the
 * value (:before).
 */
input#myTextField + *:before {
  content: "";
} 
Run Code Online (Sandbox Code Playgroud)
<input id="myTextField" class="mystyle" type="text" value="someValue" />
<!--
  There's maybe something after a input-text
  Does'nt matter what it is (*), I use it.
  -->
<span></span>
Run Code Online (Sandbox Code Playgroud)

(*)有限的解决方案:

  • 你必须希望有一个以下的dom元素,
  • 你必须希望输入字段后面没有其他输入字段.

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

  • `输入#myTextField~span:之前{`好多了,但是span应该有一个类更真实,比如`.tick`或`.icon` (2认同)

Pon*_*man 14

像伪元素一样:after,:before仅用于容器元素.开始和在一个地方如关闭元件<input/>,<img>等不是容器元素,因此伪构件不被支持.将伪元素应用于容器元素之后<div>,如果检查代码(请参见图像),您就可以理解我的意思了.实际上,伪元素是在容器元素内创建的.在<input>或的情况下这是不可能的<img>

在此输入图像描述


Mor*_*ney 13

我找到了这篇文章,因为我遇到了同样的问题,这是对我有用的解决方案.与替换输入的值相反,只需将其删除并绝对在其后面放置一个相同大小的跨度,跨度可以使用: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>
Run Code Online (Sandbox Code Playgroud)


CSS*_*ner 8

问题提到“输入字段”。尽管我相信OP指的是type=text的输入字段,::after并且::beforepseudocontent确实呈现了几种不同类型的输入字段:

input::before {
    content: "My content" /* 11 different input types will render this */
}    
Run Code Online (Sandbox Code Playgroud)

这是所有输入类型的综合演示,清楚地显示了哪些输入类型与(在本例中)伪元素兼容。::before

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

  1. 复选框
  2. 颜色
  3. 日期
  4. 日期时间本地
  5. 文件
  6. 图像
  7. 收音机
  8. 范围
  9. 时间
  10. 星期

  • 到目前为止,FireFox 尚不支持(版本 102) (2认同)

Juk*_*ela 5

根据CSS 2.1规范中的注释,该规范“未完全定义:before和:after与替换元素(例如HTML中的IMG)的交互。这将在更详细的在未来的规范来定义“虽然,input是不是一个真正的替换元素更多,基本态势没有改变:效果:before:after未指定就可以了,一般没有影响。

解决方案是找到另一种方法来解决您要解决的问题。将生成的内容放入文本输入控件中会产生很大的误导性:对用户而言,它似乎是控件中初始值的一部分,但无法修改-因此,它似乎是在开始时就被强制执行的操作。控件,但它不会作为表单数据的一部分提交。

  • 这是一个评论,而不是一个答案-相当长的评论,但仍然是一个评论。 (3认同)

Ori*_*iol 5

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

然而,CSS工作组正在考虑明确允许::before::after万一inputappearance: none

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

Safari和Chrome都允许在表单输入中使用伪元素。其他浏览器则没有。我们曾考虑删除它,但是使用计数器正在记录使用它的〜.07%页面,这是我们最大删除阈值的20倍。

实际上,在输入上指定伪元素将需要至少指定输入的内部结构,而我们尚未设法做到这一点(我不确定我们可以做到)。但鲍里斯(Boris)建议,在其中一个bug线程中,允许其出现:无输入-基本上只是将它们转换为<div>,而不是“ kinda替换”元素。


Ale*_*kin 5

尝试下一步:

label[for="userName"] {
  position: relative;
}

label[for="userName"]::after {
  content: '[after]';
  width: 22px;
  height: 22px;
  display: inline-block;
  position: absolute;
  right: -30px;
}
Run Code Online (Sandbox Code Playgroud)
<label for="userName">
	Name: 
	<input type="text" name="userName" id="userName">
	</label>
Run Code Online (Sandbox Code Playgroud)


Man*_*ngo 5

这里最大的误区,就是这些词的含义beforeafter。它们不是指元素本身,而是指元素中的内容。所以,element:before是之前的内容,并且element:after是内容之后,但两者仍然是原来的元素中。

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

没有伪元素引用元素外部

在不同的宇宙中,这些伪元素可能被称为其他名称,以使这种区分更加清晰。甚至有人可能提出了一个伪元素,而该伪元素确实在元素之外。到目前为止,在这个宇宙中情况并非如此。

  • @Chris 这让我和其他一些人在搜索时感到惊讶。我认为这是一个怪癖。从 CSS 的角度来看,“hr”一直是含糊不清的,尽管您在讨论颜色时会更多地看到这一点。 (2认同)