Aby nadać wcięcie wiszące zawijanym wpisom rozdzielonym znacznikami <br>, zastosuj do ich kontenera blokowego text-indent: 2em hanging each-line. Sprawdź obsługę obu słów kluczowych; jeśli musisz uwzględnić starsze przeglądarki, umieść każdy wpis w osobnym bloku i użyj dopełnienia oraz ujemnego wcięcia.

Ten przewodnik jest przeznaczony dla osoby edytującej niewielką stronę HTML na Macu, która chce, aby każdy wpis zaczynał się równo z lewą krawędzią, a jego kolejne wiersze były bardziej wcięte. Przykłady używają tekstu przykładowego i wymagają jedynie edytora zwykłego tekstu lub kodu oraz przeglądarki.

Dlaczego zwykłe wcięcie wiszące nie działa po znaczniku podziału wiersza

Trzeba uwzględnić dwa różne zakończenia wiersza. Znacznik <br> tworzy jawny podział wiersza. Miękkie zawijanie następuje, gdy przeglądarka dopasowuje tekst do dostępnej szerokości. W zamierzonym układzie pierwszy przypadek oznacza początek kolejnego wpisu, a drugi — kontynuację. WHATWG definiuje <br> jako podział wiersza; nie tworzy on nowego akapitu ani kontenera wpisu. Standard HTML: element br.

Zwykłe ujemne text-indent wpływa na pierwszy sformatowany wiersz bloku. Dodanie dopełnienia może więc utworzyć wcięcie wiszące w tym bloku, ale nie przywraca wysunięcia po każdym <br>. Kolejne wpisy nadal należą do tego samego bloku. MDN: text-indent.

Specyfikacja CSS definiuje potrzebne tu połączenie: each-line obejmuje pierwszy wiersz oraz wiersze bezpośrednio po wymuszonych podziałach; hanging odwraca ten wybór. Razem wcinają zawijane miękko kolejne wiersze, pozostawiając każdy jawnie rozpoczęty wiersz przy lewej krawędzi. W3C: wcięcie pierwszego wiersza.

Docelowy układ wygląda tak. Poniższe zakończenia wierszy są poglądowe; przeglądarka wybierze rzeczywiste miejsca zawijania na podstawie dostępnej szerokości i parametrów fontu.

Wpis A zaczyna się przy zewnętrznej krawędzi i jest kontynuowany
    od wewnątrz, gdy zabraknie dostępnej szerokości.
Wpis B również zaczyna się przy zewnętrznej krawędzi, a jego
    kontynuacja jest wcięta niezależnie.
Wpis C jest krótki.

Wybierz metodę przed zmianą strony

Wybierz podejście na podstawie istniejącego znacznika i wymagań dotyczących przeglądarek. Ta tabela decyzyjna wynika z udokumentowanego działania wcięć i danych o obsłudze przez przeglądarki; pomaga we wdrożeniu, a nie opisuje osobnej funkcji przeglądarki.

Twoja sytuacja Zalecane podejście
Jawne podziały wiersza są częścią jednego fragmentu tekstu, a obsługiwane przeglądarki są wystarczające Zachowaj podziały i użyj hanging each-line
Wpisy są osobnymi akapitami lub elementami listy Nadaj każdemu wpisowi odpowiednią strukturę w znacznikach
Wcięcie wiszące musi być widoczne w starszych przeglądarkach Użyj osobnego bloku dla każdego wpisu, z dopełnieniem i ujemnym wcięciem
Możesz edytować tylko CSS, a starszej przeglądarce brakuje słów kluczowych Zachowaj czytelny układ bez wcięcia lub poproś o zmianę znaczników

Nie zakładaj obsługi słów kluczowych na podstawie obsługi podstawowego text-indent. Aktualne dane zgodności MDN wskazują obsługę zarówno hanging, jak i each-line od Safari 15, Firefox 121 i Chrome 146. Starsze wersje mogą obsługiwać zwykłe wcięcia, a jednocześnie odrzucać tę kombinację. Dane zgodności przeglądarek MDN: text-indent.

