若要讓段落文字環繞延伸超出卡片邊緣的圖片,請將圖片設為浮動,並使用負的外邊距。加入 shape-outside 可建立曲線輪廓。本教學會建立一個完整的本機範例,供你在 Mac 上用 Safari 開啟。

文字為何能環繞重疊的圖片?

圖片必須參與段落的浮動排版。CSS float 會將元素放在容器的一側,並讓相鄰文字沿著它排列。這個範例將圖片靠右浮動,讓文字在圖片左側流動,接著排到圖片下方。MDN:float。

三個設定會決定結果:浮動會產生環繞效果,負的右邊距會讓圖片延伸到容器之外,而 shape-outside 則定義鄰近文字會沿著排列的輪廓。一般浮動元素會產生矩形環繞;使用形狀則能讓每一行文字沿著圓形排列。MDN:shape-outside。

只在視覺上移動圖片並不足夠。絕對定位的圖片不會占用一般文件流中的空間,因此周圍元素會像圖片不存在一樣排列。位移會改變圖片的呈現位置,卻不會重新安排一般文件流。這些行為說明了為什麼使用 position: absolute 或 transform: translateX(...) 定位時,重疊的圖片可能會蓋住文字。MDN:position、MDN:使用 CSS transforms。

這裡的目標很明確:一張圓形圖片跨出一張文字卡片的右邊緣,而卡片中的段落沿著圓形的左側輪廓排列。圖片與段落必須位於同一個環繞區域。

在 Mac 上建立完整範例

使用純文字程式碼編輯器,建立名為 overlap-wrap.html 的檔案。貼上以下完整文件、儲存,然後用 Safari 開啟。範例內含以資料 URL 嵌入的抽象 SVG 圖片,因此不需要安裝圖片檔、套件或建置工具。

浮動圖片會放在它要影響的段落之前。這個位置很重要,因為浮動元素的位置會受文件中較早出現的內容限制。將標題放在浮動元素之前,也能讓標題使用卡片的完整文字寬度。W3C:視覺格式化模型。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Overlapping image and paragraph wrapping</title>
  <style>
    * { box-sizing: border-box; }
    body {
      margin: 0;
      padding: 32px 96px 32px 32px;
      background: #eef1f5;
      color: #243247;
      font: 18px/1.65 system-ui, sans-serif;
    }
    .card {
      display: flow-root;
      width: 100%;
      max-width: 640px;
      margin: 0 auto;
      padding: 24px;
      background: white;
      box-shadow: 0 0 0 1px #cbd3df;
      overflow: visible;
    }
    .card h2 {
      margin: 0 0 16px;
      font-size: 26px;
      line-height: 1.25;
    }
    .card p { margin: 0 0 16px; }
    .card p:last-child { margin-bottom: 0; }
    .art {
      display: block;
      float: right;
      width: 240px;
      height: 240px;
      margin: 0 -88px 16px 16px;
      border-radius: 50%;
      shape-outside: circle(50%) border-box;
      shape-margin: 16px;
    }
    @media (max-width: 760px) {
      body { padding: 16px; }
      .art {
        float: none;
        width: min(240px, 100%);
        height: auto;
        margin: 0 auto 24px;
        shape-outside: none;
      }
    }
  </style>
</head>
<body>
  <article class="card">
    <h2>Study A: circles and spacing</h2>
    <img class="art" width="240" height="240" alt=""
      src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240' viewBox='0 0 240 240'%3E%3Crect width='240' height='240' fill='%233a628b'/%3E%3Ccircle cx='90' cy='85' r='60' fill='%23b9d8eb'/%3E%3Ccircle cx='165' cy='170' r='45' fill='%238db5cc'/%3E%3C/svg%3E">
    <p>Panel A pairs a circular graphic with a continuous passage of
      sample text. Follow the right edge of this paragraph as each
      line approaches the curved outline. Near the widest part of
      the circle, the available space becomes narrower.</p>
    <p>Panel B continues the same passage with a second paragraph.
      The graphic extends into the outer gutter while the words
      remain inside the white card. As the contour curves inward,
      later lines can use more of the available width.</p>
    <p>Panel C provides enough additional text to show the transition
      below the graphic. Once the passage continues beyond the
      wrapping region, its lines return to the full content width.
      Resize the window to compare the desktop arrangement with
      the stacked layout used in a narrower window.</p>
  </article>
</body>
</html>

在寬度大於 760px 的視窗中,預期結果是圓形圖案延伸至右側間隔區,段落文字則沿著圖案左側排列。在 760px 或更窄的視窗中,圖片會成為置中的區塊,顯示在段落上方。這個斷點只是示範用的設計選擇;當 @media 的查詢條件符合時,瀏覽器便會套用其中的宣告。MDN:@media。

範例圖案僅供裝飾,因此圖片元素使用 alt=""。如果你換成傳達資訊的圖案,請提供適當的文字替代內容。WHATWG 區分了裝飾圖片,以及需要以文字提供等效資訊的圖片。WHATWG:提供文字作為圖片替代內容的要求。

如何選擇重疊量與文字間距?

先調整圖片的位置,再調整輪廓。右浮動元素會依據其外邊距盒定位。在這個範例中,負的右邊距會讓圖片右緣超出卡片內容邊緣 88px。卡片的右內距為 24px,因此圖片超出白色背景 64px。這些是依照本範例推算的尺寸,以 CSS 像素為單位。W3C:浮動元素的定位。

