Dopasowywanie pustego pola wejściowego za pomocą CSS

141

Jak zastosować styl do pustego pola wprowadzania? Jeśli użytkownik wpisze coś w polu wejściowym, styl nie powinien już być stosowany. Czy to możliwe w CSS? Próbowałem tego:

input[value=""]
Sjoerd
źródło

Odpowiedzi:

159

Gdyby tylko pole było required, mógłbyś iśćinput:valid

#foo-thing:valid + .msg { visibility: visible!important; }      
 <input type="text" id="foo-thing" required="required">
 <span class="msg" style="visibility: hidden;">Yay not empty</span>

Zobacz na żywo na jsFiddle

LUB #foo-thing:invalidzaneguj użycie (kredyt dla @SamGoody)

lukmdo
źródło
14
..lub zaneguj, używając: invalid {} developer.mozilla.org/en-US/docs/Web/CSS/…
SamGoody
6
Chcę tego samego, ale moje pole nie jest wymagane. czy jest jakiś sposób, aby to zrobić?
Zahidul Islam Ruhel
1
To genialne :)
kriskodzi
@ZahidulIslamRuhel oczywiście ta odpowiedź nie powinna być pierwszą. zobacz odpowiedź poniżej stackoverflow.com/a/35593489/11293716
sijanec
150

W nowoczesnych przeglądarkach możesz użyć :placeholder-showndo kierowania na puste dane wejściowe (nie mylić z ::placeholder).

input:placeholder-shown {
    border: 1px solid red; /* Red border only if the input is empty */
}

Więcej informacji i obsługa przeglądarek: https://css-tricks.com/almanac/selectors/p/placeholder-shown/

Berend
źródło
4
To wspaniale! Bardzo pomocny :)
unbreak
1
@TricksfortheWeb Wydaje się, że w znaczniku wejściowym musi znajdować się atrybut zastępczy (z wartością). Przetestowano w Chrome - nie jestem pewien, czy to się liczy dla wszystkich przeglądarek.
Berend
9
Należy ustawić atrybut zastępczy. W każdym razie możemy ustawić atrybut zastępczy jako biały znak.
Barcelonczyk
2
@Amanpreet Według caniuse.com/#search=placeholder , to nie zadziała ani w IE 11 (ani w Edge).
Tim Malone,
4
W ogóle nieobsługiwane w przeglądarkach Microsoft: caniuse.com/#feat=css-placeholder-shown
Lounge9
44

W CSS nie ma selektora, który to robi. Selektory atrybutów pasują do wartości atrybutów, a nie do obliczonych wartości.

Musiałbyś użyć JavaScript.

