Als enkele regeleinden in de bron als spaties moeten worden weergegeven en lege regels nieuwe alinea’s moeten beginnen, maak je eerst de alineastructuur aan en pas je daarna de normale tekstterugloop toe. Op een Mac kun je dit testen op een lokale webpagina; met alleen CSS kun je dat onderscheid niet maken.

Deze handleiding is bedoeld voor iemand die Engelse proza voorbereidt voor een eenvoudige webpagina of Markdown-voorbeeld. Het doel is de leesbare regels in de bron te behouden en tegelijk doorlopende alinea’s te maken die opnieuw worden afgebroken wanneer de breedte van het browservenster verandert.

Waarom een CSS-instelling voor witruimte niet aan beide vereisten voldoet

Bekijk deze synthetische brontekst. Elke alinea beslaat twee bronregels en de alinea’s worden gescheiden door een lege regel:

Panel A introduces the layout
and describes the first section.

Panel B introduces another section
and describes the remaining space.

Het gewenste resultaat bestaat uit twee alinea’s. Binnen elke alinea wordt het regeleinde in de bron een spatie. De browser bepaalt vervolgens waar zichtbare regeleinden komen, afhankelijk van de beschikbare breedte.

Met white-space: normal worden regeleinden in de bron samengevoegd, net als andere witruimtetekens die kunnen worden samengevoegd. Dat geldt ook voor opeenvolgende regeleinden: een lege bronregel maakt geen alinea. Met white-space: pre-line blijven newline-tekens regeleinden, ook de enkele regeleinden die je juist wilde samenvoegen. MDN beschrijft dit gedrag in de referentie voor de eigenschap white-space.

Instelling toegepast op één tekstblok Eén regeleinde in de bron Lege bronregel Geschikt voor deze taak?
white-space: normal Wordt samengevoegd met witruimte Wordt ook samengevoegd Pas nadat alinea’s zijn aangemaakt
white-space: pre-line Behoudt een regeleinde Behoudt regeleinden Nee
white-space: pre-wrap Behoudt een regeleinde Behoudt regeleinden Nee
Afzonderlijke alineaelementen met white-space: normal Loopt door binnen elke alinea Weergegeven als een alineagrens Ja

W3C beschrijft witruimteverwerking als een weergavebewerking die de onderliggende documentgegevens ongewijzigd laat. De regels voor segmentafbrekingen hangen ook af van de omliggende tekst; voor het Engelse proza dat hier wordt gebruikt, is een regeleinde vervangen door een spatie geschikt, maar dit is geen universele transformatie voor alle tekst. Zie CSS Text Module Level 3.

De praktische oplossing bestaat daarom uit twee stappen: herken de alinea’s in de bron en laat de browser vervolgens de tekst opmaken. De WHATWG HTML Standard definieert het element p als een alinea. De zichtbare afstand ervan kan afzonderlijk met stijlen worden geregeld. Zie het p-element.

Kies de aanpak die bij je bron past

Gebruik deze besliswijzer voordat je iets verandert. Zo houd je de interpretatie van de bron gescheiden van de vormgeving en voorkom je dat je de verkeerde laag aanpast.

Wat je hebt Wat je doet
Platte tekst met alleen proza Splits bij lege regels, voeg enkele regeleinden binnen elke alinea samen en maak alineaelementen aan
Markdown met koppen, lijsten of codeblokken Gebruik een Markdown-parser en controleer hoe zachte regeleinden worden verwerkt
Bestaande HTML met afzonderlijke alineaelementen Controleer de instellingen voor witruimte en afstand van de alinea’s
Een pagina met expliciete regeleindeelementen Corrigeer de bron of de weergaveconfiguratie als die regeleinden onbedoeld zijn
Een pagina die je alleen kunt bekijken Gebruik een beschikbare bron- of exportworkflow; voor de voorbeelden hier moet je het document kunnen aanpassen

Vervang niet elk regeleinde door een spatie voordat je de alinea’s hebt herkend: dan verwijder je de scheidingstekens waarmee je ze kunt onderscheiden. Vervang de alineastructuur evenmin door herhaalde elementen br. Volgens WHATWG is br een regeleinde en mag het niet worden gebruikt om thematische groepen binnen een alinea te scheiden. Zie het br-element.

Maak een lokaal werkend voorbeeld met TextEdit

