HTML + CSS ile Mükemmel Bir İçindekiler Tablosu PlatoBlockchain Veri Zekası. Dikey Arama. Ai.

HTML + CSS ile Mükemmel Bir İçindekiler

Bu yılın başlarında, adında bir e-kitap yayınladım. JavaScript Sözlerini Anlamak (indirmek için ücretsiz). Bunu basılı bir kitaba dönüştürmek gibi bir niyetim olmamasına rağmen, yeterince insan bir basılı sürüm hakkında bilgi almak için bana ulaştı ve ben de bunu kendim yayınlamaya karar verdim. HTML ve CSS kullanarak kolay bir alıştırma olacağını düşündüm. bir PDF oluşturun ve ardından yazıcıya gönderin. Basılı bir kitabın önemli bir bölümüne bir cevabım olmadığının farkında değildim: içindekiler tablosu.

İçindekiler tablosunun yapısı

Özünde, içindekiler tablosu oldukça basittir. Her satır, bir kitabın veya web sayfasının bir bölümünü temsil eder ve bu içeriği nerede bulabileceğinizi gösterir. Tipik olarak, çizgiler üç bölümden oluşur:

  1. Bölüm veya bölümün başlığı
  2. Başlığı görsel olarak sayfa numarasına bağlayan liderler (yani noktalar, çizgiler veya çizgiler)
  3. sayfa numarası

Microsoft Word veya Google Docs gibi kelime işlem araçlarının içinde bir içindekiler tablosu oluşturmak kolaydır, ancak içeriğim Markdown'da olduğu ve ardından HTML'ye dönüştürüldüğü için bu benim için iyi bir seçenek değildi. Baskıya uygun bir biçimde içindekiler tablosunu oluşturmak için HTML ile çalışacak otomatik bir şey istedim. Ayrıca, belgede gezinmek için web sayfalarında ve PDF'lerde kullanılabilmesi için her satırın bir bağlantı olmasını istedim. Ayrıca başlık ve sayfa numarası arasında nokta liderleri istedim.

Ve böylece araştırmaya başladım.

HTML ve CSS ile bir içindekiler tablosu oluşturma konusunda iki mükemmel blog yazısına rastladım. İlki "HTML'nizden İçindekiler Tablosu Oluşturun" Julie Blanc'ın fotoğrafı. Julie'de çalıştı PagedJS, web tarayıcılarında belgeleri yazdırmak üzere uygun şekilde biçimlendiren eksik sayfalı ortam özellikleri için bir çoklu dolgu. Julie'nin örneğiyle başladım ama benim için pek işe yaramadığını gördüm. Sonra Christoph Grabo's'u buldum. “CSS ile duyarlı TOC lider hatları” hizalamayı kolaylaştırmak için (Julie'nin kayan nokta tabanlı yaklaşımının aksine) CSS Izgarası kullanma kavramını tanıtan post. Yine de, yaklaşımı benim amaçlarım için pek doğru değildi.

Bu iki gönderiyi okuduktan sonra, kendi başıma başlamak için yerleşim konularını yeterince iyi anladığımı hissettim. Her iki blog gönderisinden de parçalar kullandım, ayrıca yaklaşıma bazı yeni HTML ve CSS konseptleri ekleyerek memnun olduğum bir sonuç elde ettim.

Doğru işaretlemeyi seçme

Bir içindekiler tablosu için doğru işaretlemeye karar verirken, öncelikle doğru anlambilim hakkında düşündüm. Temel olarak, bir içindekiler tablosu, neredeyse bir anahtar/değer çifti gibi, bir sayfa numarasına bağlanan bir başlık (bölüm veya alt bölüm) ile ilgilidir. Bu beni iki seçeneğe götürdü:

  • Bir seçenek bir tablo kullanmaktır (<table>) başlık için bir sütun ve sayfa için bir sütun içerir.
  • Sonra sık sık kullanılmayan ve unutulan tanım listesi var (<dl>) öğesi. Aynı zamanda bir anahtar/değer haritası görevi görür. Böylece, bir kez daha, başlık ve sayfa numarası arasındaki ilişki açık olacaktır.