數值 範例值 計算方式或用途
圖片寬度 240px 顯示圓形的直徑
從內容邊緣向外延伸的距離 88px 負的右邊距的絕對值
卡片內距 24px 內容邊緣與背景邊緣之間的空間
超出背景的可見部分 64px 88 − 24
留在內容區域內的圖片寬度 152px 240 − 88
矩形環繞的預留寬度 168px 240 − 88 + 16,包含左邊距

在你自己的版面中,負邊距的絕對值應等於預期的外伸距離加上容器的右內距。例如,若要在 24px 內距下外伸 40px,右邊距應設為 -64px。每當放大圖片或縮小容器寬度時,都要重新檢查剩餘文字寬度。

圓形版本使用 shape-outside: circle(50%) border-box,讓幾何形狀符合正方形圖片方框。此處明確指定 border-box 很有用,因為不對稱的邊距會改變外邊距盒。若未明確指定參照方框,基本形狀預設會使用 margin-box。MDN:搭配 shape-outside 使用基本形狀。

shape-margin: 16px 會在環繞輪廓周圍增加空間。正的左邊距會在面向文字的一側留出這段間距。形狀及其形狀邊距都會裁切在浮動元素的外邊距盒內;單獨增加 shape-margin 無法無限延伸環繞區域。負的右邊距也會裁切朝外的一側;在這個範例中,該側沒有段落文字。W3C:CSS Shapes Module Level 1。

若要使用矩形圖片,請將 border-radius 改為 0,將 shape-outside 改為 none,並將 shape-margin 改為 0。保留浮動與邊距。這樣會以相同的向外位置產生直邊環繞。若只移除形狀而保留圓形裁切,圖片仍會是圓形,但文字會留出矩形空間。

哪些容器邊界會影響環繞?

卡片使用 display: flow-root 建立區塊格式化上下文,讓卡片能在垂直方向上容納浮動元素。即使文字很短,卡片高度也會將圖片計入其中。這也能讓這個環繞區域獨立於外部浮動元素。MDN:區塊格式化上下文。

請讓段落留在該區域的一般區塊流中。如果圖片是 flex 或 grid 的直接子項目,它的浮動就無法形成這種段落環繞配置。同樣地,若為獨立的段落包裝元素建立區塊格式化上下文,該包裝元素的內容就不會受到外部浮動元素影響。外層 grid 可以負責定位整張卡片;卡片內部仍可使用流式排版。MDN:區塊格式化上下文。

請另外檢查裁切情況。範例讓 overflow 保持可見,以便呈現外伸部分。使用 overflow 來容納浮動元素可能會導致裁切或捲軸;flow-root 則能在不採用這種設定的情況下容納浮動元素。如果圖片恰好在某個祖先元素的邊緣消失,也要檢查外層元件。MDN:容納內部浮動元素。

CSS Shapes 也有方向限制:右浮動元素允許文字在其左側環繞,左浮動元素則允許文字在其右側環繞。單一浮動元素無法在置中圖片兩側各自建立文字通道。對這個需求而言,支援的配置是將圖片浮動在邊緣。W3C:CSS Shapes 與浮動行為。

可以在 Tailwind CSS 中使用這個方法嗎?

可以。在現有的 Tailwind 專案中,float-right 會產生 float: right,而 float-none 則會移除浮動。這些工具類別由 Tailwind 提供;文字排版仍由瀏覽器處理。Tailwind CSS:float。

對於輪廓宣告,可以用 Tailwind 的任意屬性語法表達 [shape-outside:circle(50%)_border-box] 和 [shape-margin:16px]。底線代表 border-box 前方的空格。這些是供已完成設定的 Tailwind 專案使用的類別名稱片段,不能取代上方的完整文件。轉換時請保留相同的尺寸、邊距、容器版面,以及窄視窗下的重設設定。Tailwind CSS:新增自訂樣式。

如何找出環繞效果異常的原因?

以本機範例為基準,接著一次加入一項現有樣式。以下步驟會檢查決定版面配置的條件:

  1. 先確認矩形環繞。 暫時將 shape-outside: none 設為樣式。如果文字仍延伸到圖片下方,請檢查圖片是否設為浮動、絕對定位,或是 flex/grid 的直接子項目。
  2. 檢查文件順序。 將浮動元素放在應環繞它的段落之前。
  3. 檢查環繞區域。 讓浮動元素與段落內容位於同一個區塊格式化上下文中;移除段落包裝元素不必要的獨立上下文。
  4. 檢查輪廓。 恢復圓形及其明確指定的 border-box 參照。套用圓形裁切前,請確認顯示的圖片是正方形。
  5. 檢查側邊間隔。 放大視窗,查看卡片或其祖先元素是否裁切了圖片。確認頁面留有足夠的外部空間來容納外伸部分。
  6. 檢查窄版配置。 將視窗大小調整到範例的斷點附近,確認浮動與負邊距都已重設。

這些檢查依循了關於浮動元素定位、格式化上下文以及形狀參照方框的文件說明。請勿加入手動換行來修補個別行,否則內容就會受限於特定視窗尺寸。

MDN 指出 shape-outside 已廣泛可用,同時也提醒部分語法的支援情況可能不同。這個範例使用文件記載的 circle() 形式。請在預計支援的 Mac 瀏覽器中比較頁面,並評估間距與可讀性,不必要求每一行都在相同位置結束。如果瀏覽器不支援形狀宣告,浮動元素仍會以矩形方式環繞。MDN:shape-outside。

完成版面時,請一併選擇圖片尺寸與外伸距離,保留足夠寬度供文字排列,並維持窄版堆疊配置。這些尺寸調整妥當後,再使用輪廓微調圖片周圍的間距。這樣文字就能隨著內容或可用寬度變化重新排列。

來源