Sprawdź też, czy podziały odpowiadają właściwej strukturze. WHATWG zastrzega <br> do podziałów wynikających z treści i wskazuje, że nie wolno używać go do oddzielania grup tematycznych w akapicie. Osobne akapity powinny być zapisane jako elementy akapitu; zbiór elementów listy powinien używać znaczników listy. Standard HTML: element br, Standard HTML: grupowanie treści.

Zachowaj znaczniki podziału przy natywnym rozwiązaniu CSS

Poniższy kompletny dokument HTML pokazuje metodę zachowującą podziały. Na Macu wklej go do edytora zwykłego tekstu lub kodu, zapisz jako hanging-indent.html i otwórz plik w przeglądarce. Użyj pliku HTML, a nie dokumentu z formatowaniem tekstu.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Break-separated hanging indent</title>
  <style>
    body {
      margin: 2rem;
      font-family: system-ui, sans-serif;
      line-height: 1.6;
    }

    .entries {
      max-inline-size: 30rem;
      margin: 0;
      white-space: normal;
      text-align: start;
      text-indent: 0;
    }

    @supports (text-indent: 2em hanging each-line) {
      .entries {
        text-indent: 2em hanging each-line;
      }
    }
  </style>
</head>
<body>
  <h1>Sample entries</h1>
  <p class="entries">Entry A: A long sample line describing a pale rectangular panel, a narrow heading area, and a small square beside the heading.<br>
Entry B: Another long sample line describing a circular tile, an open space beneath it, and a row of neutral labels.<br>
Entry C: A short sample line.</p>
</body>
</html>

Warunek @supports sprawdza całą deklarację przed jej zastosowaniem. Przeglądarki, które nie obsługują tej kombinacji, zachowują jawnie określony układ bez wcięcia. Zapytania o funkcje warunkowo stosują CSS w zależności od obsługi przez przeglądarkę. MDN: @supports.

Zastosuj wcięcie do .entries, bloku zawierającego tekst. Ta właściwość dotyczy kontenerów blokowych; umieszczenie deklaracji na <br> nie zapewnia kontenera dla kolejnego wpisu. MDN: text-indent.

Wartość 2em jest regulowanym wyborem projektowym. Po sprawdzeniu układu w wąskiej kolumnie wypróbuj mniejszą lub większą wartość. Zapewnia stałe przesunięcie kontynuacji; nie mierzy szerokości Entry A: ani nie wyrównuje automatycznie tekstu pod pierwszym słowem etykiety o zmiennej długości.

Użyj osobnych bloków, jeśli wcięcie ma działać w każdej przeglądarce

Jeśli każdy wpis jest niezależnym akapitem, zmień znaczniki tak, aby każdy wpis miał własny pierwszy wiersz. Poniższa kompletna alternatywa usuwa oddzielające wpisy podziały i osobno stosuje tradycyjne obliczenie wcięcia wiszącego do każdego akapitu.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Paragraph hanging indents</title>
  <style>
    body {
      margin: 2rem;
      font-family: system-ui, sans-serif;
      line-height: 1.6;
    }

    .entries {
      max-inline-size: 30rem;
      text-indent: 0;
    }

    .entry {
      margin: 0;
      padding-inline-start: 2em;
      text-indent: -2em;
      white-space: normal;
      text-align: start;
    }
  </style>
</head>
<body>
  <h1>Sample entries</h1>
  <div class="entries">
    <p class="entry">Entry A: A long sample paragraph describing a pale rectangular panel, a narrow heading area, and a small square beside the heading.</p>
    <p class="entry">Entry B: Another long sample paragraph describing a circular tile, an open space beneath it, and a row of neutral labels.</p>
    <p class="entry">Entry C: A short sample paragraph.</p>
  </div>
</body>
</html>

Dopełnienie przesuwa początek treści akapitu do wewnątrz o 2em. Ujemne wcięcie cofa tylko jego pierwszy wiersz o tę samą wartość. Zawijane wiersze zachowują pozycję wyznaczoną przez dopełnienie. Równe wartości są niezbędne: zmiana tylko jednej z nich przesuwa początek pierwszego wiersza. Ujemne wcięcie opisuje MDN, a padding-inline-start dodaje dopełnienie przy logicznej krawędzi początkowej. MDN: text-indent, MDN: padding-inline-start.