Bunlardan herhangi biri, gerçekten yalnızca tek düzeyli içindekiler için, yani yalnızca bölüm adlarına sahip bir içindekiler tablosuna sahip olmak istediğimde işe yaradıklarını anlayana kadar iyi seçenekler gibi görünüyordu. Yine de içindekiler bölümünde alt bölümleri göstermek isteseydim, iyi bir seçeneğim yoktu. Tablo öğeleri hiyerarşik veriler için harika değilve tanım listeleri teknik olarak iç içe yerleştirilebilirken, anlambilim doğru görünmüyordu. Bu yüzden çizim tahtasına geri döndüm.

Julie'nin yaklaşımından yola çıkarak bir liste kullanmaya karar verdim; ancak, sıralı bir liste seçtim (<ol>) sırasız bir liste yerine (<ul>). Bu durumda sıralı bir listenin daha uygun olduğunu düşünüyorum. İçindekiler, içerikte göründükleri sıraya göre bölümlerin ve alt başlıkların bir listesini temsil eder. Sıra önemlidir ve işaretlemede kaybolmamalıdır.

Ne yazık ki, sıralı bir liste kullanmak, başlık ve sayfa numarası arasındaki anlamsal ilişkiyi kaybetmek anlamına geliyor, bu yüzden bir sonraki adım, bu ilişkiyi her liste öğesi içinde yeniden kurmaktı. Bunu çözmenin en kolay yolu, sayfa numarasının önüne "sayfa" kelimesini eklemektir. Bu şekilde, sayının metne göre ilişkisi, başka bir görsel ayrım olmaksızın bile açıktır.

İşaretlememin temelini oluşturan basit bir HTML iskeleti:

<ol class="toc-list"> <li> <a href="#link_to_heading"> <span class="title">Chapter or subsection title</span> <span class="page">Page 1</span> </a> <ol> <!-- subsection items --> </ol> </li>
</ol>

İçindekiler tablosuna stiller uygulama

Kullanmayı planladığım işaretlemeyi oluşturduktan sonraki adım bazı stilleri uygulamaktı.

İlk önce, otomatik olarak oluşturulan sayıları kaldırdım. İsterseniz otomatik olarak oluşturulmuş sayıları kendi projenizde tutmayı seçebilirsiniz, ancak kitapların bölümler listesinde numaralandırılmamış önsöz ve son kelimelere sahip olması yaygındır, bu da otomatik olarak oluşturulmuş sayıları yanlış yapar.

Amacım için, bölüm numaralarını manuel olarak doldurur, sonra düzeni, üst düzey listenin herhangi bir dolgusu olmayacak şekilde (böylece onu paragraflarla hizalayarak) ve gömülü her liste iki boşlukla girintili olacak şekilde ayarlardım. bir kullanmayı seçtim 2ch dolgu değeri çünkü hangi yazı tipini kullanacağımdan hala tam olarak emin değildim. bu ch uzunluk birimi, dolgunun tutarsız görünmesine neden olabilecek mutlak bir piksel boyutu yerine, hangi yazı tipi kullanılırsa kullanılsın, bir karakterin genişliğine göre olmasını sağlar.

İşte bitirdiğim CSS:

.toc-list, .toc-list ol { list-style-type: none;
} .toc-list { padding: 0;
} .toc-list ol { padding-inline-start: 2ch;
}

Sara Soueidan bana WebKit tarayıcılarının aşağıdaki durumlarda liste anlambilimini kaldırdığına dikkat çekti. list-style-type is none, bu yüzden eklemem gerekiyordu role="list" korumak için HTML'ye:

<ol class="toc-list" role="list"> <li> <a href="#link_to_heading"> <span class="title">Chapter or subsection title</span> <span class="page">Page 1</span> </a> <ol role="list"> <!-- subsection items --> </ol> </li>
</ol>
CodePen Göm Geri Dönüşü

Başlığın ve sayfa numarasının şekillendirilmesi

Liste benim beğenime göre şekillendirildiğinde, bireysel bir liste öğesinin stiline geçmenin zamanı gelmişti. İçindekiler tablosundaki her bir öğe için, başlık ve sayfa numarası, başlık sola ve sayfa numarası sağa hizalı olacak şekilde aynı satırda olmalıdır.

