css grid 自动高度_2020年你不应该错过的CSS新特性(二)
茫茫人海中與你相遇
相信未來的你不會很差
作者:阿里巴巴淘系技術
來源:https://juejin.im/post/6886258269137043464
Web排版
先看布局上將會有的一些新特性:
subgrid
CSS Grid布局是Web布局模式中唯一一種二維布局,也是我自己最認可的布局模式(至少到目前為止還沒有發現比Grid更強大的)。如果你從未接觸過Grid布局的話,你可以把他想象成最初的table布局,因為他們倆之間有很多概念都非常的相似。
隨著Web布局技術不斷的更新以及瀏覽器不斷的發展,現在使用Grid布局的越來越多,特別是今年以來,Grid和Flexbox布局的占比越來越近:
上面的數據是來自于MDN,更詳細的可以閱讀MDN Browser Compatibility Report 2020
暫時把你拉回到90年代,那個時候Web的布局主要以table布局為主,在使用table布局的時候也時常會發現表格嵌套表格:
在Grid布局也是相似的,也會碰到網格嵌套網格。
<div class="grid"> <div class="item"> <div class="subitem">div> div>div> /* CSS */.grid { display: grid; grid-template-columns: repeat(9, 1fr); grid-template-rows: repeat(4, minmax(100px, auto));}.item { grid-column: 2 / 7; grid-row: 2 / 4; display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 80px);}.subitem { grid-column: 2 / 4; grid-row: 1 / 4;}網格嵌套在網格中,各自的網格軌道是相互獨立的,不過也會引起子網格中元素對齊會存在一些問題。不過在 CSS Grid Layout Module Level 2(drafts.csswg.org/css-grid-2) 模塊中新增了 subgrid 屬性(Firefox 71開始就支持該屬性)。
有了subgrid之后,在嵌套網格的時候,我們就可以在grid-template-columns和grid-template-rows設置subgrid。這樣一來,上面示例的代碼我們就可以修改成:
.grid { display: grid; grid-template-columns: repeat(9, 1fr); grid-template-rows: repeat(4, minmax(100px, auto));}.item { grid-column: 2 / 7; grid-rows: 2 / 4; display: grid; grid-template-columns: subgrid; grid-template-rows: subgrid;}.subitem { grid-column: 3 / 6; grid-row: 1 / 4;}這樣一來,子網格就會繼承其父網格的網格軌道,反過來,在使用任何類型的自動調整(比如,auto、min-content、max-content等)時也會影響其維度(尺寸)。
在我們平時的一些UI布局中,subgrid就可以用得上了:
我們一起來看一個subgrid的具體實例。注意,請使用Firefox 71+查看上面的Demo,看到的效果如下:
subgrid和grid一樣,是一套復雜的體系,如果要說清楚subgrid的話,可能會要多文章文章才能講清楚。如果你對subgrid感興趣的話,還可以閱讀下面這幾篇文章:
- CSS Grid Layout Module Level 2: subgrid
- Hello subgrid!
- CSS Grid Level 2: Here Comes Subgrid
- MDN: Subgrid
- Irregular-shaped Links with Subgrid
可用于雙屏幕和可折疊屏幕的媒體查詢條件和環境變量
隨著技術不斷的發展,我們所面對的終端個性化越來越強,比如現在市場上已有或將有的雙屏幕和可折疊屏幕設備:
作為Web開發者,我們終究有一天需要面對這些終端的適配處理。到目前為止,CSS世界具備處理方面適配的能力,即使用screen-spanning媒體查詢條件和env(fold-left)、env(fold-top)、env(fold-height)及env(fold-width)環境變量:
有了這些特性,我們就可以很輕易的實現像下圖這樣的布局效果:
如果你對這方面的知識感興趣的話,可以閱讀下面幾篇文章,這幾篇文章也是全網介紹雙屏幕和可折疊屏幕最詳細的教程:
聊聊安卓折疊屏給交互設計和開發帶來的變化
可折疊Web可能會給我們帶來的變化
可用于雙屏幕和折疊屏的Web API
瀑布流布局
瀑布流布局(Masonry Layout)也是Web布局中的典型布局之一:
雖然能使用CSS的多列布局、Flexbox布局和Grid布局等模擬出瀑布流布局效果,但更多的同學還是更喜歡使用一些JavaScript庫來實現瀑布流布局,比如 Masoonry。
為了能讓原生的CSS直接實現瀑布流布局效果,早在2017年社區中就有人提出用原生的CSS實現瀑布流布局效果,不幸的是,直到現在也還只是一個實驗性的屬性,而且僅在Firefox Nightly瀏覽器中支持。
.masonry { display: grid; gap: 20px; grid: masonry / repeat(auto-fill, minmax(250px, 1fr));}比如這個Demo。
為了能在Firefox Nightly瀏覽器能正常的查看上面Demo的效果,你需要確保開啟了相應的功能。如果沒有的話,請在Firefox Nightly瀏覽器地址欄中輸入about:config,然后搜索layout.css.grid-template-masonry-value.enabled,并將其設置為true:
然后重啟瀏覽器,查看Demo,你看到的效果將會是像下面這樣:
gap
“Gap”從字面上來解釋的話可以有“間隙,間隔”之意。那么在Web的布局中總是避免不了處理塊與塊以及行與行之間的間距。
而在CSS的世界中,用來控制元素之間的間距的間距,一般會使用盒模型中的外距,即 margin 屬性,但是往往很多時候,使用margin來控制元素之間間距并不能很好的滿足設計師的訴求。比如說,元素只和元素之間有間距,但和它的父容器之間沒有任何的間距。針對于這樣的場景,使用gap屬性會比使用margin要容易控制的多。
注意,上圖來自于《Next-generation web styling》一文。
CSS的gap屬性自身最大的特點就是:gap是相對于流的,這意味著它會根據內容流的方向動態變化。比如說書寫模式的改變,gap也會自動改變。
早期在CSS中,gap分很多種,在不同的容器格式中,叫法不同,比如在多列布局(Multi-column Containers)中對應的是column-gap:
body { column-gap: 35px;}但在網格容器(Grid Containers)又被稱為grid-row-gap和grid-column-gap。
除此之外,它還可以被運用于Flexbox容器(Flexbox Containers),只不過早前,在Flexbox中沒有類似flex-row-gap和flex-column-gap這樣的屬性。
需要注意的是,在Flexbox模塊中是沒有gap屬性,但這并不影響我們在Flexbox布局中使用gap屬性,這是因為gap統一納入到了 CSS Box Alignment Module Level 3模塊。而且gap是row-gap和column-gap的簡寫屬性:
我們現在可以在多列布局,Flexbox布局和網格布局中像下面這樣使用gap:
// 多列布局.multi__column { gap: 5ch}// Flexbox布局.flexbox { display: flex; gap: 20px}// Grid布局.grid { display: grid; gap: 10vh 20%}從上面示例代碼中我們可以發現,gap是row-gap和column-gap的簡寫屬性,而且gap可以接受一個值也可以接受兩個值,當gap只有一個值時,表示row-gap和column-gap的值相同;當gap有兩個值時,其中第一個值是row-gap,第二個值是column-gap。
.gap { gap: 10px;}// 等同于.gap { row-gap: 10px; column-gap: 10px}.gap { gap: 20px 30px;}// 等同于.gap { row-gap: 20px; column-gap: 30px;}特別聲明一點,雖然CSS新增了gap屬性(row-gap、column-gap),但Grid中早期的grid-row-gap和grid-column-gap屬性同樣可用。
aspect-ratio
aspect-ratio 是 CSS Box Sizing Module Level 4 模塊中的一個用來計算元素盒子寬高比的屬性。在這個屬性還沒有之前,在CSS中都是通過其他一些方法來模擬寬高比的效果。比如:
.aspectration { position: relative;/*因為容器所有子元素需要絕對定位*/ height: 0; /*容器高度是由padding來控制,盒模型原理告訴你一切*/ width: 100%; } .aspectration"https://codepen.io/rachelandrew/pen/WNrRZaV"> padding-top: 56.25%; } .aspectration[data-ratio="4:3"]{ padding-top: 75%; }如果瀏覽器支持了aspect-ratio的話,可以像下面這樣使用:div { aspect-ratio: 1 / 1;}比如[@rachelandrew在Codepen提供的一個示例,我在該示例的基礎上稍作調整了一下(codepen.io/airen/pen/v…
:target和:target-within
:target和:target-within都是 Selectors Level 4 模塊中的兩個偽元素。可能很多同學對:target更熟悉一些,甚至用:target偽元素的特性制作了 Tab 、Accordion 和 Modal 等UI交互效果。
比如下面這個手風琴的效果就是用:target偽元素制作的:
這里簡單的來看看:target和:target-within的作用。
在某些文檔語言中,文檔的URL可以通過URL的片段進一步指向文檔中的特定元素。以這種方式指向的元素是文檔的目標元素。其中片段標識符是URL中緊跟#的部分,例如#top或#fontnote1。你可能已經使用它們創建頁面內導航,比如大家常見的“跳轉鏈接”。有了:target偽類,我們可以突出顯示與該片段對應的文檔部分,而且無需JavaScript也可以做到這一點。
比如下面這個簡單的示例:
<h3>Table of Contentsh3><ol> <li><a href="#p1">Jump to the first paragraph!a>li> <li><a href="#p2">Jump to the second paragraph!a>li> <li><a href="#nowhere">This link goes nowhere, because the target doesn't exist.a>li>ol><h3>My Fun Articleh3><p id="p1">You can target <i>this paragraphi> using a URL fragment. Click on the link above to try out!p><p id="p2">This is <i>another paragraphi>, also accessible from the links above. Isn't that delightful?p>/* CSS */p:target { background-color: gold;}/* 在目標元素中增加一個偽元素*/p:target::before { font: 70% sans-serif; content: "?"; color: limegreen; margin-right: .25em;}/*在目標元素中使用italic樣式*/p:target i { color: red;}點擊示例中的鏈接,你可以看到像下圖的效果:
而:target-within偽類應用于:target偽類所應用的元素,以及在平面樹(Flat Tree)的后代(包括非元素節點,比如文本節點)與匹配:target-within的條件相匹配的元素。
article:target-within { background-color: hsl(var(--surfaceHSL) / 10%); } 其實在選擇器Level 4模塊中還新增了很多其他的偽類選擇器,如果你對這方面新增的選擇器感興趣的話,可以聽一聽@Adam Argyle和@Ana Tudor一起辦的CSS Podcast,其中第十四期就是專門聊CSS的偽類選擇器的。
CSS邏輯屬性
如果你閱讀過《Web中向左向右》一文或者有接觸過CSS書寫模式特性,你會發現以前我們熟悉的物理屬性在不同的語言環境之下很難滿足布局的需求,比如英語和阿拉伯語,日語和蒙語等,我們設置的margin-left有可能不是margin-left,width也有可能不是width。
這個時候,CSS邏輯屬性就顯得尤其重要。換句話說,邏輯屬性的出現,我們以往熟悉的盒模型也將帶來很大的變化:
下圖是我們熟悉的 物理屬性 和 邏輯屬性 的對應關應:
對于塊軸(block axis)和內聯軸(inline axis)區別,同樣用一張圖來描述這兩者吧:
塊軸和內聯軸和CSS的書寫模式writing-mode以及direction和HTML的dir有關系。換句話說:
塊軸:主要定義網站文檔(元素塊)流,CSS的書寫模式writing-mode會影響塊軸的方向
內聯軸:主要定義網站的文本流方向,也就是文本的閱讀方式,CSS的direction或HTML的dir會影響內聯軸的方向
有關于writing-mode、direction和dir對Web排版的影響相關的詳細介紹可以閱讀《Web中向左向右》一文。
min() max() 和 clamp()
min()、max()和clamp()三個函數稱為“比較函數”。早在《聊聊min(),max()和clamp()函數》一文中對其做過詳細的介紹。這里不做詳細介紹,僅和三張圖來分別展示他們的功能。
我們可以使用 min()設置最大值:
max()和min()相反,返回的是最大值。使用max()設置一個最小值:
clamp()函數和min()以及max()不同,它返回的是一個區間值。clamp()函數接受三個參數,即 clamp(MIN, VAL, MAX),其中MIN表示最小值,VAL表示首選值,MAX表示最大值。它們之間:
如果VAL在MIN和MAX之間,則使用VAL作為函數的返回值;
如果VAL大于MAX,則使用MAX作為函數的返回值;
如果VAL小于MIN,則使用MIN作為函數的返回值
這里有一個關于clamp()的示例,嘗試著拖動瀏覽器視窗的大小,你可以看到類似下圖這樣的效果:
我們再來看幾個和文本相關的特性:
leading-trim 和 text-edge
一直以來,在Web的排版中行高(line-height)總是令Web開發者感到困惑和頭痛,主要是因為line-height在CSS中是一個非常復雜的體系。他的計算總是會涉及到很多因素:
@iamvdo的《Deep dive CSS: font metrics, line-height and vertical-align》一文對這方面做過深入的闡述!
在還原UI時,文本的行高總是讓我們計算元素塊之間的間距帶來一定的麻煩:
為了解決這方面的煩惱, CSS Inline Layout Module Level 3新增了一個leading-trim和text-edge屬性。可以讓我們刪除每一種字體中的額外間距,以便我們可以更好的計算相鄰塊元素之間的間距。
h1 { leading-trim: both; text-edge: cap alphabetic;}復制代碼上面的示例首先使用text-edge來告訴瀏覽器想要的文本邊緣是cap高度和字母基線(alphabetic baseline)。然后用leading-trim對文本兩邊進行修剪。
注意,leading-trim只影響文本框,它不會切斷其中的文字。
示例中的兩行簡單的CSS創建了一個包含文本的干凈的文本框(不受line-height相關的特性影響)。這有助于實現更精確的間距,并創建更好的視覺層次結構。
CSS的text-edge和leading-trim分別可接受的值:
text-edge: leading | text | cap | ex | ideographic | ideographic-ink ] [ text | alphabetic | ideographic | ideographic-ink ]?leading-trim:?normal?|?start?|?end?|?both如果你對leading-trim特性感興趣的話,除了閱讀規范之外,還可以閱讀下面幾篇文章:
[The Thing With Leading in CSC]
Leading-Trim: The Future of Digital Typesetting
Rethinking line-sizing and leading-trim
::grammar-error 和 ::spelling-error
::grammar-error和::spelling-error是兩個非常有意思的偽元素選擇器。從字面說我們可以知道, Grammar error 指的是語法錯誤, Spelling error指的是拼寫錯誤。其實這兩種現象在我們平時書寫文本的時候經常可見,可能會由于手誤, 將某個單詞或標點符號用錯,甚至語法上的錯誤。針對于這種現象,我們總是希望有一定的提示信息來提示我們,比如顏色上的差異,添加一些下劃線等等:
在 CSS Pseudo-Elements Module Level 4 的高亮偽元素中我們可以看到這兩個偽元素的身影:
::grammar-error:瀏覽器為語法錯誤的文本段添加樣式
::spelling-error:瀏覽器為拼寫錯誤的文本段添加樣式
在CSS中并不是所有屬性都能運用于這兩個偽元素,到目前為止,只有color、background-color、cursor、text-emphasis-color、text-shadow、outline、text-decoration、fill-color、stroke-color 和stroke-width可以用于這兩個偽元素。
:root::spelling-error { text-decoration: spelling-error; }:root::grammar-error { text-decoration: grammar-error; }"https://drafts.csswg.org/css-values-4">spellcheck]::spelling-error { text-decoration: wavy underline var(--neon-red);}[grammarcheck]::grammar-error { text-decoration: wavy underline var(--neon-blue);}新增相對單位:cap、lh、rlh、vi和 vb
[CSS中單位和值(drafts.csswg.org/css-values-…) 中單位有:
但在 相對單位中并沒有提到cap、lh、rlh、vi和vb這幾個相對單位。
從上表的描述來看,其中cap、lh、rlh的計算都和元素的字體以及行高等有關系。我用下圖來描述一個字體的Cap Height,Line Height等:
我們在虛擬的空間與你相遇,期待可以碰撞出不一樣的火花
公眾號ID:前端大聯盟掃碼關注最新動態總結
以上是生活随笔為你收集整理的css grid 自动高度_2020年你不应该错过的CSS新特性(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python format函数实例_Py
- 下一篇: java contains_Java基础