Stylování placeholderu pomocí CSS

Atribut placeholder napovídá, co se od vstupního pole čeká, dokud je prázdné. Kdysi jeho stylování vyžadovalo čtyři vendor prefixy, dnes stačí jediný selektor ::placeholder. Podíváme se, jak nápovědu upravit správně, který trik s ní udělá formulář pohodlnějším a proč jí nelze nahradit popisek pole.

To hlavní: placeholder není popisek

Nápověda zmizí při prvním zadaném znaku. Člověk vyrušený uprostřed formuláře už nezjistí, co vyplňuje; čtečka obrazovky ji v části prohlížečů vůbec nepřečte; automatické vyplňování funguje hůř. Proto musí mít pole skutečný popisek <label>, zatímco placeholder nese jen formát nebo příklad.

TAKTO NE: POPISEK ŽIJE JEN V PLACEHOLDERUTelefon ve formátu +380…pole prázdné — nápověda je vidět+380 67 502 45 84začalo se psát — nápověda zmizelaa co to bylo za pole, už nezjistíteTAKTO ANO: POPISEK ZVLÁŠŤ, PLACEHOLDER UKAZUJE FORMÁTTelefon+380 __ ___ __ __popisek zůstává vždyTelefon+380 67 502 45 84přečte ji člověk i čtečka obrazovky
Popisek jen v placeholderu a správná varianta s label
<!-- takto ne -->
<input type="tel" name="phone" placeholder="Telefon ve formátu +380…">

<!-- takto ano -->
<label for="phone">Telefon</label>
<input type="tel" id="phone" name="phone"
       placeholder="+380 __ ___ __ __" autocomplete="tel">

Jak změnit barvu a písmo nápovědy

Dnes stačí jediné pravidlo — ::placeholder podporují všechny aktuální prohlížeče:

input::placeholder,
textarea::placeholder {
    color: #8A8A8A;
    font-style: italic;
    opacity: 1; /* Firefox nápovědu ve výchozím stavu ztlumí */
}

Řádek s opacity není navíc: Firefox odjakživa vykresluje placeholder poloprůhledně a bez něj vyjde zvolená barva bledší, než bylo v plánu.

Sada vlastností, které se na nápovědu skutečně použijí, je malá: barva, pozadí, celá rodina font-*, prokládání písmen a slov, text-decoration, text-transform, line-height, opacity a text-overflow. Odsazení, rámečky a pozicování neplatí — to patří samotnému poli.

Staré prefixy a proč je znát

Články staré pět let psaly tentýž efekt takto:

::-webkit-input-placeholder { color: #8A8A8A; }
::-moz-placeholder          { color: #8A8A8A; }
:-moz-placeholder           { color: #8A8A8A; }
:-ms-input-placeholder      { color: #8A8A8A; }

Důvodem bylo, že standard neexistoval a každé jádro si stylování vyřešilo po svém: v IE a ve Firefoxu do verze 19 byl placeholder pseudotřídou, ve WebKitu a Blinku pseudoelementem. Dnes tyto řádky potřebují jen projekty s podporou velmi starých prohlížečů. Důležitý detail: tyto selektory nelze spojit čárkou — prohlížeč, který jeden z nich nezná, zahodí celé pravidlo.

Dlouhá nápověda v úzkém poli

Na telefonu se pole zužují a dlouhý text se ořízne uprostřed slova. Tři tečky vypadají úhledněji:

input::placeholder {
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
}

Trik funguje, ale léčí následek. Pokud se nápověda nevejde, je příliš dlouhá: vzor „+380 __ ___ __ __“ se čte lépe než věta přes celou šířku.

Skrýt nápovědu při fokusu

Prohlížeče se chovají různě: jedny placeholder odstraní, jakmile kurzor dosedne, jiné ho drží do prvního znaku. Sjednotí to jediný řádek:

input:focus::placeholder,
textarea:focus::placeholder {
    color: transparent;
}

Hezčí je plynulé odsunutí:

input::placeholder {
    opacity: 1;
    transition: opacity .2s ease, transform .2s ease;
}

input:focus::placeholder {
    opacity: 0;
    transform: translateX(6px);
}

Stavy pole a :placeholder-shown

Samostatná pseudotřída :placeholder-shown platí, dokud je pole prázdné a nápověda vidět. Stojí na ní triky, které se dřív dělaly skriptem.

TŘI STAVY POLE A JEJICH SELEKTORYVaše jménoprázdné, nápověda vidět::placeholder:placeholder-shownVaše jménokurzor v poli:focus::placeholdertady se nápověda obvykle skryjeMaximje zadaná hodnota:not(:placeholder-shown)popisek se zvedne nahoruSelektor :placeholder-shown platí, dokud je pole prázdné — na něm stojí plovoucí popiseki zvýraznění nevyplněných polí, bez jediného řádku JavaScriptu.
Tři stavy pole a selektory, které jim odpovídají

Plovoucí popisek leží přes prázdné pole a zvedne se, jakmile se objeví text. Celý efekt v CSS:

<div class="field">
  <input type="text" id="name" placeholder=" ">
  <label for="name">Vaše jméno</label>
</div>
.field { position: relative; }

.field label {
    position: absolute;
    left: 12px;
    top: 12px;
    color: #8A8A8A;
    pointer-events: none;
    transition: transform .15s ease, font-size .15s ease;
}

/* pole vyplněné nebo ve fokusu — popisek jede nahoru */
.field input:not(:placeholder-shown) + label,
.field input:focus + label {
    transform: translateY(-22px);
    font-size: 12px;
}

Mezera v placeholder=" " je povinná: bez atributu pseudotřída :placeholder-shown nezabere vůbec.

Tentýž selektor zvýrazní nevyplněná povinná pole, a to až poté, co se jich návštěvník dotkl:

input:required:not(:placeholder-shown):invalid {
    border-color: #C0392B;
}

Přístupnost a tmavý režim

  • Kontrast. Světle šedá nápověda na bílém pozadí je klasická chyba. WCAG žádá alespoň 4,5:1 u běžného textu; nápověda smí být tlumená, ale čitelná.
  • Nerušte popisek kvůli čistému vzhledu. Pokud design žádá pole bez viditelného popisku, musí popisek přesto být v kódu — alespoň jako aria-label.
  • Tmavý režim. Barvu nápovědy nastavte tokenem a přepište ji v media query:
input::placeholder { color: #8A8A8A; }

@media (prefers-color-scheme: dark) {
    input::placeholder { color: #9B9B9B; }
}
  • Nic důležitého do placeholderu. Požadavky na heslo, formát data, povinnost pole — to je text vedle pole, ne mizející nápověda.

Stručně to hlavní

Ke stylování nápovědy dnes stačí ::placeholder a vendor prefixy potřebuje jen ten, kdo podporuje velmi staré prohlížeče. Pro stavy pole je tu :placeholder-shown: drží na něm plovoucí popisek i zvýraznění prázdných polí — bez JavaScriptu. Hlavní pravidlo zůstává: placeholder ukazuje formát, popisek říká, o jaké pole jde, a jedno druhé nenahradí.

Pokud formulář na vašem webu funguje, ale návštěvníci ho opouštějí v půli, napište nám — najdeme, kde se poptávky ztrácejí.