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

时间:2010-04-06 19:28:08

标签: html css pseudo-element css-content

我正在尝试在:after字段上使用input 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">

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

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

21 个答案:

答案 0 :(得分:1206)

:before:after在容器内呈现

和&lt; input&gt;不能包含其他元素。


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

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

W3C规范

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

  

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

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

答案 1 :(得分:233)

Internet Explorer 7及其下的任何元素都不支持

:after:before

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

换句话说,纯粹的CSS 不可能

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

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

API docs on .after

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

答案 2 :(得分:58)

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

<input type="checkbox" />

工作正常,与

相同
<input type="radio" />

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

答案 3 :(得分:37)

Here's another approach(假设您已控制HTML):在输入后立即添加空<span></span>,并使用input.mystyle + span:after

在CSS中定位

&#13;
&#13;
.field_with_errors {
  display: inline;
  color: red;
}
.field_with_errors input+span:after {
  content: "*"
}
&#13;
<div class="field_with_errors">Label:</div>
<div class="field_with_errors">
  <input type="text" /><span></span> 
</div>
&#13;
&#13;
&#13;

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

答案 4 :(得分:36)

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

  

它不适用于自闭元素。

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

答案 5 :(得分:28)

我使用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

答案 6 :(得分:20)

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

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 }

答案 7 :(得分:14)

:after:before等伪元素仅适用于容器元素。在<input/><img>等单个位置开始和关闭的元素不是容器元素,因此不支持伪元素。将伪元素应用于<div>等容器元素后,如果检查代码(参见图像),您就可以理解我的意思了。实际上,伪元素是在容器元素内创建的。在<input><img>

的情况下,这是不可能的

enter image description here

答案 8 :(得分: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>

答案 9 :(得分:13)

纯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: "";
} 
<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>

(*)有限的解决方案:

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

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

答案 10 :(得分:4)

根据CSS 2.1规范中的note,规范“没有完全定义:替换元素(例如HTML中的IMG)之前和之后的交互。这将在未来的规范中更详细地定义。“虽然input不再是真正的替换元素,但基本情况没有改变::before:after的影响它没有具体说明,通常没有效果。

解决方案是找到解决此问题的不同方法。将生成的内容放入文本输入控件会非常误导:对于用户来说,它似乎是控件中初始值的一部分,但它不能被修改 - 因此它似乎是在开始时被强制的东西控制,但它不会作为表格数据的一部分提交。

答案 11 :(得分:4)

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

但是,如果::before::after,CSS工作组正在考虑明确允许inputappearance: none

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

  

Safari和Chrome都允许在表单输入上使用伪元素。   其他浏览器没有。我们考虑删除这个,但是   use-counter使用它来记录〜.07%的页面,这是我们最大的20倍   删除门槛。

     

实际上,在输入上指定伪元素需要指定   至少在某种程度上,投入的内部结构,我们还没有   设法做到了(我不相信我们*可以*做)。但是鲍里斯   建议,在其中一个bugthreads中,允许它出现:none   输入 - 基本上只是将它们转换为&lt; div&gt; s而不是   &#34;有点儿置换&#34;元件。

答案 12 :(得分:4)

尝试下一步:

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

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

答案 13 :(得分:3)

您必须在输入周围使用某种包装器才能使用前或后伪元素。这里是一个小提琴,它在输入的包装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;
}

答案 14 :(得分:1)

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

正如罗伯特·科里特尼克的回答所指出的,:之前和之后只能应用于容器元素,而输入元素不是容器。

但是,HTML 5引入了按钮元素,它是一个容器,其行为类似于输入[type =&#34; submit | reset&#34;]元素。

    <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>

答案 15 :(得分:1)

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

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

没有伪元素引用 元素。

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

答案 16 :(得分:1)

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

答案 17 :(得分:1)

<强>摘要

它不适用于<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;
}

答案 18 :(得分:0)

您可以使用jQuery在父块中使用元素之后或之前。 像这样:

$(yourInput).parent().addClass("error-form-field");

答案 19 :(得分:0)

我发现你可以这样做:

&#13;
&#13;
.submit .btn input
{
   padding:11px 28px 12px 14px;
   background:#004990;
   border:none;
    color:#fff;
}

 .submit .btn
 {
     border:none;
     color:#fff;
     font-family: 'Open Sans', sans-serif;
     font-size:1em;
     min-width:96px;
     display:inline-block;
     position:relative;
 }

.submit .btn:after
{
    content:">";
    width:6px;
    height:17px;
    position:absolute;
    right:36px;
    color:#fff;
    top:7px;
}
&#13;
<div class="submit">
  <div class="btn">
     <input value="Send" type="submit" />
  </div>
</div>
&#13;
&#13;
&#13;

你需要一个带有填充的div父级和:after。 第一个父亲需要是相对的,第二个div应该是绝对的,所以你可以设置后面的位置。

答案 20 :(得分:0)

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

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

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