Чи можу я використовувати: перед або: після псевдоелемента у полі введення?


686

Я намагаюся використовувати :afterпсевдоелемент CSS у inputполі, але це не працює. Якщо я використовую його з a span, він працює добре.

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

Це працює (ставить смайлик після "бу!" І перед "ще трохи")

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

Це не працює - воно лише забарвлює певну варію в червоний колір, але смайлика немає.

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

Що я роблю неправильно? чи варто використовувати інший псевдоселектор?

Примітка. Я не можу додати spanнавколо себе input, оскільки він генерується стороннім керуванням.


Якщо ви абсолютно ніякого контролю над HTML, спробуйте змінюючи border-colorз inputзамість. Я вважаю, що це привертає більше уваги.
Blazemonger

Відповіді:


255

:afterі :beforeне підтримуються в Internet Explorer 7 і під будь-якими елементами.

Він також не призначений для використання на замінених елементах, таких як елементи форми (входи) та елементи зображення .

Іншими словами, з чистим CSS це неможливо .

Однак якщо ви використовуєте jquery, ви можете використовувати

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

Документи API на. Далі

Щоб додати свій вміст за допомогою JavaScript. Це працюватиме в усіх браузерах.


Алекс, я використовую IE8 та останню версію FF, тому IE7 - це не проблема. Я шукав будь-яку документацію про обмеження: після, але не зміг її знайти. w3.org/TR/CSS2/generate.html стверджує, що він вставляється після поточного вузла в дереві документів, тому він повинен працювати в обох випадках.
матра

3
Якщо ви не створюєте сторінку лише для власного використання, великий відсоток Інтернету все ще використовує ці браузери. Специфікація w3c каже це так; але, як ви добре знаєте, браузери реалізують власну інтерпретацію специфікації. Використання: after на вході буде працювати лише в Opera 9+, але не реалізовано в IE, FF, safari або chrome через те, як вони внутрішньо будують DOM - це знову не можна зробити з чистим CSS.
Олексій

3
Я не впевнений , якщо це було в квітні, але Webkit робить підтримку :afterв цілому, хоча він не підтримує ні :beforeабо :afterна входах.
coreyward

258
Наскільки я розумію елементи W3C :afterта :beforeпсевдо, вони можуть бути розміщені лише на контейнерних елементах. Чому? Тому що вони додаються всередині цього конкретного елемента. inputне є контейнером. buttonнаприклад, отже, ви можете надіти їх. Працює як очікувалося. Специфікація насправді говорить: до та після вмісту дерева елемента елемента в ньому прямо вказано ЗМІСТ . Отже, елементом повинен бути контейнер.
Роберт Коритник

29
Наступна відповідь - це набагато краще. Наводить фактичну причину, а не говорити про IE 7 (кого байдуже) та jQuery (погана ідея)
Rowan

1305

:beforeі :afterвізуалізувати всередині контейнера

та <input> не можуть містити інших елементів.


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

Якщо ви запитаєте мене, якщо якийсь - то браузер робить відображати ці два псевдо-елементи, що не мають відношення елементів контейнера, це помилка і нестандартним відповідність. Специфікація безпосередньо говорить про вміст елементів ...

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

Якщо ми уважно читаємо специфікацію, то насправді йдеться про те, що вони вставлені всередині елемента, що містить:

Автори визначають стиль та розташування створеного контенту за допомогою: перед та: після псевдоелементів. Як вказують їх назви, псевдоелементи: до та: після вказують розташування вмісту до та після вмісту дерева документа. Властивість "content" спільно з цими псевдоелементами визначає, що вставлено.

Подивитися? вміст дерева документа елемента . Як я розумію, це означає в контейнері.


119
+1 Набагато краще прийнятої відповіді. Дякую за чітке пояснення самого стандарту. Стільки за [required]::before { content "*"; color: red; }: P
Кевін Пено

93
Порада. Якщо у вас виникають проблеми з лише введенням даних <input type="submit" value="Send"/>, <button type="submit">Send</button>натомість скористайтеся . Презентація ідентична, але <button>є контейнером і, таким чином, підтримує :beforeі :after.
грип

15
Про що <hr />? Я подумав, що це не контейнерний елемент, але він може відобразити :afterі :before jsfiddle.net/Uf88j/1
смертельна

7
@deathlock: це справді цікаво. Я б сказав, що це повинна бути якась аномалія, і я б не покладався на це, працюючи між браузером або перехресними версіями ... HR не є елементом контейнера, отже, не слід допускати псевдоелементів. Навіть стандарт W3C говорить, що він не дозволяє вмісту. І якщо ви перевірите наявність недійсних елементів, ви можете побачити, що ці елементи не повинні містити жодного вмісту ні за яких обставин. Псевдоелементи є вмістом, тому очікуйте, що майбутня версія браузера не відображатиме їх.
Роберт Коритник

