新時代佈局中一些有意思的特性

在最新的 Chrome Canary 中,一個有意思的 CSS 語法 Container Queries 獲得了支持。css

Chrome Canary:開發者專用的每日構建版,站上網絡科技最前沿。固然,不必定穩定~

而在最近幾個 Chrome 版本中,有一些挺有意思的屬性相繼獲得支持,本文就將介紹一下,在今天,新時代佈局中,咱們能逐漸去使用的一些有意思的新特性,經過本文,你將能瞭解到:html

  • flex 佈局中的 gap 屬性
  • 控制容器寬高比屬性 aspect-ratio
  • firefox 下的 CSS Grid 瀑布流佈局(grid-template-rows: masonry)
  • CSS 容器查詢(Container Queries)

flex 佈局中的 gap 屬性

gap 並不是是新的屬性,它一直存在於多欄佈局 multi-column 與 grid 佈局中,其中:前端

  • column-gap 屬性用來設置多欄佈局 multi-column 中元素列之間的間隔大小
  • grid 佈局中 gap 屬性是用來設置網格行與列之間的間隙,該屬性是 row-gapcolumn-gap 的簡寫形式,而且起初是叫 grid-gap

譬如咱們有以下一個 grid 佈局:git

<div class="grid-container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
</div>
.grid-container {
    display: grid;
    border: 5px solid;
    padding: 20px;
    grid-template-columns: 1fr 1fr 1fr;
}
.item {
    width: 100px;
    height: 100px;
    background: deeppink;
    border: 2px solid #333;
}

效果以下:github

grid 佈局

經過給 grid-container 添加 gap 屬性,能夠很是方便的設置網格行與列之間的間隙:chrome

.grid-container {
    display: grid;
    border: 5px solid;
    padding: 20px;
    grid-template-columns: 1fr 1fr 1fr;
+   gap: 5px;
}

而從 Chromium 84 開始,咱們能夠開始在 flex 佈局中使用 gap 屬性了!Can i use -- gap property for Flexbox瀏覽器

Can i use -- gap property for Flexbox

它的做用與在 grid 佈局中的相似,能夠控制水平和豎直方向上 flex item 之間的間距:網絡

.flex-container {
    width: 500px;
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    justify-content: center;
    border: 2px solid #333;
}

.item {
    width: 80px;
    height: 100px;
    background: deeppink;
}

gap 屬性的優點在於,它避免了傳統的使用 margin 的時候須要考慮第一個或者最後一個元素的左邊距或者右邊距的煩惱。正常而言,4 個水平的 flex item,它們就應該只有 3 個間隙。gap 只生效於兩個 flex item 之間。佈局

控制容器寬高比屬性 aspect-ratio

保持元素容器一致的寬高比(稱爲長寬比)對於響應式 Web 設計和在某些佈局當中相當重要。 如今,經過 Chromium 88 和 Firefox 87,咱們有了一種更直接的方法來控制元素的寬高比 -- aspect-ratioCan i use -- aspect-ratioflex

Can i use -- aspect-ratio

首先,咱們只須要設定元素的寬,或者元素的高,再經過 aspect-ratio 屬性,便可以控制元素的總體寬高:

<div class="width"></div>
<div class="height"></div>
div {
    background: deeppink;
    aspect-ratio: 1/1;
}
.width {
    width: 100px;
}
.height {
    height: 100px;
}

均可以獲得以下圖形:

其次,設定了 aspect-ratio 的元素,元素的高寬其中一個發生變化,另一個會跟隨變化:

<div class="container">
    <div>寬高比1:1</div>
    <div>寬高比2:1</div>
    <div>寬高比3:1</div>
</div>
.container {
    display: flex;
    width: 30vw;
    padding: 20px;
    gap: 20px;
}
.container > div {
    flex-grow: 1;
    background: deeppink;
}
.container > div:nth-child(1) {
    aspect-ratio: 1/1;
}
.container > div:nth-child(2) {
    aspect-ratio: 2/1;
}
.container > div:nth-child(3) {
    aspect-ratio: 3/1;
}

當容器大小變化,每一個子元素的寬度變寬,元素的高度也隨着設定的 aspect-ratio 比例跟隨變化:

CodePen Demo -- aspect-ratio Demo

firefox 下的 CSS Grid 瀑布流佈局(grid-template-rows: masonry)

grid-template-rows: masonry 是 firefox 在 firefox 87 開始支持的一種基於 grid 佈局快速建立瀑布流佈局的方式。而且 firefox 一直在推進該屬性進入標準當中。

從 firefox 87 開始,在瀏覽器輸入網址欄輸入 about:config 而且開啓 layout.css.grid-template-masonry-value.enabled 配置使用。Can i use -- grid-template-rows: masonry

正常而言,咱們想要實現瀑布流佈局仍是須要花費必定的功夫的,即使是基於 grid 佈局。在以前,咱們經過 grid 佈局,經過精細化控制每個 grid item,也能夠實現一些僞瀑布流佈局:

<div class="g-container">
  <div class="g-item">1</div>
  <div class="g-item">2</div>
  <div class="g-item">3</div>
  <div class="g-item">4</div>
  <div class="g-item">5</div>
  <div class="g-item">6</div>
  <div class="g-item">7</div>
  <div class="g-item">8</div>
</div>
.g-container {
    height: 100vh;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: repeat(8, 1fr);
}

