捨棄 create-react-app 之餘還架了個 astro blog 昭告天下:樣式管理與文章 toc

已知 astro 提供兩種設定樣式的方式:

  1. 以較傳統的方式將樣式收納在 .css 檔案中,每個 .astro 元件再根據需求各自引用
  2. 將樣式直接寫在每個 .astro 元件的 <style></style> 標籤中

今天會以排版元件 SinglePostLayout 為例,來說明兩種樣式的使用方式。也會順便介紹如何取得一篇文章的目錄(toc / table of contents)資訊。

本文

透過 .css 檔案管理樣式

沒有什麼特別,就是透過選取器(css selector)搭配樣式內容來進行排版。而需要該包樣式設定的 astro 檔案,則在 Component Script 區塊將該份樣式 import 進來即可。比如:

---
// Component Script
import '@Styles/global.css';
---

<!-- Component Template -->

即代表此元件引用了位於 ./src/styles/global.css 這份樣式設定,完整的樣式內容可在這裡看到。

(路徑寫為 @Styles 是因為已經設定好 alias path,不清楚這部分設定的讀者可以參考第 18 天的內容)

透過 .astro 中的 style 標籤管理樣式

有時樣式可能只會被套用到單一 astro 元件上,此時就可選擇將這類「範圍限定」的樣式收納到每一個 astro 元件中的 <style></style> 標籤裡。

比較需要注意的是 SinglePostLayout 元件中的 <slot/> 欄位。透過 astro 處理後的 markdown 內容不會帶上 class。比如文章段落全部都會被包進 <p></p> 標籤裡,而這些標籤的 class 欄位不會有額外內容。因此,在設定 <slot/> 樣式時,多半需要搭配親元件的 class 來處理。

比如個人已經在 global.css 中設定好 h1 的樣式為 margin: 16px 0; color: #4c5958;,在 SinglePostLayout 中就會透過以下方式來微調「每一篇文章中的 h1 樣式」:

<style>
  .post-container h1 {
    margin: 0;
    margin-bottom: 16px;
  }
</style>

番外:關於 toc

可以直接透過 Astro.props.headings 來取得每一篇 markdown 文章的 toc 資訊,資料結構如下:

Astro.props = {
  headings: [
    {
      depth: 2,
      text: '本文',
      slug: '本文',
    },
    {
      depth: 3,
      text: '透過 .css 檔案管理樣式',
      slug: '透過-css-檔案管理樣式',
    },
    {
      depth: 3,
      text: '透過 .astro 中的 style 標籤管理樣式',
      slug: '透過-astro-中的-style-標籤管理樣式',
    },
    /* ... */
  ],
};

slug 加上 # 即可作為 url anchor 使用,比如:

<ul class="toc-container">
  {
    headings.map((head) => (
      <li class={`toc-${head.depth}`}>
        <a href={`#${head.slug}`}>{head.text}</a>
      </li>
    ))
  }
</ul>

即是將一篇文章的 toc 渲染出來,並搭配 # 產生該段落的直連網址。

總結

現在我們搞定「整個部落格的基礎樣式設定」以及「單一篇文章的排版」了,明天會來聊聊門面樣式的處理細節。

感謝你今天的閱讀 (。•ㅅ•。)

參考