Agar baris baru sumber tunggal dibaca sebagai spasi sementara baris kosong memulai paragraf, buat struktur paragraf sebelum menerapkan pembungkus teks normal. Di Mac, Anda dapat mengujinya di halaman browser lokal; CSS saja tidak membuat pembedaan itu.

Panduan ini untuk orang yang menyiapkan prosa bahasa Inggris untuk halaman web sederhana atau pratinjau Markdown. Tugannya adalah mempertahankan baris sumber yang mudah dibaca sambil menghasilkan paragraf yang mengalir dan terbungkus ulang saat lebar jendela browser berubah.

Mengapa pengaturan whitespace CSS tidak memenuhi kedua persyaratan

Perhatikan teks sumber sintetis ini. Setiap paragraf menempati dua baris sumber, dan baris kosong memisahkan paragraf:

Panel A memperkenalkan tata letak
dan mendeskripsikan bagian pertama.

Panel B memperkenalkan bagian lain
dan mendeskripsikan ruang yang tersisa.

Hasil yang diinginkan adalah dua paragraf. Di dalam setiap paragraf, baris baru sumber menjadi spasi. Browser kemudian memilih pemutusan baris terlihat sesuai lebar yang tersedia.

Dengan white-space: normal, baris baru sumber runtuh bersama whitespace lain yang dapat diruntuhkan. Termasuk baris baru beruntun: baris sumber kosong tidak membuat paragraf. Dengan white-space: pre-line, karakter baris baru tetap sebagai pemutus baris, termasuk baris baru tunggal yang Anda inginkan untuk digabungkan. MDN mendokumentasikan perilaku ini di referensi properti white-space.

Pengaturan yang diterapkan pada satu blok teks Baris baru sumber tunggal Baris sumber kosong Cocok untuk tugas ini?
white-space: normal Runtuh dengan whitespace Juga runtuh Hanya setelah paragraf dibuat
white-space: pre-line Menjaga pemutusan baris Menjaga pemutusan Tidak
white-space: pre-wrap Menjaga pemutusan baris Menjaga pemutusan Tidak
Elemen paragraf terpisah dengan white-space: normal Mengalir di dalam setiap paragraf Diwakili oleh batas paragraf Ya

W3C mendeskripsikan pemrosesan whitespace sebagai operasi rendering yang meninggalkan data dokumen yang mendasarinya tidak berubah. Aturan pemutus segmen-nya juga bergantung pada teks sekitar; menggantikan baris baru dengan spasi sesuai untuk prosa bahasa Inggris yang digunakan di sini, bukan transformasi universal untuk semua teks. Lihat CSS Text Module Level 3.

Solusi praktis oleh karena itu memiliki dua tahap: mengenali paragraf di sumber, lalu biarkan browser menata teks mereka. Standar HTML WHATWG mendefinisikan elemen p sebagai mewakili paragraf. Pemisahan terlihatnya dapat dikendalikan independen melalui styling. Lihat elemen p.

Pilih jalur yang cocok dengan sumber Anda

Gunakan bantuan keputusan berikut sebelum mengubah apa pun. Ia memisahkan interpretasi sumber dari tampilan, yang membantu menghindari memperbaiki lapisan yang salah.

Apa yang Anda miliki Apa yang harus dilakukan
Teks biasa yang hanya berisi prosa Pecah pada baris kosong, gabungkan baris baru tunggal di dalam setiap paragraf, dan buat elemen paragraf
Markdown dengan heading, daftar, atau blok kode Gunakan parser Markdown dan periksa perilaku soft-break-nya
HTML yang sudah ada dengan elemen paragraf terpisah Periksa whitespace dan gaya spasi paragraf tersebut
Halaman yang berisi elemen pemutus baris eksplisit Koreksi sumber atau konfigurasi rendering jika pemutusan itu tidak disengaja
Halaman yang hanya bisa dilihat Gunakan alur kerja sumber atau ekspor yang tersedia; contoh di sini memerlukan kontrol dokumen