Voor de volgende volledige webpagina heb je TextEdit en een browser met ingeschakelde JavaScript nodig. De pagina bevat een bewerkbaar bronveld en een afzonderlijk voorbeeld. Er zijn geen externe bibliotheken nodig.

  1. Open TextEdit en kies File > New en daarna Format > Make Plain Text.
  2. Plak het volledige voorbeeld hieronder.
  3. Kies File > Save en geef het bestand de naam paragraph-demo.html.
  4. Kies Use .html als je wordt gevraagd wat je met de extensie wilt doen.
  5. Open het opgeslagen bestand in Safari of een andere desktopbrowser.

Apple beschrijft de stappen voor het maken van platte tekst en het instellen van de extensie in Werken met HTML-documenten in TextEdit op de Mac. Gebruik bij het opnieuw openen van het bestand om het te bewerken de instelling Display HTML files as HTML code instead of formatted text onder TextEdit > Settings > Open and Save.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Paragraph flow demo</title>
  <style>
    body {
      max-width: 46rem;
      margin: 2rem auto;
      padding: 0 1rem;
      font: 1rem/1.6 system-ui, sans-serif;
    }
    label { display: block; }
    textarea {
      box-sizing: border-box;
      width: 100%;
      min-height: 12rem;
      font: 1rem/1.5 monospace;
    }
    #preview p {
      white-space: normal;
      margin: 0;
    }
    #preview p + p { margin-top: 1em; }
  </style>
</head>
<body>
  <h1>Paragraph flow demo</h1>
  <label for="source">Source text</label>
  <textarea id="source">Panel A introduces the layout
and describes the first section.

Panel B introduces another section
and describes the remaining space.</textarea>
  <h2>Preview</h2>
  <div id="preview"></div>
  <script>
    function toParagraphs(source) {
      return source.replace(/\r\n?/g, '\n')
        .split(/\n[ \t]*\n(?:[ \t]*\n)*/)
        .map(block => block
          .replace(/^[ \t\n]+|[ \t\n]+$/g, '')
          .replace(/[ \t]*\n[ \t]*/g, ' '))
        .filter(text => text.length > 0);
    }

    const source = document.getElementById('source');
    const preview = document.getElementById('preview');

    function render() {
      const paragraphs = toParagraphs(source.value).map(text => {
        const paragraph = document.createElement('p');
        paragraph.textContent = text;
        return paragraph;
      });
      preview.replaceChildren(...paragraphs);
    }

    source.addEventListener('input', render);
    render();
  </script>
</body>
</html>

De omzetter normaliseert eerst regeleinden met carriage return en CRLF naar LF. Vervolgens splitst hij de tekst bij regels die leeg zijn of alleen gewone spaties en tabs bevatten. Binnen elk resulterend blok vervangt hij een overgebleven regeleinde, plus eventuele aangrenzende spaties of tabs, door één gewone spatie.

Dit zijn expliciete regels voor dit voorbeeld, geen algemene documentparser. Meerdere lege regels leveren één alineagrens op. Gewone witruimte aan het begin en einde wordt verwijderd. Lege invoer levert geen alinea’s op. De oorspronkelijke bron blijft zichtbaar in het invoerveld, zodat je de transformatie ermee kunt vergelijken.

Elke uitvoeralinea krijgt tekst via textContent. MDN beschrijft dat toewijzing aan deze eigenschap de onderliggende knooppunten van een element vervangt door een tekstknooppunt. Hier wordt de eigenschap alleen toegewezen aan nieuw aangemaakte, lege alinea’s. Zie Node: de eigenschap textContent.

De conversiefunctie doorstond in Node.js zes deterministische controles: gewone alinea-invoer, CRLF-invoer, invoer met carriage returns, invoer die alleen uit lege regels bestaat, herhaalde lege regels en behoud van een vaste spatie. De browserweergave is tijdens de voorbereiding niet uitgevoerd; gebruik de visuele controles hieronder om deze op je Mac te verifiëren.

Controleer alineagrenzen en tekstterugloop afzonderlijk

Begin met het meegeleverde voorbeeld. De voorbeeldweergave moet Panel A introduces the layout and describes the first section. als één alinea tonen, gevolgd door de bijbehorende alinea voor Panel B. Bij een smal browservenster kan elke alinea over meerdere zichtbare regels lopen.