5
" : до і: після візуалізації всередині контейнера " Елементи: до і: після того, як псевдоелементи надходять " до і після вмісту ". Не "на початку чи в кінці" контейнера. Специфікація не згадує контейнер . З такими тегами, як pі h1, вміст знаходиться в тезі, тому до / після відображається також всередині. З такими елементами, як inputі hr,: до і: після, як і раніше, з’являться до або після вмісту, але контейнер не задіяний (особливо для input). Вхід: Позначено: раніше широко використовується для позначення прапорців, що перевіряються через css.
Radley Sustaire

60

Як не дивно, він працює з деякими типами введення. Принаймні в Chrome,

<input type="checkbox" />

працює чудово, так само, як

<input type="radio" />

Просто type=textі деякі інші не працюють.


1
@ANeves, він працював у Chromium для мене, але не у Firefox.
kcpr

45

Ось ще один підхід (якщо припустити, що ви керуєте 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>.


1
Це дозволяє додавати при наведенні курсору миші дії, як: input:hover+span:after{color: blue}. Оновлення
krassowski

2
Чому ця відповідь має так мало відгуків? Я думаю, що теоретичні знання важливі, але це вирішує проблему.
jorgefpastor

Хороший варіант піти з тим, щоб вирішити проблему.
Шут

39

:beforeі :afterзастосовуються всередині контейнера, що означає, що ви можете використовувати його для елементів із кінцевою міткою.

Він не застосовується до елементів, що закриваються.

У бічній примітці елементи, які самозамикаються (наприклад, img / hr / input), також відомі як "Замінені елементи", оскільки вони замінені відповідним вмістом. "Зовнішні об'єкти" за відсутністю кращого терміну. Краще читайте тут


Ця відповідь правильна, стисла і містить важливий контекст. Повинен бути на вершині, imo.
Павло

32

Я використовував 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

Ви не можете помістити псевдоелемент у вхідний елемент, але можна поставити тіньовий елемент, як заповнювач!

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 }

3
Приємно! Зауважте, що псевдоелемент заповнювача заповнення має обмежену підтримку властивостей: колір, тло, інтервал між словами, інтервал між літерами, оформлення тексту, вертикальне вирівнювання, перетворення тексту, висота рядка, відступ тексту, непрозорість. Дивіться css-tricks.com/almanac/selectors/p/placeholder
henry

Дякую за підказку. Просто пам’ятайте, що всередині псевдоелемента зникне, коли поле введення буде заповнене користувачем. Це проблема UX, якщо все, що ви хотіли, як я, показувало glyphicon-searchбез торкання розмітки.
Даві Ліма

2
Деякі контексти щодо того, чому це більше не працює: bugs.chromium.org/p/chromium/isissue/detail?id=582301
Олівер Джозеф Еш

17

Псевдо елементи , такі як :after, :beforeтільки для елементів контейнера. Елементи, що починаються і закриваються в одному місці, наприклад <input/>, <img>тощо, не є контейнерними елементами, отже, псевдоелементи не підтримуються. Як тільки ви застосуєте псевдоелемент до елемента контейнера, як <div>і якщо ви оглянете код (див. Зображення), ви зможете зрозуміти, що я маю на увазі. Насправді псевдоелемент створюється всередині елемента контейнера. Це неможливо у випадку <input>або<img>

введіть тут опис зображення


15

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


2
input#myTextField ~ span:before {набагато краще, але в прольоті повинен бути клас, щоб він був більш чітким, наприклад, .tickабо.icon
Вал

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>

1
+1 - Це рішення добре працює, якщо ви використовуєте плагін або фреймворк, який автоматично додає класи перевірки до самого елемента, але не до батьківської мітки.
Blazemonger

9

Найбільшим нерозумінням тут є значення слів beforeі after. Вони НЕ відносяться до самого елементу, але і до змісту в елементі. Так element:beforeє і перед змістом, іelement:after після змісту, але обидва все ще знаходяться всередині початкового елемента.

inputЕлемент не має вмісту в поданні CSS, і так не має :beforeабо :afterвміст псевдо. Це стосується багатьох інших недійсних або замінених елементів.

Немає жодного псевдоелемента, що посилається на зовнішній елемент.