Jangan mengganti setiap baris baru dengan spasi sebelum mengidentifikasi paragraf: itu menghapus pemisah yang dibedakan untuk membedakan mereka. Demikian pula, jangan menggantikan elemen br berulang untuk struktur paragraf. WHATWG mendefinisikan br sebagai pemutus baris dan mengatakan ia tidak boleh digunakan untuk memisahkan kelompok tematik di dalam paragraf. Lihat elemen br.

Buat contoh lokal yang berfungsi dengan TextEdit

Halaman lengkap berikut memerlukan TextEdit dan browser dengan JavaScript diaktifkan. Ia berisi kolom sumber yang dapat diedit dan pratinjau terpisah. Ia tidak menggunakan pustaka eksternal.

  1. Buka TextEdit dan pilih File > Baru, lalu Format > Buat Teks Biasa.
  2. Tempelkan contoh lengkap di bawah.
  3. Pilih File > Simpan dan beri nama file paragraph-demo.html.
  4. Jika diminta tentang ekstensi, pilih Gunakan .html.
  5. Buka file yang disimpan di Safari atau browser desktop lain.

Apple mendokumentasikan langkah pembuatan teks biasa dan ekstensi di Bekerja dengan dokumen HTML di TextEdit di Mac. Saat membuka kembali file untuk diedit, gunakan pengaturan TextEdit Tampilkan file HTML sebagai kode HTML bukan teks terformat di bawah TextEdit > Pengaturan > Buka dan Simpan.

<!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>

Konverter pertama menormalkan akhir baris carriage-return dan CRLF ke LF. Kemudian ia memecah teks di mana saja baris kosong atau hanya berisi spasi dan tab biasa. Di dalam setiap blok yang dihasilkan, ia menggantikan baris baru yang tersisa, ditambah spasi atau tab berdekatan, dengan satu spasi biasa.

Ini adalah aturan eksplisit untuk contoh ini, bukan parser dokumen umum. Beberapa baris kosong menghasilkan satu batas paragraf. Whitespace biasa di awal dan akhir dihapus. Input kosong tidak menghasilkan paragraf. Sumber asli tetap terlihat di kolom input, sehingga transformasi dapat dibandingkan dengannya.

Setiap paragraf output menerima teksnya melalui textContent. MDN mendokumentasikan bahwa menetapkan properti ini menggantikan anak-anak node dengan node teks. Di sini ia hanya ditetapkan ke paragraf yang baru dibuat, kosong. Lihat Properti textContent Node.

Fungsi konversi lolos enam pemeriksaan deterministik di Node.js: input paragraf biasa, input CRLF, input carriage-return, input hanya-kosong, baris kosong berulang, dan pelestarian spasi tidak-pemutus. Rendering browser tidak dieksekusi selama persiapan; gunakan pemeriksaan visual di bawah untuk memverifikasinya di Mac Anda.

Periksa batas paragraf dan pembungkusan secara terpisah

Mulai dengan contoh yang disediakan. Pratinjau harus berisi Panel A memperkenalkan tata letak dan mendeskripsikan bagian pertama. sebagai satu paragraf, diikuti paragraf Panel B yang sesuai. Pada lebar jendela sempit, salah satu paragraf mungkin menempati beberapa baris terlihat.

Sekarang buat pengeditan terkontrol ini:

  1. Ganti baris baru tunggal setelah layout dengan spasi. Struktur paragraf pratinjau harus tetap sama.
  2. Kembalikan baris baru itu dan hapus baris kosong antara dua blok. Pratinjau harus menjadi satu paragraf.
  3. Tambahkan baris kosong yang hanya berisi spasi atau tab di antara blok. Pratinjau harus kembali menjadi dua paragraf.
  4. Tambahkan beberapa baris kosong di sana. Jaraknya harus tetap satu celah paragraf.
  5. Ubah ukuran jendela browser. Batas paragraf harus tetap tetap sementara baris di dalam setiap paragraf terbungkus ulang.