“Sorun değil, flexbox bunun için var!” diye düşünüyor olabilirsiniz. Yanlış değilsin! Flexbox gerçekten de doğru başlık sayfası hizalamasını sağlayabilir. Ancak liderler eklendiğinde bazı zorlu hizalama sorunları var, bu yüzden Christoph'un bir ızgara kullanarak yaklaşımını tercih ettim, bu da bonus olarak çok satırlı başlıklarda da yardımcı oluyor. Tek bir öğe için CSS:

.toc-list li > a { text-decoration: none; display: grid; grid-template-columns: auto max-content; align-items: end;
} .toc-list li > a > .page { text-align: right;
}

Izgara iki sütuna sahiptir, bunlardan ilki auto- konteynerin tüm genişliğini dolduracak şekilde boyutlandırılmış, eksi ikinci sütunu dolduracak şekilde boyutlandırılmıştır. max-content. İçindekiler tablosunda geleneksel olduğu gibi sayfa numarası sağa hizalanır.

Bu noktada yaptığım diğer tek değişiklik “Sayfa” metnini gizlemekti. Bu, ekran okuyucular için yararlıdır ancak görsel olarak gereksizdir, bu yüzden bir geleneksel visually-hidden sınıf görünümden gizlemek için:

.visually-hidden { clip: rect(0 0 0 0); clip-path: inset(100%); height: 1px; overflow: hidden; position: absolute; width: 1px; white-space: nowrap;
}

Ve elbette, HTML'nin bu sınıfı kullanmak için güncellenmesi gerekiyor:

<ol class="toc-list" role="list"> <li> <a href="#link_to_heading"> <span class="title">Chapter or subsection title</span> <span class="page"><span class="visually-hidden">Page</span> 1</span> </a> <ol role="list"> <!-- subsection items --> </ol> </li>
</ol>

Bu temel hazır olduğunda, başlık ve sayfa arasındaki liderlere hitap etmeye devam ettim.

CodePen Göm Geri Dönüşü

Nokta liderleri oluşturma

Liderler basılı medyada o kadar yaygındır ki merak ediyor olabilirsiniz, CSS bunu neden zaten desteklemiyor? Cevap: öyle. Şey, bir çeşit.

Aslında bir leader() içinde tanımlanan işlev Sayfalı Medya için CSS Tarafından Oluşturulan İçerik belirtimi. Ancak, disk belleğine alınmış medya özelliklerinin çoğunda olduğu gibi, bu işlev hiçbir tarayıcıda uygulanmaz, bu nedenle bir seçenek olarak hariç tutulur (en azından bunu yazdığım sırada). Listede bile yok caniuse.com, muhtemelen hiç kimse bunu uygulamadığı ve yapacaklarına dair hiçbir plan veya sinyal olmadığı için.

Neyse ki, hem Julie hem de Christoph bu sorunu ilgili gönderilerinde zaten ele aldılar. Nokta liderlerini eklemek için ikisi de bir ::after sözde eleman onunla content özellik, bunun gibi çok uzun bir nokta dizisine ayarlandı:

.toc-list li > a > .title { position: relative; overflow: hidden;
} .toc-list li > a .title::after { position: absolute; padding-left: .25ch; content: " . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . . . . "; text-align: right;
}

The ::after sözde öğe, onu sayfanın akışından çıkarmak ve diğer satırlara kaydırmaktan kaçınmak için mutlak bir konuma ayarlanır. Her satırın son noktalarının satırın sonundaki sayıyla aynı hizada olmasını istediğimiz için metin sağa hizalanır. (Bunun karmaşıklığı hakkında daha sonra.) .title eleman göreli bir konuma sahip olacak şekilde ayarlanmıştır, böylece ::after sözde eleman kutusundan çıkmaz. Bu arada, overflow gizlenir, böylece tüm bu ekstra noktalar görünmez. Sonuç, nokta liderleriyle güzel bir içindekiler tablosu.

Ancak, dikkate alınması gereken başka bir şey var.

Sara ayrıca tüm bu noktaların ekran okuyucular için metin olarak sayıldığını da belirtti. Peki ne duyuyorsun? "Giriş nokta nokta nokta..." tüm noktalar ilan edilene kadar. Bu, ekran okuyucu kullanıcıları için korkunç bir deneyim.

Çözüm, ek bir eleman eklemektir. aria-hidden ayarlandığında true ve ardından noktaları eklemek için bu öğeyi kullanın. Böylece HTML şöyle olur:

