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

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

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

это работает (ставит смайлик после "Буу! и перед "еще немного")

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

это не работает - он только окрашивает someValue в красный цвет, но нет смайлика.

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

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

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

19 ответов


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

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

иными словами,невозможно С чистым CSS.

при использовании в jQuery можно использовать
$(".mystyle").after("add your smiley here");

API docs on .после

добавить свой содержание с javascript. Это будет работать во всех браузерах.


:before и :after рендеринг внутри контейнера

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


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

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

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

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

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

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


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

<input type="checkbox" />

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

<input type="radio" />

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


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


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

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

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


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


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

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

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

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

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

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

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


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

enter image description here


По словам Примечание в спецификации CSS 2.1 спецификация " не полностью определяет взаимодействие: до и: после с замененными элементами (такими как IMG в HTML). Это будет определено более подробно в будущей спецификации.- Хотя! .. --0--> на самом деле больше не является замененным элементом, основная ситуация не изменилась: эффект :before и :after на нем в неуказанном и вообще не имеет никакого эффекта.

решение найти другую подход к проблеме, которую вы пытаетесь решить таким образом. Положить контент в текстовый входной контроль будут вводить в заблуждение: для пользователя, казалось бы, часть первоначальной стоимости в контроле, но он не может быть изменен – так было бы чему-то принуждают в начале контроля, но еще не было бы представлено в рамках данных форм.


как и другие, пояснила, inputs являются своего рода замененными элементами void, поэтому большинство браузеров не позволят вам генерировать ::before, ни ::after псевдо-элементы в них.

однако рабочая группа CSS рассматривает возможность явного разрешения ::before и ::after в случае input и appearance: none.

от https://lists.w3.org/Archives/Public/www-style/2016Mar/0190.html,

Safari и Chrome позволяют псевдо-элементы на их форма входа. Другие браузеры этого не делают. Мы рассматривали удаление этого, но использование-счетчик записи ~.07% из страниц используя его, которое 20x наше максимальное порог удаления.

фактически указание псевдоэлементов на входах потребует указания внутренняя структура входов по крайней мере то, что мы не удалось сделать еще (и я не уверен, что мы * можем * сделать). Но Борис предложил, в одном из bugthreads, позволяя ему по внешнему виду:нет входы-в основном просто превращение их в S, а не "своего рода замененные" элементы.


вы должны иметь какую-то оболочку вокруг ввода, чтобы использовать псевдо-элемент до или после. Вот скрипка, которая имеет перед на обертке div ввода, а затем помещает перед внутри ввода - или, по крайней мере, выглядит так. Очевидно, что это работа вокруг, но эффективна в крайнем случае и поддается реагированию. Вы можете легко сделать это после, если вам нужно поместить какой-то другой контент.

Рабочая Скрипку

знак доллара внутри входа в качестве псевдоэлемента: 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;
}

попробуйте следующее:

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>

Если вы пытаетесь стиль входной элемент :before и :after, скорее всего, вы пытаетесь имитируйте эффекты других span, div или даже элементов в вашем стеке CSS.

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

однако HTML 5 представил элемент, который является контейнером и ведет себя как 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>

резюме

не работает с <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;
}

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


Я нашел, что вы можете сделать это так:

.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, который принимает заполнение и: после. Первый родитель должен быть относительным,а второй div должен быть абсолютным, чтобы вы могли установить положение после.


вы можете использовать элемент after или before в родительском блоке с помощью jQuery. вот так:

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