8

Можно ли использовать псевдоэлементы :before или :after для полей ввода?

7

Я пытаюсь использовать псевдоэлемент CSS :after для поля input, но это не работает. Если я использую его с span, то всё нормально.

Вот мой код:

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

Это работает (добавляет смайлик после "buu!" и перед "some more"):

<span class="mystyle">buuu!</span>a some more

Однако это не работает — только цвет текста someValue становится красным, но смайлик не отображается:

<input class="mystyle" type="text" value="someValue">

Что я делаю не так? Должен ли я использовать другой псевдоселектор?

Примечание: я не могу добавить span вокруг моего input, так как это поле генерируется сторонним контролом.

5 ответ(ов)

0

Странно, но это действительно работает с некоторыми типами ввода. По крайней мере, в Chrome:

<input type="checkbox" />

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

<input type="radio" />

Проблема возникает только с type=text и некоторыми другими типами.

0

Наиболее распространенное недоразумение заключается в понимании слов «before» и «after». Эти слова не относятся к самому элементу, а к содержимому внутри элемента. Таким образом, element:before позиционируется перед содержимым, а element:after — после содержимого, но оба по-прежнему находятся внутри оригинального элемента.

Элемент input не имеет содержимого в контексте CSS, и, следовательно, не имеет псевдоконтента :before или :after. Это верно для многих других пустых или заменяемых элементов.

Не существует псевдоэлемента, который ссылался бы на что-то вне элемента.

В другой реальности эти псевдоэлементы могли бы называться как-то иначе, чтобы сделать это различие более понятным. И кто-то мог бы даже предложить псевдоэлемент, который действительно находился бы вне элемента. Но на данный момент в нашей реальности это не так.

0

Вы не можете использовать псевдоэлементы внутри элемента <input>, но вы можете использовать их в теневом элементе, например, в placeholder!

input[type="text"] {   
  &::-webkit-input-placeholder {
    &:before {
      // ваш код
    }
  }
}

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

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

input[type="text"]::-webkit-input-placeholder:before { // ваш код }
0

Рабочее решение на чистом CSS:

Фокус заключается в том, что нужно предположить наличие элемента DOM после текстового поля.

/*
 * Хитрость тут:
 * этот селектор говорит "возьми первый элемент DOM 
 * сразу после текстового поля ( + ) и установи его 
 * псевдоэлементу :before содержимое с заданным значением.
 */
input#myTextField + *:before {
  content: "👍";
}
<input id="myTextField" class="mystyle" type="text" value="someValue" />
<!--
  Можно добавить любой элемент после текстового поля, 
  не важно, что это (*), я просто использую его.
-->
<span></span>

(*) Ограниченное решение, однако:

  • необходимо надеяться, что сразу после текстового поля будет следующий элемент DOM,
  • нужно также, чтобы после вашего текстового поля не было других полей ввода.

Но в большинстве случаев мы знаем структуру нашего кода, поэтому это решение кажется эффективным, абсолютно на CSS и без использования jQuery.

0

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

Надеюсь, это поможет!

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь