又出 bug 了 ?Safari 下文字和省略號重疊問題

XboxYan發表於2023-03-13

Safari不愧是新時代的 IE,各種 bug 層出不窮。比如有這樣一個多行省略打點的佈局

div{
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}

這樣在文字超過三行的時候就會出現省略號

image.png

沒啥問題,和正常瀏覽器一樣。但是這樣有個問題,每行文字右端空隙太大,不美觀,如下

image.png

下面加上文字兩端對齊

div{
    /* */
    text-align: justify;
}

啪!bug 就出現了

image.png

當然,如果設計不介意的話,不使用文字兩端對齊也能簡單規避這個問題。

那有沒有什麼辦法可以解決這個問題呢?

一、為啥會有這個問題

出現這個 bug 的原因在於,這個省略號是自動生成的,在Safari沒有受到文字兩端對齊的作用,所以導致和文字發生了重疊, 貌似是忘記了對這個省略號進行對齊處理。

因此,如果這個省略號是自己定義的,本來就在頁面中,當然就不會有這個問題了。

要實現超過指定行數出現省略號有幾個實現點:

  1. 超過指定行數截斷文字
  2. 右下角環繞的省略號
  3. 在字數較少時自動隱藏省略號

之前在這兩篇文章中都用到了相關技巧

有興趣的可以回顧一下,本文相當於這個技巧的另一個應用

二、超過指定行數截斷文字

前面說了,透過-webkit-line-clamp設定的超出文字在Safari下有 bug,所以需要藉助其他方式來實現。

拋開省略號,其實這個比較好實現,給一個固定最大高度,超出就透過overflow:hidden隱藏就行了。

假設佈局是這樣的

<div class="con">
  <div class="txt">
    歡迎關注前端偵探,這裡有一些有趣的、你可能不知道的HTML、CSS、JS小技巧技巧,比如這篇文章,safari又出bug了,省略號和文字重疊了,如何修復這個問題呢?一起看看吧
  </div>
</div>

為了方便行數控制,可以更加行高來確定最大高度,比如 3 行,那麼最大高度就是1.5 * 3 = 4.5em

.txt{
  line-height: 1.5; 
  max-height: 4.5em; /*1.5 * 3*/
  overflow: hidden;
}

這樣整個文字就不會超出 3 行了,只是現在還沒有省略號,如下

image.png

如何新增省略號呢?接著往下看

二、右下角環繞的省略號

這是一個典型的文字環繞佈局。提到環繞,就不得不用上浮動float

我們透過偽元素生成省略號,並設定浮動

.txt::before{
    content: '...';
    float: left;
}

為了方便演示,這裡給偽元素新增了紅色背景,如下

image.png

然後設定右浮動

.txt::before{
    content: '...';
    float: right;
}

這樣省略號跑到了右上角

image.png

然後,將省略號移動到右下角,可以用flex對齊實現

.txt::before{
    content: '...';
    float: right;
    height: 100%;
    display: flex;
    align-items: flex-end;/*居底對齊*/
}

可以看到,省略號已經到了右下角,但是沒有環繞效果

image.png

如何讓這個省略號到右下角呢?這就需要用到 CSS shapes 佈局

shapes佈局可以很輕易的實現任意形狀的環繞效果。我們這個環繞效果很簡單,只需要利用到 shape-outside:inset()就可以了,表示以自身為邊界,然後上、右、下、左四個方向分別向內縮排的距離,也可以想象成在右下角挖個孔,是不是就實現了右下角環繞佈局了?具體實現如下

.txt::before{
    shape-outside: inset(calc(100% - 1em) 0 0 0);
    margin-left: 2px;
}

效果如下

image.png

最後去除背景,看看效果

Kapture 2023-03-11 at 15.11.38.gif

已經很完美了,只是這個省略號一直都在

image.png

四、自動隱藏省略號

可以試試之前用過的 “CSS 障眼法”。

原理很簡單,就是用一個足夠大的色塊蓋住省略號,設定絕對定位後(不設定lefttop),色塊是跟隨內容文字的,

關於這個絕對定位的小技巧,可以參考之前這篇文章:你可能不知道的絕對定位

所以在文字較多時,色塊也跟隨文字擠下去了,實現如下

.txt::after{
    content: '';
    position: absolute;
    width: 999vh;
    height: 999vh;
    background: #fff;
} 

效果是這樣的

Kapture 2023-03-11 at 16.26.20.gif

然後將這個色塊換成和背景相同的顏色就可以了

Kapture 2023-03-11 at 16.30.29.gif

這樣就不會出現省略號重疊的情況了,看下兩者對比(Safari下)

image.png

完整 demo 可以訪問以下任意連結(注意使用 Safari 瀏覽器,iOS也行):

五、總結一下

這樣就相對完美的解決了 Safari 下的小 bug,雖然實現不算特別複雜,但還是有很多小技巧的,下面總結一下

  1. Safari 下在多行打點時如果設定了文字兩端對齊,會導致省略號和文字重疊
  2. 原因在於省略號是自動加上的,Safari 貌似忘記了對這個省略號進行對齊處理,需要手動新增省略號
  3. 多行文字截斷可以藉助 max-height overflow:hidden
  4. 省略號右下角環繞佈局可以接著右浮動和shapes佈局
  5. 自動隱藏省略號可以用一個絕對定位的色塊遮擋實現
  6. 適當積累一些 CSS 奇技淫巧,有時候會幫上大忙

當然,這個方式也有侷限性,僅限於純色背景。另外,我也嘗試了容器查詢,發現並沒有想象中的那麼好用,有興趣的小夥伴可以嘗試一下。最後,如果覺得還不錯,對你有幫助的話,歡迎點贊、收藏、轉發❤❤❤

相關文章