不像響應式布局,通過media query,設置幾個變化點來適配,流體排版通過調整大小,適配所有設備寬度。這個方法可以使我們開發的網頁,在幾乎所有屏幕尺寸上都可以使用。但出于一些原因,它的使用率還遠遠沒有響應式技術高。
在印刷的歷史上,排版是根深蒂固的。關于“流體”的概念,在傳統思想里并不存在。這是因為,在印刷上,尺寸大小都是有固定的,不用考慮在頁面上使用。我認為流體排版技術可以和網頁很好的匹配。這是在不同媒介上的一種解決方法。
并不意味著我們要推翻之前的所有關于排版的認識,只需要去學習如何用不同方式,去運用掌握新的技術。只要注意細節,就可以制作出適配所有屏幕尺寸的完美的頁面。
視口(viewport)單位,使流體排版在頁面上應用變為可能。視口單位是根據瀏覽器的視口尺寸的百分比來定義的。
舉個例子,1視口寬度(vw)等于視口寬度的1%,它不同于百分比的地方是,它的寬度是依賴于視口的寬度的,而百分比是元素的祖先元素來決定的。
視口單位,不同于其它單位,它不依賴于基礎字體的大小。這種差別很重要,使它變得有意義而且獨特。
可以使用的4種視口單位:
使用流體排版最簡單的方法,是把html元素的font-size,設置為一個流體單位:
html{ font-size: 2vw; }
這個例子中,我們把根元素的字體大小設置為2vw。這里我們已經修改了根元素字體大小。因為直接或間接使用的em或rem單位,都是依賴于"root rem"的,所以也變成流體的了。例如
h1{ font-size:2em; }
h1的font-size:2em,如果它依賴的是根節點的字體大小,那么 font-size:2*2vw=4vw。
只使用視口相關的單位也有一些不足。
html設置為font-size:2vw的方法,看起來既是流體的,調用起來也很方便,但有些場景沒法覆蓋。視口單位不是萬能的,它也需要使用一些其它的方法,來解決無法覆蓋的場景。由于視口單位都是依賴于視口的,在非常小的屏幕上,會得到很小的字體大小,已致無法查看。(chrome的最小字體是12px,好像可以解決了。)
理想情況下,我們可以通過設置最小字體來避免這種情況,但CSS中沒有min-font-size這個屬性。通過一些橫向思維,我們可以得到實現這種效果的方法。
首先,我們可以使用calc()表達式。
html{ font-size: calc(1em + 1vw); }
這樣就算我們在一個0寬度的視口中,font-size的大小也會存在,并為1em。在大的屏幕上,1vw也會在最小字體1em的基礎上增加。但是這種解決方法也不是最理想的。通常我們只是想在一些小的屏幕上去設置最小字體。我們可以使用media query來解決:
@media screen and (min-width: 50em) { html { font-size: 2vw; }}
上面代碼設置,是僅在當視口寬度大于50em的時候,使用流體。雖然這樣能很好的工作,但也表明會在固定值和流體值之間跳動。為了解決這個問題,我們可以計算出流體值和固定值之間的對應關系。
如果默認字體大小是16像素,并且2vw是2%的視口寬度,那么可以知道在800像素的視口時兩個值是相等的。(16/(2/100)=800)
因為我們想在media query中,使用em單位來匹配。現在來換算一下像素到em。800像素除以16:800/16=50。我們也可以使用這個公式來算1/(2/100)=50。和上面例子里使用的變化條件一樣,2vw對應的是50em。最終,我們得到了一個不會在固定和流體之間,產生跳動變化的值。
同樣的可以用公式去算出最大字體。如果我們想使用的最大字體是24像素,那么對應的視口寬度就是24/(2/100)=1200px。換算成字體,就是1.5/(2/100)=75em。如果視口寬度大于75em時,我們就把字體大小設置成固定值。
@media screen and (min-width: 75em) { html { font-size: 1.5em; }}
這些計算都不是太難,下面做了一個表格,顯示了各視口寬度,流體大小對應的字體大小。
通過這個表格,你可以獲得一些控制視口單位變化。使用單獨的視口單位,可以只看對應的一列中的字體大小。
在不使用media query的情況下,我們不可能解決,在400像素的屏幕上顯示16像素的字體,在800像素顯示24像素的問題。
還有,你可能會說,可以使用設置最大最小字體的方式,來解決這個問題。但這里不是像那樣來處理的。
我們要怎么去解決這個問題呢?答案是使用calc()。使用calc和視口單位配合,我們可以用高級的流體排版,可以精確地控制一定范圍內的視口寬度使用特定大小的像素值。這里需要建立一個基本的數字函數:
這個函數可以能過一個范圍內的一個值,可以計算出另一個對應范圍的值。如果你取1-100的中的50,用它獲取1-200的值 ,你將得到100。(其實我得到的是(1+(200-1)*(50-1)/(100-1)=99.4949495))。這兩個值都是各自范圍的中間值。
這是一個求映射值的工具函數,在JS中處理數據時經常使用。當我認識到這只是一個純粹的數學函數,我只需要一個變化的量,我使用calc()來運行這個函數。這里的變化關鍵值是視口大?。阂暱诖笮【褪且粋€變量。100vw是一個變化的值,它是根據視口的尺寸變化的。有了最終的設想,花了一段時間來獲得了能工作的函數表達式。calc()函數以其獨特的方式來處理不同的單位類型。如果你對這方面感興趣,強烈推薦《 W3C對單位類型和值規范》,不為別的,就為了你在同事之間溝通時,可以吹牛B。
計算看上去很復雜,其實很簡單。我們選擇最小和最大字體值,并且可以根據屏幕的尺寸來獲取精確的字體大小。我們可以使用任何單位,包括em,rem,px。這里拿像素來舉例,是因為可以解釋起來更方便并更好理解,但正常工作中我是使用rem單位的??茨阕约旱南埠美?,但有一點,方程式里所有的值必須是單位統一的,而且你也要像上面的例子中一樣,去除一些單位。
如果你不想輸入上面的代碼,有一些工具可以幫助你實現。比如:SASS,LESS,PostCSS插件。這樣你就可以輕松的工作了。
在《The elements of typographic style》,Robert Bringhurst 提出一個合理的閱讀長度 大約是45到75個字符的長度
Anything from 45 to 75 characters is widely regarded as a satisfactory length of line for a single-column page set in a serifed text face in a text size. The 66-character line (counting both letters and spaces) is widely regarded as ideal.
同樣的規則可以直接運用到流體排版上,很多情況下,文件縮放實現一致的閱讀長度是可能的。
在響應式方法里,我們在media query里設置不同的字體大小,調整容器的寬度,來保持正確的閱讀長度。然而,使用流體排版,調整media query下的值方法已經行不通了。 只是設置容器的大小,使它的比率和字體相同。我們可以使用像上文提到的計算font-size的方法,使用 calc()來計算width屬性的值。這可以保持閱讀長度-而且樣式表也更容易閱讀和維護了。
在非常小的屏幕維護理想的閱讀長度是不可能的。這種情況下,我們選擇把容器的寬度設置為智能移動設備的寬度。
模塊化縮放是指一組成比例的數值。看圖可以更直觀地看到效果:
每個標題都是下面標題的1.2倍大小。
不用的屏幕尺寸顯示不同的綻放效果會更好。
在小屏幕的時候,標題大小顯示得更統一。在大屏幕上有足夠的空間可以顯示更大的差別。我們可以使用排版技術來使在不同的模板縮放變化時更平滑。簡單地在不同的屏幕上選擇不的縮放比率,然后計算出每個的標題級別,不同的最小和最大的字體大小。
計算模塊化的縮放,使用基礎字體大小乘以一個期望的比率來得到一個大的值。得到小值是用除法。使用相同的方法去計算出每個縮放對應的值。
大值:
小值:
我們使用1.125做為我們最小縮放比率,1.250做為我們最大縮放比率。下面我們把這個縮放比率應用到每個級別的標題級別上。
讓我們在codepen上演示一下流體模塊縮放標題。你可以從Tim Brown的《排版的意義》是去了解更多的模塊綻放信息。
如何去選擇一個合適的縮放比率,推薦 Jeremy Church的網站Type Scale,Tim brown、Scott Kellum的Modular Scale網站
縱向排版有必要保持頁面元素之間的空白一致。這方面信息可以讀Espen Brunborg的《CSS Baseline: The Good, the Bad and the Ugly》。
在我們的層上保持縱向排版,需要設置一個元素之間的垂直空白的比例。找到一個在大屏幕和小屏幕上都適配的垂直排版,是很有挑戰性的。我們通常希望找出大屏和小屏的基本度量,或使用不同的比例。
在流體排版中,基線也像字體大小一樣是流體的。事實上,你給根元素設置一個流體的值,你可以使用em或rem單位。你也可以使用calc()來計算。
我們設置baseline為1.5rem,然后把body的padding設置為一個單位的baseline。
body { padding: 1.5rem;}
可以同樣來設置line-height和margin
p { line-height: 1.5rem; margin-bottom: 1.5rem;}
給標題元素設置不同的line-height。我想讓line-height加margin值等于baseline的增量。這里可以使用calc()來計算。
h1 { font-size: 2rem; line-height: 2rem; margin-top: calc((1.5rem - 2rem) + 1.5rem);}
這個例子里,標題元素的height加上margin值等于3rem,正好是baseline值的兩倍。
這里用sass變量創建一個例子,方便大家理解。
未來,使用自定義css屬性,可以對這項技術進行更多的擴展。我們能在calc()表達式中,使用css變量,計算出對應media query中的baseline基值。
當你想在WordPress或Bootstrap,這些已經有預定義的布局中使用,或在已經存在布局的網站上使用,流體排版時。容器有可能不是流體的,或它們不是根據字體大小的比率來改變的。
最近,幫助澳大利亞政府的民眾部,實現了流體排版。這是一個很大的網站,而且我必須根據已有的設計進行制作。在這種大流量的網站上實現流體布局,我有兩個主要方面的問題。
第一問題,怎樣阻止布局被破壞?在這個項目中,我預期導航容器里的內容,會因為字體大小和窗口的改變的比例不同而溢出。但很神奇的是,并沒有出現這個問題。
實際情況,正好相反。之前需要單獨設置來調整的地方,內容很自然的適配了它的容器。總之,樣式表中需要盡量少的media query,大多的組件需要更少的樣式聲明。
還有一個好處是,我們可以不用單獨為平板設備去制作一個單獨的版本,因為這已經可以很好地在小屏幕上工作了。
下面是在過去需要去為每種不同屏幕尺寸調整一個版本的導航組件。雖然在小屏幕下表現還是不太完美,但可以不破壞它的整體性和功能性。
第二個問題,因為里面有很多的固定寬度,所以無法保持每行的字符都有理解的閱讀長度。我在手機和平板電腦上,對字體大小進行了調整,使其保持在理想的閱讀長度--移動設備閱讀更重要。
主容器和文本的縮放比是不同的,當瀏覽器改變大小時,一些文本會重新排列。因為我不想在設備改變方向時,導致閱讀處置改變。這是無法避免的情況,我們只能去測試一下主要設備的影響情況。還好,在移動設備上重排的影響并不是太大。
最后,我們對結果滿意。毫無疑問,可以做更多關于排版的改進,我們已經提高了網站的可讀性。隨著流體排版的經驗越來越多,在下一個設計迭代中,主要的焦點會集中在排版和可讀性上。
經常聽到在Safari和特別是移動版的Safari,在同時使用視口單位和calc()表達式時,會出現明顯的bug。但都沒有提出什么具體的問題是什么,所以這里做了一些測試。
單獨測試了calc()表達式和視口單位,以及同時使用它們來實現流體排版技術。在使用些技術時,沒有發現什么問題。
在現代瀏覽器中,calc()和視口單位都能很好的工作。
在Safari 8以下和ie 11以下瀏覽器,當窗口中瀏覽器改變大小時,calc()表達式中的視口單位,不會重新計算。
可以通過media query來加以修正。
/* Older browsers */ html { font-size: 16px; } /* Modern browsers only need this one */ @media screen and (min-width: 25em){ html { font-size: calc( 16px + (24 - 16) * (100vw - 400px) / (800 - 400) ); } } /* Safari <8 and IE <11 */ @media screen and (min-width: 25em){ html { font-size: calc( 16px + (24 - 16) * (100vw - 400px) / (800 - 400) ); } } @media screen and (min-width: 50em){ html { font-size: calc( 16px + (24 - 16) * (100vw - 400px) / (800 - 400) ); } }
設置了Safary 8以下和ie 11以下,通過media query來重新計算字體大小。
老的瀏覽器則能過js來監聽窗口的改變事件來重新計算字體大小。
可以在caniuse和查看支持情況
如果要使用流體排版,要先想清楚要使用哪種解決方案。
如果整個設計都是流體的,可以考慮使用rem來定義流體,可以聲明html字體大小為一個流體單位??梢允褂胑m和rem來定義所有設計部分。
小心選擇你的最大最小字體。關于這點,你需要決定是否直接使用視口單位或對更加精確地縮放比率。如果是后者,使用Sass,LESS或PostCSS插件中的函數,可以更簡單實現。
確保獲得了正確的字體的最大最小值。這是問題的關鍵。一旦你選定了根元素的字體大小,其它的所有組件都是依賴這個值來計算的。項目中如果后面要調整這個值,那么整個項目都要調整。
不要忘記,在使用流體排版之前定義一個默認的字體大小。默認字體大小,用來在那些不支持流體字體大小的瀏覽器上使用的,這個值不需要和字體最小值 相同。
最后,考慮你的設計上的限制,如何去解決像標題級別和閱讀長度的問題??梢詤⑴c文中的處理方法。如果你的標題組件,想和常規的文本,以不同的比率進行縮放,在添加calc()表達式之前,先考慮可讀性和樣式代碼的可維護性。
我希望這可以給你啟發,可以讓你思考在下個項目中那里可以用到流體排版。
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com