В іншому Всесвіті ці псевдоелементи могли бути названі чимось іншим, щоб зробити це розрізнення зрозумілішим. А хтось навіть міг запропонувати псевдоелемент, який справді знаходиться поза елементом. Поки що це не так у цьому Всесвіті.


Я не можу зрозуміти, що ти маєш на увазі, але якщо я це роблю, псевдоелементи працюють на hr? jsfiddle.net/demetriad/o49yn5hq
Кріс

1
@Chris Це стає для мене несподіванкою та пошуком деяких інших. Я думаю, що це вигадка. hrзавжди був неоднозначним з точки зору CSS, хоча ви більше бачите в обговоренні кольору.
Манго

5

Згідно з приміткою до специфікації CSS 2.1, специфікація "не повністю визначає взаємодію: до та: після із заміненими елементами (наприклад, IMG в HTML). Це буде визначено більш детально в майбутній специфікації ». Хоча inputнасправді вже не замінений елемент, основна ситуація не змінилася: ефект :beforeі :afterна нього не визначений і, як правило, не впливає.

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


3
Це коментар, не відповідь - досить довгий коментар, але все-таки коментар.
Blazemonger

@Blazemonger, не зовсім зрозуміло, про що було питання, але у будь-якому випадку ця відповідь стосується того ж питання, що і прийнята відповідь, але більш правильним способом. Це не неможливо використовувати генерований контент для inputелементів, просто невизначених і браузерних залежності.
Jukka K. Korpela

5

Як пояснили інші, inputs - це ніщо не замінені недійсні елементи, тому більшість браузерів не дозволять вам генерувати ::beforeні ::afterпсевдоелементи в них.

Однак Робоча група CSS розглядає можливість прямого дозволу ::beforeта ::afterна випадок, якщо inputє appearance: none.

Від https://lists.w3.org/Archives/Public/www-style/2016Mar/0190.html ,

І Safari і Chrome дозволяють псевдоелементам вводити форму. Інші веб-переглядачі не мають. Ми намагалися видалити це, але лічильник використання записує ~ .07% сторінок, які використовують його, що становить 20 разів наш максимальний поріг видалення.

Власне кажучи, псевдоелементи на входах вимагатимуть хоч дещо уточнити внутрішню структуру входів, що нам ще не вдалося зробити (і я не впевнений, що ми можемо * зробити). Але Борис запропонував, в одному з помилок, дозволити це на вигляд: жодних входів - в основному просто перетворення їх на <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>


3

Ви повинні мати якусь обгортку навколо входу, щоб використовувати псевдоелемент до або після. Ось загадка, на якій розміщено раніше, на обгортковому розділі введення, а потім розміщується попереднє всередині входу - або, принаймні, воно виглядає так. Очевидно, що це робота навколо, але ефективна вкрай, і вона піддається чуйності. Ви можете легко зробити це після, якщо вам потрібно помістити якийсь інший вміст.

Робоча скрипка

Знак долара всередині введення як псевдоелемент: 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;
}

Хороший трюк, але ви можете зробити поділ, стилізований для "продовження" введення. Дивіться цю скрипку jsfiddle.net/ose4r8uj/31 Але ви також можете зробити це простіше, використовуючи bootstrap: getbootstrap.com/css/#forms-control-validation шукайте частину "З необов’язковими піктограмами". Хоча це не має нічого спільного з початковим питанням.
Віктор Івенс

1
FYI не корисний для: фокусування
,:

2

Якщо ви намагаєтеся ввести елемент вводу за допомогою: до і після, шанси, ви намагаєтесь імітувати ефекти інших span, div або навіть елементів у вашому стеку CSS.

Як вказується у відповіді Роберта Коритника,: до та після, якщо їх можна застосувати лише до елементів контейнерів, а вхідні елементи не є контейнерами.

ЗАРАЗ, HTML 5 представив елемент кнопки, який є контейнером, і веде себе як елемент введення [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>

HTML 4 фактично представив елемент <кнопка>.
Містер Лістер,

1

Підсумок

Це не працює <input type="button">, але добре працює <input type="checkbox">.

Fiddle : 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

Я виявив, що ви можете це зробити так:

Потрібно мати батьків-дів, який приймає padding та:: after. Перший батько повинен бути відносним, а другий діл повинен бути абсолютним, щоб ви могли встановити позицію після.


-1

У мене є інша ідея використовувати це замість цього:

<div>
<input type="text"></input>text can be entered here</div>

Автор запитання прямо заявив, що вони не в змозі змінити розмітку HTML. Ця відповідь не має сенсу. Можливо, це слід було б замінити, а не редагувати, @Morpheus.
Палець
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.