<ol class="toc-list" role="list"> <li> <a href="#link_to_heading"> <span class="title">Chapter or subsection title<span class="leaders" aria-hidden="true"></span></span> <span class="page"><span class="visually-hidden">Page</span> 1</span> </a> <ol role="list"> <!-- subsection items --> </ol> </li>
</ol>

Ve CSS olur:

.toc-list li > a > .title { position: relative; overflow: hidden;
} .toc-list li > a .leaders::after { position: absolute; padding-left: .25ch; content: " . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . . . . " ". . . . . . . . . . . . . . . . . . . . . . . "; text-align: right;
}

Artık ekran okuyucular noktaları görmezden gelecek ve kullanıcıları birden çok noktanın duyurulmasını dinleme hayal kırıklığından kurtaracak.

CodePen Göm Geri Dönüşü

Son rötuşlar

Bu noktada, içindekiler bileşeni oldukça iyi görünüyor, ancak bazı küçük detay çalışmaları gerektirebilir. Başlangıç ​​olarak, çoğu kitap bölüm başlıklarını alt bölüm başlıklarından görsel olarak dengeledi, bu yüzden üst düzey öğeleri kalın yaptım ve alt bölümleri izleyen bölümlerden ayırmak için bir kenar boşluğu ekledim:

.toc-list > li > a { font-weight: bold; margin-block-start: 1em;
}

Ardından, sayfa numaralarının hizalamasını temizlemek istedim. Sabit genişlikli bir yazı tipi kullandığımda her şey yolunda görünüyordu, ancak değişken genişlikli yazı tiplerinde, lider noktalar bir sayfa numarasının genişliğine göre ayarlandıkça bir zikzak deseni oluşturabilirdi. Örneğin, 1'li herhangi bir sayfa numarası diğerlerinden daha dar olur ve bu, önceki veya sonraki satırlardaki noktalarla yanlış hizalanmış lider noktalara neden olur.

İçindekiler tablosundaki yanlış hizalanmış sayılar ve noktalar.
HTML + CSS ile Mükemmel Bir İçindekiler

Bu sorunu çözmek için ayarladım font-variant-numeric için tabular-nums bu nedenle tüm sayılar aynı genişlikte ele alınır. Minimum genişliği de ayarlayarak 2ch, bir veya iki basamaklı tüm sayıların mükemmel şekilde hizalanmasını sağladım. (Bunu şu şekilde ayarlamak isteyebilirsiniz: 3ch projenizin 100'den fazla sayfası varsa.) Sayfa numarası için son CSS:

.toc-list li > a > .page { min-width: 2ch; font-variant-numeric: tabular-nums; text-align: right;
}
İçindekiler tablosunda hizalanmış lider noktalar.
HTML + CSS ile Mükemmel Bir İçindekiler

Ve bununla, içindekiler tablosu tamamlandı!

CodePen Göm Geri Dönüşü

Sonuç

HTML ve CSS'den başka bir şey içermeyen bir içindekiler tablosu oluşturmak beklediğimden daha zordu ama sonuçtan çok memnunum. Bu yaklaşım sadece bölümleri ve alt bölümleri barındıracak kadar esnek olmakla kalmaz, aynı zamanda alt alt bölümleri CSS'yi güncellemeden güzel bir şekilde yönetir. Genel yaklaşım, içeriğin çeşitli konumlarına bağlantı vermek istediğiniz web sayfalarının yanı sıra, içindekiler tablosunun farklı sayfalara bağlantı vermesini istediğiniz PDF'lerde çalışır. Ve elbette, bir broşürde veya kitapta kullanmaya meyilliyseniz, basılı olarak da harika görünüyor.

Julie Blanc ve Christoph Grabo'ya, bir içindekiler tablosu oluşturma konusundaki mükemmel blog yazıları için teşekkür etmek istiyorum, çünkü ikisi de başladığımda çok değerliydi. Bu projede çalışırken erişilebilirlik geri bildirimi için Sara Soueidan'a da teşekkür etmek istiyorum.


HTML + CSS ile Mükemmel Bir İçindekiler aslen yayınlandı CSS Hileleri. Malısın bülteni al.

Zaman Damgası:

Den fazla CSS Püf Noktaları