790

我正在尝试:after在字段上使用 CSS 伪元素input,但它不起作用。如果我将它与 a 一起使用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在 my 周围添加 a input,因为它是由第三方控件生成的。

4

22 回答 22

1469

:before:after在容器内渲染

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


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

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

W3C 规范

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

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

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

于 2011-01-11T17:18:28.543 回答
286

:after并且:before在 Internet Explorer 7 及更低版本中不受任何元素的支持。

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

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

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

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

.after 上的 API 文档

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

于 2010-04-07T10:01:42.930 回答
68

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

<input type="checkbox" />

工作正常,与

<input type="radio" />

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

于 2012-12-24T09:56:56.990 回答
56

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

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

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

于 2015-07-13T20:25:39.393 回答
48

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

它不适用于自闭合元素。

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

于 2015-01-13T12:25:24.020 回答
40

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

在 Codepen 上查看

于 2014-06-17T11:40:46.037 回答
32

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

在此处输入图像描述

于 2017-12-04T11:20:32.823 回答
28

before这里最大的误解是和的意思after。它们不是指元素本身,而是指元素中的内容element:before内容之前和内容之后也是如此element:after,但两者仍然在原始元素内。

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

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

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

于 2019-02-17T03:37:12.177 回答
23

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

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 }
于 2014-11-13T21:10:17.583 回答
21

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

于 2017-10-29T08:45:17.370 回答
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>
于 2012-11-02T10:38:42.833 回答
5

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

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

于 2013-10-14T11:00:57.160 回答
5

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

然而,CSS 工作组正在考虑明确允许::before::after以防万一inputhas appearance: none.

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

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

实际上在输入上指定伪元素至少需要在某种程度上指定输入的内部结构,我们还没有设法做到(而且我不相信我们*可以*做到)。但鲍里斯建议,在其中一个错误线程中,允许它出现在外观:无输入 - 基本上只是将它们变成 <div>,而不是“有点替换”元素。

于 2016-03-17T22:47:49.843 回答
4

您必须在输入周围使用某种包装器才能使用 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;
}
于 2014-12-19T15:25:23.357 回答
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>

于 2016-11-06T10:04:20.153 回答
2

如果您尝试使用 :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>
于 2015-12-31T01:46:06.343 回答
1

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

于 2017-02-10T13:42:05.010 回答
1

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

.fm-form-control {
  position: relative;
  margin-top: 25px;
  margin-bottom: 25.2px;
}


.fm-switcher {
  display: none;
}
.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 {
  cursor: not-allowed;
}
.fm-switcher[disabled] + .fm-placeholder-switcher:before {
  background-color: #cbd0d3;
}
.fm-switcher[disabled] + .fm-placeholder-switcher:after {
  background-color: #eaeded;
  border-color: #cbd0d3;
}

.fm-placeholder-switcher {
  padding-left: 53px;
  cursor: pointer;
  line-height: 24px;
}
.fm-placeholder-switcher:before {
  position: absolute;
  content: '';
  left: 0;
  top: 50%;
  width: 20px;
  height: 20px;
  margin-top: -10px;
  margin-left: 2px;
  background-color: #2980b9;
  z-index: 2;
  -moz-transition: all 0.15s ease-in-out;
  -o-transition: all 0.15s ease-in-out;
  -webkit-transition: all 0.15s ease-in-out;
  transition: all 0.15s ease-in-out;
  border-radius: 12px;
}
.fm-placeholder-switcher:after {
  position: absolute;
  content: '';
  left: 0;
  top: 50%;
  width: 48px;
  height: 20px;
  margin-top: -12px;
  background-color: #ffffff;
  z-index: 1;
  border-radius: 12px;
  border: 2px solid #bdc3c7;
  -moz-transition: all 0.15s ease-in-out;
  -o-transition: all 0.15s ease-in-out;
  -webkit-transition: all 0.15s ease-in-out;
  transition: all 0.15s ease-in-out;
}
<div class='fm-form-control'>
  <input class='fm-switcher' id='switcher_id' type='checkbox'>
  <label class='fm-placeholder-switcher' for='switcher_id'>
    Switcher
  </label>
</div>

于 2021-09-28T11:46:43.543 回答
0

我发现你可以这样做:

.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;
}
<div class="submit">
  <div class="btn">
     <input value="Send" type="submit" />
  </div>
</div>

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

于 2014-12-02T14:28:35.353 回答
0

概括

它不适用于<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;
}
于 2016-11-10T08:56:33.423 回答
0

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

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

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

于 2021-03-19T12:38:37.467 回答
0

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

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

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

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

  1. 复选框
  2. 颜色
  3. 日期
  4. 本地日期时间
  5. 文件
  6. 图片
  7. 收音机
  8. 范围
  9. 时间
  10. 星期
于 2022-02-15T18:25:55.033 回答