.g-item {
    &:nth-child(1) {
        grid-column: 1;
        grid-row: 1 / 3;
    }
    &:nth-child(2) {
        grid-column: 2;
        grid-row: 1 / 4;
    }
    &:nth-child(3) {
        grid-column: 3;
        grid-row: 1 / 5;
    }
    &:nth-child(4) {
        grid-column: 4;
        grid-row: 1 / 6;
    }
    &:nth-child(5) {
        grid-column: 1;
        grid-row: 3 / 9;
    }
    &:nth-child(6) {
        grid-column: 2;
        grid-row: 4 / 9;
    }
    &:nth-child(7) {
        grid-column: 3;
        grid-row: 5 / 9;
    }
    &:nth-child(8) {
        grid-column: 4;
        grid-row: 6 / 9;
    }
}

效果以下:

CSS Grid 實現僞瀑布流佈局

CodePen Demo -- CSS Grid 實現僞瀑布流佈局

在上述 Demo 中,使用 grid-template-columnsgrid-template-rows 分割行列,使用 grid-row 控制每一個 grid item 的所佔格子的大小,可是這樣作的成本過高了,元素一多,計算量也很是大,而且仍是在咱們提早知道每一個元素的高寬的前提下。

而在有了 grid-template-rows: masonry 以後,一切都會變得簡單許多,對於一個不肯定每一個元素高度的 4 列的 grid 佈局:

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}

正常而言,看到的會是這樣:

簡單的給容器加上 grid-template-rows: masonry,表示豎方向上,採用瀑布流佈局:

.container {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
+ grid-template-rows: masonry;
}

即可以輕鬆的獲得這樣一種瀑布流佈局:

若是你在使用 firefox,而且開啓了 layout.css.grid-template-masonry-value.enabled 配置,能夠戳進下面的 DEMO 感覺一下:

CodePen Demo -- grid-template-rows: masonry 實現瀑布流佈局

固然,這是一個最簡單的 DEMO,關於更多 grid-template-rows: masonry 相關知識,你能夠詳細的看看這篇文章:Native CSS Masonry Layout In CSS Grid

CSS 容器查詢(Container Queries)

什麼是 CSS 容器查詢(Container Queries)?

在以前,對於同個樣式,咱們若是但願根據視口大小獲得不同效果,一般使用的是媒體查詢

可是,一些容器或者組件的設計可能並不老是與視口的大小有關,而是與組件在佈局中的放置位置有關。

因此在將來,新增了一種方式能夠對不一樣狀態下的容器樣式進行控制,也就是容器查詢。在最新的 Chrome Canary 中,咱們能夠經過 chrome://flags/#enable-container-queries 開啓 Container Queries 功能。

假設咱們有以下結構:

<div class="wrap">
    <div class="g-container">
        <div class="child">Title</div>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Necessitatibus vel eligendi, esse illum similique sint!!</p>
    </div>
</div>

正常狀況下的樣式以下:

.g-container {
    display: flex;
    flex-wrap: nowrap;
    border: 2px solid #ddd;

    .child {
        flex-shrink: 0;
        width: 200px;
        height: 100px;
        background: deeppink;
    }
    
    p {
        height: 100px;
        font-size: 16px;
    }
}

結構以下:

在將來,咱們能夠經過 @container query 語法,設定父容器 .wrap 在不一樣寬度下的不一樣表現,在上述代碼基礎上,新增下述代碼:

.wrap {
    contain: layout inline-size;
    resize: horizontal;
    overflow: auto;
}
.g-container {
    display: flex;
    flex-wrap: nowrap;
    border: 2px solid #ddd;
    .child {
        flex-shrink: 0;
        width: 200px;
        height: 100px;
        background: deeppink;
    }
    p {
        height: 100px;
        font-size: 16px;
    }
}
// 當 .wrap 寬度小於等於 400px 時下述代碼生效 
@container (max-width: 400px) {
    .g-container {
        flex-wrap: wrap;
        flex-direction: column;
    }
    .g-container .child {
        width: 100%;
    }
}

注意這裏要開啓 @container query,須要配合容器的 contain 屬性,這裏設置了 contain: layout inline-size,當 .wrap 寬度小於等於 400px 時,@container (max-width: 400px) 內的代碼則生效,從橫向佈局 flex-wrap: nowrap 變換成了縱向換行佈局 flex-wrap: wrap

若是你的瀏覽器已經開啓了 chrome://flags/#enable-container-queries,你能夠戳這個代碼感覺一下:

CodePen Demo -- CSS @container query Demo

媒體查詢與容器查詢的異同,經過一張簡單的圖看看,核心的點在於容器的寬度發生變化時,視口的寬度不必定會發生變化

這裏僅僅是介紹了 @container query 的冰山一角,更多內容你能夠戳這裏瞭解更多:say-hello-to-css-container-queries

最後

好了,本文到此結束,但願對你有幫助 :)

想 Get 到最有意思的 CSS 資訊,千萬不要錯過個人 iCSS 公衆號 -- iCSS前端趣聞

更多精彩 CSS 技術文章彙總在個人 Github -- iCSS ,持續更新,歡迎點個 star 訂閱收藏。

若是還有什麼疑問或者建議,能夠多多交流,原創文章,文筆有限,才疏學淺,文中如有不正之處,萬望告知。

相關文章
相關標籤/搜索