如何實現 font-size 的響應式

Erichain發表於2019-03-01

本文樣式程式碼採用 SCSS。

那麼多的文章講了響應式的網站如何佈局,使用 CSS 如何實現,如何 Blah Blah 的。但是,我們都忘了很重要的一點——對字型大小的響應式控制。

現在的很多網站,從佈局上來說,儘管是響應式的(當然,或許可以說成所謂響應式的)。但是,從字型上來說,卻不一定是響應式的。雖然,每個網站可能會通過某些方式(比如頻繁使用 @media )來讓自己的網站在不同的螢幕大小下顯示不同大小的字型,但是,這樣不能叫做響應式,這只是一種適應式的做法。

那麼,怎麼樣才能對我們的 font-size 實現真正的響應式呢?

我們需要做的主要有以下兩點:

1、制定一個最大的和最小的螢幕寬度值,我們的 font-size 應該是在這個螢幕範圍內平滑均勻的變化;

不可能讓字型大小一直不停的變化。試想一下,自己一直縮小或者方法瀏覽器,字型一直變小或者變大的場景。

2、制定最大和最小的 font-size,螢幕大小小於最小的螢幕寬度值的時候,應用最小的 font-size,反之,應用最大的 font-size

OK,計劃制定好了,那麼,應該如何實施呢?我們需要用到哪些技術呢?

其實要用到的技術不多,只是,我們需要把腦子轉一下。

  • @media:CSS Level 3 提供的媒體查詢,只要做過響應式,或者任何適應螢幕功能的肯定用過這個屬性。所以,在此不過多解釋此屬性,詳細可檢視 @media | MDN
  • vw:Viewport 單位,1vw 相當於螢幕寬度的百分之一。此處也不過多解釋,詳細可檢視 length | CSS
  • calc:這是 CSS 提供的一個非常強大的屬性,可以用來動態計算 CSS 的值。我們的功能主要就是通過這個函式來實現。詳細可檢視 calc | MDN

OK,需要的技術也齊全了。那麼,現在就來一步一步實現。

定義變數

按照上文中所說的計劃那樣,我們需要定義四個值,他們分別是最小螢幕寬度,最大螢幕寬度,最小字型,最大字型。

$min-font-size: 14px;
$max-font-size: 18px;
$min-screen: 600px;
$max-screen: 1200px;複製程式碼

不過,使用 px 來定義字型大小顯得不是很優雅,我們可以使用 rem 來定義我們的字型。那麼,這時候,就需要先對網站的根元素設定字型大小了。

:root {
    font-size: 10px;
}複製程式碼

然後,再來更新我們的變數。

$min-font-size: 1.4rem;
$max-font-size: 1.8rem;
$min-screen: 600px;
$max-screen: 1200px;複製程式碼

我們把我們的變數定義和根元素的 font-size 放在檔案的頂部。在這裡,我們就不寫那些相關的 reset 等樣式了。

加入測試內容

起了個好頭,然後進行下一步,很簡單,寫我們的 HTML,此處不做過多贅述。

<header>
    <h2>This is Header.</h2>
</header>
<section>
    <article>
        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    </article>
</section>複製程式碼

使用 @media 對限制字型大小邊界值

上文中說過,在我們的螢幕寬度小於 600px 的時候,字型大小為 1.4rem,螢幕寬度大於 1200px 的時候,字型大小為 1.8rem。這個功能實現起來很簡單,只需要應用相應的一小段媒體查詢就行了。

@media (min-width: $max-screen) {
    article {
        font-size: $max-font-size;
    }
}

@media (max-width: $min-screen) {
    article {
        font-size: $min-font-size;
    }
}複製程式碼

OK,就這麼一段程式碼,我們就可以將字型大小的邊界值進行限制。在螢幕寬度小於或者大於對應的螢幕寬度值的時候,我們的字型大小都會保持在一個恆定的值。

那麼,邊界限制做好了,接下來就是要實現真正的響應式了。怎麼說呢?我們要讓我們的 font-size600px ~ 1200px 的螢幕寬度範圍內平滑的變化。當然,這還不夠,並不是說,只是給 font-size 設定一個百分比或者任何其他的相對單位,然後讓這個字型能夠在放大縮小螢幕的同時也能夠放大縮小。我們要做的,是要通過精確的大小控制來實現響應式。

使用 calc 函式實現字型大小的響應式

仔細看看上文中對字型大小邊界值的限制的程式碼,已經有兩個 @media 了,在這個部分,我們肯定還要加一個 @media,是不是顯得有點多餘?所以,我們可以稍微精簡一下。