Urutan ini membedakan batas sumber dari pembungkusan browser. Dalam contoh, spasi paragraf berasal dari aturan margin paragraf berdekatan. Mengubah margin itu mengubah celah terlihat tanpa mengubah cara sumber diurai.

Jika Anda menggunakan white-space: normal tanpa konverter ini, gabungan visual tidak berarti baris baru sumber dihapus. MDN menjelaskan bahwa whitespace konten-teks biasa tetap ada di DOM bahkan ketika CSS meruntuhkannya selama rendering. Lihat Menangani whitespace.

Gunakan parsing Markdown untuk dokumen Markdown

Markdown sudah menyediakan konvensi paragraf yang diperlukan di sini. CommonMark mendefinisikan paragraf sebagai baris non-kosong berurutan yang bukan tipe blok lain; baris kosong memisahkan paragraf. Baris baru biasa di dalam paragraf adalah soft break, yang renderer mungkin keluarkan sebagai baris baru atau spasi. Lihat paragraf CommonMark dan soft line breaks.

Tempelkan contoh sintetis ke tampilan sumber editor Markdown Anda dan periksa pratinjaunya. Jika setiap baris baru tunggal menghasilkan pemutusan terlihat, periksa opsi rendering yang terdokumentasi editor. Jangan asumsikan setiap aplikasi Markdown mengekspos pengaturan yang sama.

Untuk proyek yang menggunakan pustaka bernama markdown-it, opsi breaks yang terdokumentasinya default ke false. Mengatur ke true mengubah baris baru paragraf menjadi elemen br. Menjaga false mendukung hasil paragraf yang mengalir, asalkan CSS output juga meruntuhkan whitespace. Lihat MarkdownItOptions.

Hard break Markdown eksplisit tetap memerlukan perhatian. Di bawah CommonMark, dua atau lebih spasi di akhir atau backslash di akhir dapat membuat hard line break. Hapus penanda itu hanya di tempat mereka tidak disengaja. Aturannya terdokumentasi di bawah hard line breaks.

Jangan jalankan konverter teks biasa ke seluruh dokumen Markdown. Ia tidak mengenali heading, daftar, kode berpagar, atau aturan indentasi. Biarkan parser Markdown mempertahankan struktur itu; terapkan styling whitespace ke paragraf prosa yang dihasilkan.

Pertahankan batas browser dan pembentukan teks

Jaga setiap paragraf prosa sebagai teks berkelanjutan di mana praktis. Contoh membuat satu node teks per paragraf dan menyerahkan pembungkusan baris dan tata letak glyph ke browser. Ia tidak mengukur kata atau menyisipkan elemen terpisah di sekitar setiap karakter.

Batas itu penting untuk tipografi. W3C menentukan keadaan di mana pembentukan harus berlanjut melewati batas elemen-inline dan keadaan di mana harus terputus, termasuk perubahan spasi dan perataan tertentu. Hindari menambahkan kotak-inline tidak perlu hanya untuk mengontrol posisi baris. Lihat Pembentukan Melewati Batas Elemen.

Gunakan konverter hanya ketika setiap baris baru sumber terisolasi adalah pembungkus editorial. Jika baris baru sengaja membagi label, atau berada di dalam kata, menggabungkannya dengan spasi mengubah konten. Contoh ini juga memperlakukan baris yang berisi spasi tidak-pemutus sebagai konten, bukan pemisah kosong; MDN membedakan spasi tidak-pemutus dari whitespace dokumen biasa yang dapat diruntuhkan di Menangani whitespace.

Untuk prosa bahasa Inggris, tetapkan batas paragraf terlebih dahulu dan izinkan pembungkusan browser normal di dalamnya. Contoh lokal membuat aturan itu dapat diperiksa: sumber mempertahankan baris yang dapat diedit, pratinjau berisi paragraf nyata, dan mengubah ukuran hanya mengubah pembungkusan baris terlihat.

Sumber