Могу ли я использовать псевдоэлемент: before или: after в поле ввода? - PullRequest
624 голосов
/ 06 апреля 2010

Я пытаюсь использовать псевдоэлемент :after CSS в поле input, но он не работает. Если я использую его с 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, поскольку он генерируется сторонним элементом управления.

Ответы [ 20 ]

1216 голосов
/ 11 января 2011

:before и :after визуализация внутри контейнера

и не может содержать другие элементы.


Только псевдоэлементыбыть определенным (или, точнее, только поддерживаемым) на элементах контейнера.Потому что способ их визуализации - внутри самого контейнера как дочернего элемента.input не может содержать другие элементы, поэтому они не поддерживаются.button с другой стороны, это также элемент формы, поддерживает их, потому что это контейнер других подэлементов.

Если вы спросите меня, отображает ли эти два браузера эти двапсевдоэлементы на неконтейнерных элементах, это ошибка и нестандартное соответствие.Спецификация напрямую говорит о содержимом элемента ...

Спецификация W3C

Если мы внимательно прочитаем спецификацию , то на самом деле говорится, что они вставлены внутри aсодержащий элемент:

Авторы определяют стиль и расположение сгенерированного содержимого с помощью псевдоэлементов: before и: after.Как указывают их имена, псевдоэлементы: before и: after указывают местоположение содержимого до и после содержимого дерева документа элемента.Свойство content в сочетании с этими псевдоэлементами определяет, что вставляется.

Видите? дерево документа элемента содержимое .Насколько я понимаю, это означает в контейнере.

238 голосов
/ 07 апреля 2010

:after и :before не поддерживаются в Internet Explorer 7 и ниже ни для каких элементов.

Он также не предназначен для использования с заменяемыми элементами, такими как элементы формы (входы) и элементы изображения .

Другими словами это невозможно с чистым CSS.

Однако, если используется jquery Вы можете использовать

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

API документы на .after

, чтобы добавить свой контент с помощью JavaScript.Это будет работать во всех браузерах.

58 голосов
/ 24 декабря 2012

Как ни странно, он работает с некоторыми типами ввода.По крайней мере в Chrome

<input type="checkbox" />

работает нормально, так же, как

<input type="radio" />

Это просто type=text и некоторые другие, которые не работают.

38 голосов
/ 13 июля 2015

Вот еще один подход (при условии, что у вас есть контроль над 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>.

36 голосов
/ 13 января 2015

:before и :after применяются внутри контейнера, что означает, что вы можете использовать его для элементов с конечным тегом.

Не распространяется на самозакрывающиеся элементы.

В примечании стороны, элементы, которые являются самозакрывающимися (например, img / hr / input), также известны как «Замененные элементы», так как они заменяются соответствующим содержимым. «Внешние объекты» из-за отсутствия лучшего термина. Лучше читать здесь

28 голосов
/ 17 июня 2014

Я использовал 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

20 голосов
/ 14 ноября 2014

Вы не можете поместить псевдоэлемент в элемент ввода, но можете вставить теневой элемент, например заполнитель!

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

Чтобы он работал в других браузерах, используйте :-moz-placeholder, ::-moz-placeholder и :-ms-input-placeholder в разных селекторах .Невозможно сгруппировать селекторы, потому что, если браузер не распознает селектор, аннулирует весь оператор.

UPDATE : приведенный выше код работает только с препроцессором CSS (SASS, LESS...), без использования препроцессоров:

input[type="text"]::-webkit-input-placeholder:before { // your code }
14 голосов
/ 04 декабря 2017

Псевдоэлементы, такие как :after, :before, предназначены только для контейнерных элементов. Элементы, начинающиеся и закрывающиеся в одном месте, такие как <input/>, <img> и т. Д., Не являются контейнерными элементами и, следовательно, псевдоэлементы не поддерживаются. Как только вы примените псевдоэлемент к элементу контейнера, например <div>, и если вы проверите код (см. Изображение), вы поймете, что я имею в виду. На самом деле псевдоэлемент создается внутри элемента контейнера. Это невозможно в случае <input> или <img>

enter image description here

13 голосов
/ 29 октября 2017

Рабочее решение на чистом 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.

13 голосов
/ 02 ноября 2012

Я нашел этот пост, так как у меня была та же проблема, это было решение, которое работало для меня. В отличие от замены значения ввода, просто удалите его и разместите за ним промежуток того же размера, к нему можно применить псевдокласс :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>
...