article {
    font-size: $min-font-size;
}

@media (min-width: $min-screen) and (max-width: $max-screen) {
    // ...
}

@media (min-width: $max-screen) {
    article {
        font-size: $max-font-size;
    }
}複製程式碼

只要兩個 @media 其實就夠了。對於不在媒體查詢範圍內的,只需要設定一個預設值就行了。但是,要注意的是,這個預設值一定要寫在兩個媒體查詢規則的前面。否則,會由於 CSS 的層疊的特性,後宣告的樣式會覆蓋掉先宣告的樣式,從而導致媒體查詢規則不起作用。

那麼,要實現在這個螢幕寬度範圍內精確平滑的變化,肯定需要用到一點數學計算。

1、font-size 變化的範圍是 1.8rem - 1.4rem = 0.4rem

2、螢幕寬度的變化範圍是 1200px - 600px = 600px

3、最小的 font-size1.4rem。那麼,螢幕寬度只要大於 600px,這個值肯定會增加,同時,只要螢幕寬度達到 1200px,這個值也達到 1.8rem,然後便不再變化;

可以看下圖:

比如,我們現在有三種螢幕寬度,分別是 600px,1000px,1200px。那麼,仔細觀察左邊的參考線,我們將最小的那個螢幕寬度去掉,相當於就剩下了兩個值,一個是 a,一個是 b。

由於 1200px 是我們設定的螢幕寬度的最大值,那麼,也就是說,b 的變化範圍最大也就是 a 的長度。通俗一點說就是,可以把 a 和 b 看成進度條,a 為 100% 的長度,b 為不斷增加或者減少的長度。所以,這裡就存在了一個比例值,當 b 為 0 的時候,這個比例也為 0,當 b 為 100% 的時候,這個比例就是 1。

那麼,按照這樣的思路,轉換到對應 font-size 的變化:變化範圍是 0.4rem,這是分母,那麼,分子該如何計算呢?我們怎麼知道字型增加了多少呢?

此處肯定是沒有減少的。我們是在 600px ~ 1200px 之間變化的,最小的字型為 1.4rem,無論怎麼算,字型大小都不會再減小了。

所以,此處還有一個小小的轉換。想一想,我們變化的不只是字型大小,還有螢幕寬度也在變化。所以,就像圖片解釋的那樣,可以使用螢幕寬度的計算來得到一個相應的比例,然後,乘以 font-size 的變化範圍 0.4rem,就可以得到我們增加的字型大小了。然後,在最小 font-size 的基礎之上加上這個變化的範圍,就可以得到在對應螢幕寬度下的精準的 font-size了。

所以,使用 calc 可以這樣寫:

@media (min-width: $min-screen) and (max-width: $max-screen) {
    article {
        font-size: calc($min-font-size + (1.8 - 1.4) * ((100vw - $min-screen) / (1200 - 600)));
    }
}複製程式碼

注意,calc 函式在計算除法的時候,/ 右邊只能是數字,不能帶單位。* 要求至少一個引數是數字。

對這個式子我也解釋一下,可以看到,其中有個表示式是 100vw - 600px,這是什麼意思呢?

轉換成文字:瀏覽器可視區域的寬度減去最小寬度。

其實理解起來很簡單,舉個例子:假設現在螢幕寬度為 1000px,那麼,100vw - 600px 得到的結果為 400px,然後,除以 600,最後得到的是 2 / 3。然後,這個值去乘以 0.4rem,那麼,這樣就能計算出增加的字型大小值了,然後加上 1.4rem,就能得到最終的一個 font-size了。

所以,就這樣,我們就對 font-size 實現了響應式。不用再通過各種螢幕大小的媒體查詢來變化了。

值得慶幸的是,此規則對於 line-height 同樣適用。

以下是完整的 SCSS 程式碼:

$min-font-size: 1.4rem;
$max-font-size: 1.8rem;
$min-screen: 600px;
$max-screen: 1200px;

:root {
    font-size: 10px;
}

article {
    font-size: $min-font-size;
}

@media (min-width: $min-screen) and (max-width: $max-screen) {
    article {
        font-size: calc($min-font-size + (2 - 1.4) * ((100vw - $min-screen) / (1200 - 800)));
    }
}

@media (min-width: $max-screen) {
    article {
        font-size: $max-font-size;
    }
}複製程式碼

References

Precise control over responsive typography

Flexible typography with CSS locks

相關文章