Voer nu de volgende gecontroleerde aanpassingen uit:

  1. Vervang het enkele regeleinde na layout door een spatie. De alineastructuur in de voorbeeldweergave moet hetzelfde blijven.
  2. Herstel dat regeleinde en verwijder de lege regel tussen de twee blokken. De voorbeeldweergave moet nu één alinea tonen.
  3. Voeg tussen de blokken een lege regel toe die alleen spaties of tabs bevat. De voorbeeldweergave moet weer twee alinea’s tonen.
  4. Voeg daar meerdere lege regels toe. De afstand moet gelijk blijven aan één alinearuimte.
  5. Pas de breedte van het browservenster aan. De alineagrens moet op zijn plaats blijven, terwijl de regels binnen elke alinea opnieuw worden afgebroken.

Deze reeks maakt het verschil duidelijk tussen bronbegrenzingen en tekstterugloop in de browser. In het voorbeeld komt de afstand tussen alinea’s van de marge-instelling voor aangrenzende alinea’s. Als je die marge aanpast, verandert de zichtbare afstand zonder dat de bron anders wordt verwerkt.

Als je white-space: normal zonder deze omzetter gebruikt, betekent het visueel samenvloeien niet dat het regeleinde uit de bron is verwijderd. MDN legt uit dat witruimtetekens in gewone tekstinhoud in de DOM blijven staan, ook als CSS ze tijdens de weergave samenvoegt. Zie Witruimte verwerken.

Gebruik een Markdown-parser voor Markdown-documenten

Markdown biedt zelf al de benodigde alineaconventie. CommonMark definieert een alinea als opeenvolgende niet-lege regels die niet tot een ander bloktype behoren; lege regels scheiden alinea’s. Een normaal regeleinde binnen een alinea is een zachte afbreking, die een renderer kan weergeven als een regeleinde of als een spatie. Zie CommonMark-alinea’s en zachte regeleinden.

Plak het synthetische voorbeeld in de bronweergave van je Markdown-editor en bekijk het voorbeeld. Als elk afzonderlijk regeleinde als zichtbare afbreking wordt weergegeven, controleer dan de gedocumenteerde weergaveopties van de editor. Ga er niet van uit dat elke Markdown-toepassing dezelfde instelling heeft.

Als een project de genoemde bibliotheek markdown-it gebruikt, is de gedocumenteerde optie breaks standaard ingesteld op false. Als je deze instelt op true, worden regeleinden in alinea’s omgezet in elementen br. Als je de optie op false laat staan, ondersteunt dat het resultaat met doorlopende alinea’s, mits de uitvoer-CSS witruimte ook samenvoegt. Zie MarkdownItOptions.

Expliciete harde regeleinden in Markdown verdienen nog steeds aandacht. Volgens CommonMark kunnen twee of meer spaties aan het einde of een afsluitende backslash een hard regeleinde maken. Verwijder deze markeringen alleen als ze onbedoeld zijn. De regels staan beschreven onder harde regeleinden.

Voer de omzetter voor platte tekst niet uit op een volledig Markdown-document. De omzetter herkent geen koppen, lijsten, afgebakende codeblokken of inspringregels. Laat een Markdown-parser die structuren behouden en pas witruimtestijlen toe op de resulterende proza-alinea’s.

Behoud de grenzen van de browser en tekstvormgeving

Houd elke proza-alinea waar dat praktisch is als doorlopende tekst. Het voorbeeld maakt één tekstknooppunt per alinea aan en laat de browser de regels afbreken en de tekens vormgeven. Het meet geen woorden en plaatst geen afzonderlijk element rond elk teken.

Die grens is belangrijk voor typografie. W3C specificeert omstandigheden waarin de tekstvormgeving over grenzen tussen inline-elementen heen moet doorlopen en omstandigheden waarin die moet worden onderbroken, waaronder bepaalde wijzigingen in afstand en uitlijning. Voeg geen onnodige inline-vakken toe alleen om de regelposities te bepalen. Zie Vormgeving over elementgrenzen heen.

Gebruik de omzetter alleen als elk afzonderlijk regeleinde in de bron een redactioneel regeleinde is. Als een regeleinde bewust labels scheidt of midden in een woord staat, verandert het samenvoegen ervan met een spatie de inhoud. Het voorbeeld behandelt een regel met een vaste spatie ook als inhoud en niet als lege scheiding; MDN maakt in Witruimte verwerken onderscheid tussen vaste spaties en gewone samenvoegbare witruimte in documenten.

Maak voor Engelse proza eerst de alineagrenzen aan en laat de browser de tekst daarbinnen normaal afbreken. Het lokale voorbeeld maakt die regel controleerbaar: de bron behoudt de bewerkbare regels, de voorbeeldweergave bevat echte alinea’s en het aanpassen van de venstergrootte verandert alleen de zichtbare regelafbreking.

Bronnen