Dla poglądowego rozmiaru fontu wynoszącego 16 pikseli przesunięcie 2em odpowiada 32 pikselom: kontynuacja zaczyna się 32 piksele dalej do wewnątrz, a korekta pierwszego wiersza wynosi −32 piksele. To obliczenie na potrzeby przykładu, a nie zmierzony wynik renderowania.

Usuń stare separatory, gdy przyjmujesz tę strukturę. Umieść każdy kompletny wpis i jego dotychczasowe formatowanie śródtekstowe w nowym akapicie. Jeśli treść jest listą, użyj zamiast tego elementów listy; przykład z akapitami jest odpowiedni konkretnie dla niezależnych akapitów. Standard HTML: grupowanie treści.

Przed zakończeniem sprawdź zawijanie i przepływ tekstu

Przetestuj stronę przy szerokości, przy której oba długie wpisy się zawijają. Następnie poszerz okno, aż zmieszczą się w pojedynczych wierszach. Skorzystaj z poniższych wskazówek, aby odróżnić problem z wcięciem od problemu z zawijaniem lub strukturą.

  1. Sprawdź początek każdego wpisu. W przykładzie zachowującym podziały tekst po każdym <br> powinien wracać do zewnętrznej krawędzi. Jeśli tak się nie dzieje, sprawdź obsługę całej kombinacji słów kluczowych.
  2. Sprawdź każdą kontynuację. Długie wpisy powinny zawijać się z wcięciem. Krótkie powinny pozostawać przy krawędzi, bez dodatkowych spacji na początku.
  3. Sprawdź najwęższą używaną kolumnę. Zmniejsz wcięcie, jeśli zajmuje zbyt dużo dostępnej szerokości wiersza.
  4. Sprawdź właściwą treść. Przenosząc wpis do osobnego bloku, zachowaj jego słowa, formatowanie śródtekstowe i zamierzone jawne podziały.

Jeśli nic się nie zawija, sprawdź white-space. W przykładzie użyto normal, które zwija białe znaki w kodzie źródłowym i umożliwia zawijanie. pre zachowuje białe znaki, ale blokuje zwykłe miękkie zawijanie; pre-wrap zachowuje białe znaki i pozwala na zawijanie. Wcięcie nie będzie widoczne na kolejnym wierszu, który w ogóle nie powstaje. MDN: white-space.

Unikaj dodawania spacji w celu imitowania wcięcia. Przy white-space: normal ciągi spacji są zwijane. Unikaj też wstawiania dodatkowych znaczników podziału w miejscach, w których tekst zawija się w bieżącej szerokości okna: zamieniłyby kontynuacje wybrane przez przeglądarkę w jawne początki, zmieniając sposób ich traktowania przez each-line. MDN: white-space, W3C: wcięcie pierwszego wiersza.

Pozwól przeglądarce odpowiadać za podziały wierszy i kształtowanie glifów. Nie dziel wpisu na opakowania znaków, aby obliczać jego widoczne wiersze. W3C opisuje sytuacje, w których granice elementów śródtekstowych przerywają kształtowanie tekstu, między innymi niezerowe dopełnienie, obramowanie lub margines między znakami. Na potrzeby tego zadania zawijanie całych wpisów w ich zamierzonych granicach pozwala uniknąć wprowadzania dodatkowych granic wewnątrz słów. W3C: kształtowanie tekstu na granicach elementów.

Na koniec wybierz strukturę odpowiadającą treści: zachowaj znaczące jawne podziały i użyj hanging each-line albo umieść niezależne wpisy we własnych blokach. Sprawdź, czy każdy wpis zaczyna się przy krawędzi i czy tylko jego naturalnie zawinięte kontynuacje przesuwają się do wewnątrz przy szerokościach, z których zamierzasz korzystać.

Źródła