Quentin
źródło
3
Dla każdego, kto później znajdzie tę odpowiedź: Quentin ma rację co do obliczanych wartości, jednak istnieje: pusty selektor, którego można użyć tutaj i który ma rozsądne wsparcie (wszystkie przeglądarki z wyjątkiem IE8 i starszych według: w3schools.com/cssref/sel_empty.asp
Cohen
35
:emptyselektor działa tylko na pustych elementach, czyli tylko na elementach, które mają znacznik otwierający i zamykający, który jest pusty pomiędzy, oraz pojedyncze elementy, które są uważane za zawsze puste, na przykład , więc nie można go używać na elementach wejściowych, z wyjątkiemtextarea
am05mhz
7
Nie prawda. Zobacz odpowiedź Lukmo poniżej. Połączenie wymaganego atrybutu i pseudoselektorów: valid lub: invalid zapewnia właśnie to.
voidstate
2
To była poprawna odpowiedź w momencie zadawania pytania. Wymagany atrybut był dostępny tylko w Chrome i Firefox w 2011 r., A ta odpowiedź pochodzi z 2010 r. Jednak czasy się zmieniły i nie jest to już „najlepsza” odpowiedź, więc odznaczyłem ją jako zaakceptowaną.
Sjoerd
18

Aktualizacja wartości pola nie aktualizuje jego atrybutu wartości w DOM, dlatego Twój selektor zawsze pasuje do pola, nawet jeśli nie jest ono w rzeczywistości puste.

Zamiast tego użyj invalidpseudoklasy, aby osiągnąć to, co chcesz, na przykład:

input:required {
  border: 1px solid green;
}
input:required:invalid {
  border: 1px solid red;
}
<input required type="text" value="">

<input required type="text" value="Value">

Kudłaty
źródło
15

input[value=""], input:not([value])

pracuje z:

<input type="text" />
<input type="text" value="" />

Ale styl nie zmieni się, gdy tylko ktoś zacznie pisać (potrzebujesz do tego JS).

Draco Ater
źródło
1
Niepewny, ponieważ atrybut wartości nie zmienia się w DOM po edycji pola. Jednak niezła sztuczka, jeśli się tym nie przejmujesz - i działa w najnowszych Safari, Chrome, FF i IE ...
Dunc
9
Aby dopasować to pierwsze, możesz użyć input[value=""], input:not([value]).
Schizma
10

Jeśli nie jest potrzebne wspieranie starszych przeglądarek, można użyć kombinacji required, validi invalid.

Dobrą rzeczą w używaniu tego jest to, że pseudoelementy validi invaliddobrze współpracują z atrybutami typu pól wejściowych. Na przykład:

input:invalid, textarea:invalid { 
    box-shadow: 0 0 5px #d45252;
    border-color: #b03535
}

input:valid, textarea:valid {
    box-shadow: 0 0 5px #5cd053;
    border-color: #28921f;
}
<input type="email" name="email" placeholder="[email protected]" required />
<input type="url" name="website" placeholder="http://johndoe.com"/>
<input type="text" name="name" placeholder="John Doe" required/>

Dla odniesienia, JSFiddle tutaj: http://jsfiddle.net/0sf6m46j/

Mój stos przepełniony
źródło
7
$('input#edit-keys-1').blur(function(){
    tmpval = $(this).val();
    if(tmpval == '') {
        $(this).addClass('empty');
        $(this).removeClass('not-empty');
    } else {
        $(this).addClass('not-empty');
        $(this).removeClass('empty');
    }
});

w jQuery. Dodałem klasę i stylizowałem za pomocą css.

.empty { background:none; }
Israel Morales
źródło
6

To zadziałało dla mnie:

W przypadku kodu HTML dodaj requiredatrybut do elementu wejściowego

<input class="my-input-element" type="text" placeholder="" required />

W przypadku CSS użyj :invalidselektora, aby wskazać puste wejście

input.my-input-element:invalid {

}

Uwagi:

  • Informacje requiredz witryny w3Schools.com : „Jeśli jest obecny, określa, że ​​przed przesłaniem formularza należy wypełnić pole wejściowe”.
Ariella
źródło
2

To pytanie mogło zostać zadane jakiś czas temu, ale ponieważ niedawno trafiłem na ten temat, szukając walidacji formularzy po stronie klienta, a :placeholder-shown wsparcie jest coraz lepsze, pomyślałem, że poniższe informacje mogą pomóc innym.

Korzystając z pomysłu Berenda, polegającego na użyciu tej pseudoklasy CSS4, udało mi się stworzyć walidację formularza uruchamianą dopiero po zakończeniu wypełniania przez użytkownika.

Oto ademo i wyjaśnienie dotyczące CodePen: https://codepen.io/johanmouchet/pen/PKNxKQ

Johan M.
źródło
1

Jeśli cieszysz się, że nie obsługujesz IE ani Pre-Chromium Edge (co może być w porządku, jeśli używasz tego do stopniowego ulepszania), możesz użyć :placeholder-showntak, jak powiedział Berend. Zwróć uwagę, że w przypadku Chrome i Safari faktycznie potrzebujesz niepustego symbolu zastępczego, aby to działało, chociaż spacja działa.

*,
 ::after,
 ::before {
  box-sizing: border-box;
}

label.floating-label {
  display: block;
  position: relative;
  height: 2.2em;
  margin-bottom: 1em;
}

label.floating-label input {
  font-size: 1em;
  height: 2.2em;
  padding-top: 0.7em;
  line-height: 1.5;
  color: #495057;
  background-color: #fff;
  background-clip: padding-box;
  border: 1px solid #ced4da;
  border-radius: 0.25rem;
  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

label.floating-label input:focus {
  color: #495057;
  background-color: #fff;
  border-color: #80bdff;
  outline: 0;
  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}

label.floating-label input+span {
  position: absolute;
  top: 0em;
  left: 0;
  display: block;
  width: 100%;
  font-size: 0.66em;
  line-height: 1.5;
  color: #495057;
  border: 1px solid transparent;
  border-radius: 0.25rem;
  transition: font-size 0.1s ease-in-out, top 0.1s ease-in-out;
}

label.floating-label input:placeholder-shown {
  padding-top: 0;
  font-size: 1em;
}

label.floating-label input:placeholder-shown+span {
  top: 0.3em;
  font-size: 1em;
}
<fieldset>
  <legend>
    Floating labels example (no-JS)
  </legend>
  <label class="floating-label">
    <input type="text" placeholder=" ">
    <span>Username</span>
  </label>
  <label class="floating-label">
    <input type="Password" placeholder=" ">
    <span>Password</span>
  </label>
</fieldset>
<p>
  Inspired by Bootstrap's <a href="https://getbootstrap.com/docs/4.0/examples/floating-labels/">floating labels</a>.
</p>

Sora2455
źródło
1

Udało mi się dodać nazwę klasy do danych wejściowych, a następnie zastosować do tego reguły CSS:

<input type="text" name="product" class="product" />

<style>
input[value=""].product {
    display: none;
}
</style>
DeFeNdog
źródło
0

Dziwią mnie odpowiedzi, które mają jasny atrybut, aby uzyskać puste pola wejściowe, spójrz na ten kod

/*empty input*/
input:empty{
    border-color: red;
}
/*input with value*/
input:not(:empty){
    border-color: black;
}

AKTUALIZACJA

input, select, textarea {
    border-color: @green;
    &:empty {
        border-color: @red;
    }
}

Więcej za świetny wygląd podczas walidacji

 input, select, textarea {
    &[aria-invalid="true"] {
        border-color: amber !important;
    }

    &[aria-invalid="false"], &.valid {
        border-color: green !important;
    }
}
Nasser Hadjloo
źródło
7
:emptydotyczy tylko elementów, które nie mają dzieci. Wejścia nie mogą w ogóle mieć węzłów podrzędnych, więc dane wejściowe będą zawsze oznaczone czerwoną ramką. Zobacz także ten komentarz
Zhegan,
2
@NasserHadjloo czy to przetestowałeś? Zmiana valuenie zmienia liczby węzłów podrzędnych.
jcuenod
@jcuenod co rozumiesz przez liczbę węzłów podrzędnych? Nie rozumiem
Nasser Hadjloo
W strukturach XML węzły są zagnieżdżone (tj <parent><child></child></parent>.). Po prostu trzeba <input></input>i jak piszesz to, co się zmienia nie jest <value>wewnątrz węzła <input>ale wartość atrybutu :<input value='stuff you type'></input>
jcuenod
2
Ale to nie jest to, co stara się osiągnąć PO.
jcuenod
0

Zdaję sobie sprawę, że to bardzo stary wątek, ale od tamtego czasu sytuacja nieco się zmieniła i pomogło mi to znaleźć właściwą kombinację rzeczy, których potrzebowałem, aby naprawić mój problem. Więc pomyślałem, że podzielę się tym, co zrobiłem.

Problem polegał na tym, że potrzebowałem tego samego CSS zastosowanego do opcjonalnego wejścia, jeśli był wypełniony, tak jak w przypadku wypełnionego wymagania. CSS wykorzystywał klasę psuedo: valid, która zastosowała CSS na opcjonalnym wejściu również wtedy, gdy nie był wypełniony.

Tak to naprawiłem;

HTML

<input type="text" required="required">
<input type="text" placeholder="">

CSS

input:required:valid {
    ....
}
input:optional::not(:placeholder-shown){
    ....
}
Jessica
źródło