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

问题描述 投票:615回答:20

我试图在: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,因为它是由第三方控件生成的。

html css pseudo-element css-content
20个回答
236
投票

Internet Explorer 7及以下版本不支持:after:before

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

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

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

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

API docs on .after

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


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。


5
投票

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

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


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

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


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>

4
投票

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

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

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

在不同的宇宙中,这些伪元素可能被称为其他东西,以使这种区分更清晰。有人甚至可能提出了一个真正在元素之外的伪元素。到目前为止,这个世界并非如此。


3
投票

您必须在输入周围使用某种包装器才能使用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;
}

1
投票

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

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

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

1
投票

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


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应该是绝对的,所以你可以设置后的位置。


1233
投票

:before:after在容器内渲染

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


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

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

W3C规范

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

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

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


0
投票

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

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

58
投票

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

<input type="checkbox" />

工作正常,同样如

<input type="radio" />

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


38
投票

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

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


36
投票

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

它不适用于自闭元素。

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


29
投票

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


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 }

14
投票

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

enter image description here


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>
© www.soinside.com 2019 - 2024. All rights reserved.