次我們展示多個圖標動畫特效!上次有人在問,為什么不寫 font-family,就調用不了圖標。很簡單,你在 @font-face 中,指定 font-family 名字為 'FishC-icon';
@font-face {
font-family:'FishC-icon';
src: url('font/icons.ttf'), url('font/icons.eot'), url('font/icons.woff'), url('font/icons.svg');
}
那么在偽元素中就要告訴腳本,勞資就用'FishC-icon'里的圖標!
這次因為有多個動畫對象,所以用延遲參數形成動畫序列,先寫 5 個 div 吧
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>圖標元素2</title>
<style type="text/css">
@font-face {
font-family:'FishC-icon';
src: url('font/icons.ttf'), url('font/icons.eot'), url('font/icons.woff'), url('font/icons.svg');
}
.icon{
display: inline-block;
margin-right: 33px;
}
.android::before{
content: "\e65f";
font-size: 66px;
font-family: 'FishC-icon';
}
.app::before{
content: "\e660";
font-size: 66px;
font-family: 'FishC-icon';
}
.page::before{
content: "\e64d";
font-size: 66px;
font-family: 'FishC-icon';
}
.show::before{
content: "\e647";
font-size: 66px;
font-family: 'FishC-icon';
}
.victor::before{
content: "\e648";
font-size: 66px;
font-family: 'FishC-icon';
}
</style>
</head>
<body>
<div class="android icon">Android</div>
<div class="app icon">Apple</div>
<div class="page icon">Page</div>
<div class="show icon">Show</div>
<div class="victor icon">Victor</div>
</body>
</html>
效果圖:
此時由于沒有隱藏文字,這是上一講的點睛之筆 ,有興趣自己去找。但不同之處在于此處的圖標都設置為“inline-block”,使之能夠橫向排列?,F在修改樣式
.icon{
display: inline-block;
cursor: help;
width: 111px;
height: 111px;
font-size: 0px;
line-height: 100px;
border-radius: 50%;/*圓框*/
background:#7FE;
color: #000;
text-align: center;
animation:move 1s
}
效果圖:
例如,使圖標位置向下偏移 -100%。
然后在向上移動回到初始位置,此過程中讓圖標從完全透明化變?yōu)橥耆煌该鳌?/strong>
@keyframes move{
from{
opacity: 0;
transform: translateY(100%);
}
to{
opacity: 1;
transform: translateY(0%);
}
}
效果圖:
利用 transform 屬性的 translateY 方法來實現圖標的向下偏移。
然后使用 opacity 屬性設置圖標的透明度,0.0 (完全透明)到 1.0(完全不透明)。
由于未設置單個圖標的延遲,所以一下子 5 個同時出現。
既然提到了延遲,那就設置一下咯~
使用 animation-delay 屬性設置延遲:
.android{
animation-delay: 0s;
}
.app{
animation-delay: .3s;
}
.page{
animation-delay: .6s;
}
.show{
animation-delay: 1.2s;
}
.victor{
animation-delay: 1.5s;
}
效果圖:
光這么直棱棱也不好玩。
然后我們自己設置貝塞爾(cubic-bezier)速度曲線,達到不同速率節(jié)奏效果 ~
假設你穿越成功,會看到:
拖動粉點(起始點),藍點(終點)即可以生成坐標。
生成的結果為 cubic-bezier(.86,.15,.18,.9)。
.icon{
animation-fill-mode: both;
animation: move 2s cubic-bezier(.86,.15,.18,.9);
}
效果圖:
其中 animation-fill-mode 屬性用來屬性規(guī)定動畫在播放之前或之后,其動畫效果是否可見。。
設置完成后,防止圖標閃現。
學習HTML5開發(fā)培訓,到重慶千鋒教育,千鋒重慶HTML5開發(fā)培訓怎么樣?千鋒提供兩周免費試聽課程,歡迎你來試聽。
用圖像覆蓋圖標可以為你的網站交互細節(jié)或一組功能加深印象。本文內容將分為兩部分,第一部分創(chuàng)建結構并附加圖標的鏈接。在第二部分中,我們將使用CSS進行設計。
創(chuàng)建結構:在本節(jié)中,我們將創(chuàng)建一個基本結構,并為這些圖標附加Font-Awesome的CDN鏈接,這些圖標將用作懸停時的圖標。
“字體真棒”中的圖標的CDN鏈接:
<link rel =” stylesheet” href =““ https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css”>
HTML代碼:
<!DOCTYPE html>
<html>
<head>
<title>
Image Overlay Icon using HTML and CSS
</title>
<link rel="stylesheet" href=
"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<div class="container">
<h1>GeeksforGeeks</h1>
<b>Image Overlay Icon using HTML and CSS</b>
<div class="img">
<img src=
"https://media.geeksforgeeks.org/wp-content/uploads/20200326201748/download312.png"
alt="Geeksforgeeks">
<div class="overlay">
<a href="#" class="icon">
<i class="fa fa-user"></i>
</a>
</div>
</div>
</div>
</body>
</html>
設計結構:在上面內容中,我們創(chuàng)建了將用作圖像疊加圖標的基本網站的結構。在這部分內容中,我們將設計圖像疊加圖標的結構。
CSS代碼:
<style>
body {
text-align: center;
}
h1 {
color: green;
}
/* Image styling */
img {
padding: 5px;
height: 225px;
width: 225px;
border: 2px solid gray;
box-shadow: 2px 4px #888888;
}
/* Overlay styling */
.overlay {
position: absolute;
top: 23.5%;
left: 32.8%;
transition: .3s ease;
background-color: gray;
width: 225px;
height: 225px;
opacity: 0;
}
/* Overlay hover */
.container:hover .overlay {
opacity: 1;
}
/* Icon styling */
.icon {
color: white;
font-size: 92px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
</style>
最終解決方案:這是結合以上兩部分內容后的最終代碼。它將顯示圖像疊加圖標。
<!DOCTYPE html>
<html>
<head>
<title>
Image Overlay Icon using HTML and CSS
</title>
<link rel="stylesheet" href=
"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
body {
text-align: center;
}
h1 {
color: green;
}
/* Image styling */
img {
padding: 5px;
height: 225px;
width: 225px;
border: 2px solid gray;
box-shadow: 2px 4px #888888;
}
/* Overlay styling */
.overlay {
position: absolute;
top: 23.5%;
left: 32.8%;
transition: .3s ease;
background-color: gray;
width: 225px;
height: 225px;
opacity: 0;
}
/* Overlay hover */
.container:hover .overlay {
opacity: 1;
}
/* Icon styling */
.icon {
color: white;
font-size: 92px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<h1>GeeksforGeeks</h1>
<b>Image Overlay Icon using HTML and CSS</b>
<div class="img">
<img src=
"https://media.geeksforgeeks.org/wp-content/uploads/20200326201748/download312.png"
alt="Geeksforgeeks">
<div class="overlay">
<a href="#" class="icon">
<i class="fa fa-user"></i>
</a>
</div>
</div>
</div>
</body>
</html>
最終輸出效果:
最后送福利了,自己是從事了五年的前端工程師,整理了一份最全面前端學習資料,只要私信:“前端"等3秒后即可獲取地址,
里面概括應用網站開發(fā),css,html,JavaScript,jQuery,Ajax,node,angular等。等多個知識點高級進階干貨的相關視頻資料,等你來拿
SS是Web開發(fā)中不可或缺的一部分,隨著Web技術的不斷革新,CSS也變得更加強大。CSS的眾多屬性你知道了多少?具體開發(fā)中該使用什么屬性才最適合恰當?如今的一些CSS屬性可以讓我們節(jié)約更多的時間。比如在Web布局中,現代CSS特性就可以更好的幫助我們快速實現如等高布局,水平垂直居中,經典的圣杯布局、寬高比例、頁腳保持在底部等效果。淘系前端技術專家大漠將詳細介紹一些不同的CSS屬性來實現這些效果,希望對同學們有所幫助。
一 水平垂直居中
如何實現水平垂直居中可以說是CSS面試題中的經典面試題,在多年前這個面試題給很多同學都帶來了困惑,但Flexbxo布局模塊和CSS Grid布局模塊的到來,可以說實現水平垂直居中已是非常的容易。
Flexbox中實現水平垂直居中
在Flexbox布局模塊中,不管是單行還是多行,要讓它們在容器中水平垂直居中都是件易事,而且方法也有多種。最常見的是在Flex容器上設置對齊方式,在Flex項目上設置 margin:auto。
先來看在Flex容器上設置對齊方式。
Flex容器和Flex項目上設置對齊方式
你可能已經知道在Flex容器上設置 justify-content、align-items 的值為 center 時,可以讓元素在Flex容器中達到水平垂直居中的效果。來看一個示例:
<!-- HTML -->
<div class="flex__container">
<div class="flex__item"></div>
</div>
/* CSS */
.flex__container {
display: flex;
justify-content: center;
align-items: center;
}
效果如下:
這種方式特別適應于讓Icon圖標在容器中水平垂直居中,不同的是在Icon圖標容器上顯示設置display: inline-flex。比如下面這個示例:
<!-- HTML -->
<div class="flex__container">
<svg> </svg>
</div>
/* CSS */
.flex__container {
display: inline-flex;
align-items: center;
justify-content: center;
}
效果如下:
在這種模式之下,如果要讓多個元素實現水平垂直居中的效果,那還需要加上 flex-direction: column,比如:
<!-- HTML -->
<div class="flex__container">
<div class="avatar">:)</div>
<div class="media__heading"></div>
<div class="media__content"></div>
<div class="action"></div>
</div>
/* CSS */
.flex__container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
效果如下:
在Flexbox布局中,還可以像下面這樣讓Flex項目在Flex容器中達到水平垂直居中的效果:
<!-- HTML -->
<div class="flex__container">
<div class="flex__item"></div>
</div>
/* CSS */
.flex__container {
display: flex; // 或inline-flex
justify-content: center;
}
.flex__item {
align-self: center;
}
效果如下:
如果在Flex容器中有多個Flex項目時,該方法同樣有效:
.flex__container {
display: flex; // 或inline-flex
justify-content: center;
}
.flex__container > * {
align-self: center;
}
比如下面這個效果:
除此之外,還可以使用 place-content: center 讓Flex項目實現水平垂直居中:
.flex__container {
display: flex;
place-content: center;
}
.flex__item {
align-self: center;
}
效果如下:
或者換:
.flex__container {
display: flex;
place-content: center;
place-items: center;
}
效果如下:
這兩種方式同樣適用于Flex容器中有多個Flex項目的情景:
.flex__container {
display: flex;
flex-direction: column;
place-content: center;
}
.flex__container > * {
align-self: center;
}
// 或
.flex__container {
display: flex;
flex-direction: column;
place-content: center;
place-items: center;
}
效果如下:
可能很多同學對于 place-content 和 place-items 會感到陌生。其實 place-content 是 align-content 和 justify-content 的簡寫屬性;而 place-items 是 align-items 和 justify-items 的簡寫屬性。即:
.flex__container {
place-content: center;
place-items: center;
}
等效于:
.flex__container {
align-content: center;
justify-content: center;
align-items: center;
justify-items: center;
}
雖然擴展出來有四個屬性,但最終等效于:
.flex__container {
display: flex;
align-items: center;
justify-content: center;
}
// 多行
.flex__container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
在Flex項目上設置margin: auto
如果在Flex容器中只有一個Flex項目,還可以顯式在Flex項目中顯式設置 margin 的值為auto,這樣也可以讓Flex項目在Flex容器中水平垂直居中。例如:
.flex__container {
display: flex; // 或 inline-flex
}
.flex__item {
margin: auto;
}
效果如下:
整個過程,你可以通過下面這個示例來體驗。嘗試著選中不同方向的 margin 值:
Grid中實現水平垂直居中
CSS Grid布局可以說是現代Web布局中的銀彈。它也是到目前為止布局系統中唯一一個二維布局系統。
在CSS Grid布局中,只需要僅僅的幾行代碼也可以快速的幫助我們實現水平垂直居中的效果。比如下面這個示例:
<!-- HTML -->
<div class="grid__container">
<div class="grid__item"></div>
</div>
/* CSS */
.grid {
display: grid; // 或 inline-grid
place-items: center
}
效果如下:
在CSS Grid布局模塊中,只要顯式設置了 display: grid(或 inline-grid)就會創(chuàng)建Grid容器和Grid項目,也會自動生成網格線,即行和列(默認為一行一列)。
在沒有顯式地在Grid容器上設置 grid-template-columns 和 grid-template-rows,瀏覽器會將Grid容器默認設置為Grid內容大小:
這種方法也適用于CSS Grid容器中有多個子元素(Grid項目),比如:
<!-- HTML -->
<div class="grid__container">
<div class="avatar">:)</div>
<div class="media__heading"></div>
<div class="media__content"></div>
<div class="action"></div>
</div>
這個時候你看到的效果如下:
而且 palce-items 適用于每個單元格。這意味著它將居中單元格的內容。比如下面這個示例:
<!-- HTML -->
<div class="grid__container">
<div class="grid__item">
<h3>Special title treatment</h3>
<p>With supporting text below as a natural lead-in to additional content.</p>
<div class="action">Go somewhere</div>
</div>
</div>
/* CSS */
.grid__container {
display: grid;
place-items: center;
grid-template-columns: repeat(2, 1fr);
gap: 2vh;
}
.grid__item {
display: grid;
place-items: center;
}
效果如下:
二 等高布局
等高布局也是Web中非常常見的一種布局方式,而且實現等高布局的方案也有很多種。這里我們主要來看Flexbox布局模塊和Grid布局模塊給我們帶來了什么樣的變化。
在Flexbox和Grid布局模塊中,讓我們實現等高布局已經是非常的簡單了,比如:
<!-- Flexbox -->
<flex__container>
<flex__item></flex__item>
<flex__item></flex__item>
<flex__item></flex__item>
</flex__container>
/* CSS */
.flex__container {
display: flex; // 或 inline-flex
}
簡單地說,在容器上顯式設置了 display 的值為 flex 或 inline-flex,該容器的所有子元素的高度都相等,因為容器的 align-items 的默認值為 stretch。
這個時候你看到的效果如下:
這種方式特別適用于卡片組件中:
在Grid布局模塊中類似:
<!-- HTML -->
<grid__container>
<grid__item></grid__item>
<grid__item></grid__item>
<grid__item></grid__item>
</grid__container>
/* CSS */
.grid__container {
display: grid;
grid-template-columns: 20vw 1fr 20vw; /* 根據需求調整值*/
}
效果如下:
同樣在一些卡片類布局中運用:
如果需求有所調整,比如在Flex項目 或 Grid項目的子元素高度和容器高度相同。
<!-- HTML -->
<flex__container>
<flex__item>
<content></content>
</flex__item>
</flex__container>
/* CSS */
.flex__container {
display: flex;
}
.content {
height: 100%
}
// 或
.grid__container {
display: grid;
grid-auto-flow: column;
}
.content {
height: 100%;
}
效果如下:
三 Sticky Footer
首先用下圖來描述什么是Sticky Footer布局效果:
Sticky Footer實現方案和等高、垂直居中一樣,同樣有很多種方案可以實現。
比如像下面這樣的結構:
<!-- HTML -->
<header></header>
<main></main>
<footer></footer>
先來看Flexbox布局模塊中的實現方案:
body {
display: flex;
flex-direction: column;
}
footer {
margin-top: auto;
}
可以嘗試著在 main 區(qū)域右下角向下拖動,改變主內容區(qū)域的高度,你會發(fā)現“當內容不足一屏時,<footer> 會在頁面的最底部,當內容超出一屏時,<footer> 會自動往后延后”。
在Flexbox布局中,還可以在 <main> 區(qū)域上設置下面的樣式,達到相等的效果:
body {
display: flex;
flex-direction: column;
}
main {
flex: 1 0 auto;
}
效果如下:
<main> 中的 flex: 1 0 auto 相當于是:
main {
flex-grow: 1; /*容器有剩余空間時,main區(qū)域會擴展*/
flex-shrink: 0; /*容器有不足空間時,main區(qū)域不會收縮*/
flex-basis: auto; /*main區(qū)域高度的基準值為main內容自動高度*/
}
如果你想省事的話,可以在 main 上顯式設置 flex-grow:1,因為 flex-shrink 和 flex-basis 的默認值為 1 和 auto。
在CSS Grid布局中我們可以借助 1fr 讓 <main> 區(qū)域根據Grid容器剩余空間來做計算。
.grid__container {
display: grid;
grid-template-rows: auto 1fr auto;
}
效果如下:
四 均分列
在Web布局中,很多時候會對列做均分布局,最為常見的就是在移動端的底部Bar,比如下圖這樣的一個效果:
在Flexbox和Grid還沒出現之前,如果希望真正的做到均分效果,可以用 100%(或 100vw)除以具體的列數。比如:
<!-- HTML -->
<container>
<column></column>
<column></column>
<column></column>
</container>
/* CCSS */
.container {
inline-size: 50vw;
min-inline-size: 320px;
display: flex-row;
}
.column {
float: left;
width: calc(100% / 3);
}
效果如下:
通過瀏覽器調試器中可以發(fā)現,現個列的寬度都是相等的:
在Flexbox和Grid布局中,實現上面的效果會變得更容易地多。先來看Flexbox中的布局:
<!-- HTML -->
<flex__container>
<flex__item></flex__item>
<flex__item></flex__item>
<flex__item></flex__item>
</flex__container>
/* CSS */
.flex__container {
inline-size: 50vw;
display: flex;
}
.flex__item {
flex: 1;
}
效果如下:
在Flexbox布局模塊中,當flex取的值是一個單值(無單位的數),比如示例中的 flex:1,它會當作顯式的設置了 flex-grow: 1。瀏覽器計算出來的 flex:
接下來看Grid中如何實現上例的效果:
<!-- HTML -->
<grid__container>
<grid__item></grid__item>
<grid__item></grid__item>
<grid__item></grid__item>
</grid__container>
/* CSS */
.grid__container {
display: grid;
grid-template-columns: repeat(3, 1fr); /*這里的3表示具體的列數*/
}
最終的效果是相同的:
這樣的布局方式也適用于其他的布局中。但不管是Flexbox還是Grid布局中,都存在一定的缺陷,當容器沒有足夠的空間容納Flex項目(或Grid項目)時,Flex項目或Grid項目會溢出(或隱藏,如果Flex容器或Grid容器顯式設置了 overflow:hidden):
修復這種現象最簡單的方式是在Flex容器或Grid容器顯式設置一個 min-width(或 min-inline-size):
.flex__container {
min-inline-size: 300px;
}
不過話又說回來,比如我們的Flex項目(或Grid項目)是一個卡片,每張卡片寬度是相等之外,更希望容器沒有足夠空間時,Flex項目(或Grid項目)會自動斷行排列。
我們繼續(xù)通過示例向大家展示。先來看Flexbox實現方案:
.flex__container {
display: flex;
flex-wrap: wrap;
}
.flex__item {
flex: 0 1 calc((100vw - 18vh) / 4); /* calc(100vw -18vh) / 4 是flex-basis的基準值 */
}
你可以嘗試著調整瀏覽器的視窗寬度,當瀏覽器的視窗越來越小時,Flex容器寬度也就會越來越小,當Flex容器小到沒有足夠的空間容納四個Flex項目(就此例而言),那么Flex項目就會斷行排列:
基于該例,如果把Flex項目的 flex 值改成:
.flex__item {
flex: 0 0 400px;
}
這個時候,當Flex容器沒有足夠空間時,Flex項目會按 flex-basis: 400px 計算其寬度,Flex容器沒有足夠空間時,Flex就會斷行:
反過來,如果Flex項目的值 flex 改成:
.flex__item {
flex: 1 0 400px;
}
當Flex容器沒有足夠空間排列Flex項目時,Flex項目會按 flex-basis: 400px 計算其寬度,Flex會斷行,并且同一行出現剩余空間時,Flex項目會擴展,占滿整個Flex容器:
在Grid中實現類似的效果要更復雜一點??梢允褂?repeat() 函數,1fr 以及 auto-fit 等特性:
.grid__container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2vh;
}
效果如下:
如果你對這方面知識感興趣的話,還可以移步閱讀《Container Query Solutions with CSS Grid and Flexbox》一文。
其實在Grid中與 auto-fit 對比的值還有一個叫 auto-fill。但兩者的差異是非常地大,用下圖來描述 auto-fit 和 auto-fill 的差異:
另外這種方式也是到目前為止一種不需要借助CSS媒體查詢就可以實現響應式布局效果。
五 圣杯布局
圣杯布局(Holy Grail Layout))是Web中典型的布局模式。看上去像下圖這樣:
對于圣杯布局而言,HTML結構是有一定的要求,那就是內容為先:
<!-- HTML -->
<header></header>
<main>
<article></article> <!-- 主內容 -->
<nav></nav>
<aside></aside>
</main>
<footer></footer>
在這里主要還是和大家一起探討,如何使用Flexbox和Grid布局模塊來實現圣杯布局。先來看Flexbox實現方案:
body {
width: 100vw;
display: flex;
flex-direction: column;
}
main {
flex: 1;
min-height: 0;
display: flex;
align-items: stretch;
width: 100%;
}
footer {
margin-top: auto;
}
nav {
width: 220px;
order: -1;
}
article {
flex: 1;
}
aside {
width: 220px;
}
效果如下:
通過在 nav、aside 和 article 上顯式設置 order 的值,可以很好的控制這三個區(qū)域的布局順序。比如說,希望 <aside> 在 <article> 之前排列,只需要在上面的示例基礎上做一點點調整:
nav {
order: 0;
}
aside {
order: -1;
}
效果如下:
注意,order的默認值為0,值越大越排在后面!
在上例的基礎上,借助CSS媒體對象的特性,可以很容易實現響應式的圣杯布局效果:
@media screen and (max-width: 800px) {
main {
flex-direction: column;
}
nav, aside {
width: 100%;
}
}
效果如下:
嘗試著拖動瀏覽器來改變視窗大小,你可以看到如下圖的效果:
在Grid布局模塊中,實現圣杯布局要比Flexbox布局模塊中更容易,而且更靈活。在CSS Grid布局模塊中,HTML結構可以更簡潔:
<!-- HTML -->
<body>
<header></header>
<main></main>
<nav></nav>
<aside></aside>
<footer></footer>
</body>
在CSS方面有很多種方案可以實現圣杯布局效果。我們先來看第一種:
body {
display: grid;
grid-template: auto 1fr auto / 220px 1fr 220px;
}
header {
grid-column: 1 / 4;
}
main {
grid-column: 2 / 3;
grid-row: 2 / 3;
}
nav {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
aside {
grid-column: 3 / 4;
grid-row: 2 / 3;
}
footer {
grid-column: 1 / 4;
}
效果如下:
上面示例采用的是網格線來給每個區(qū)域進行定位的:
和Flexbox布局類似,在媒體查詢中可以改變每個網格區(qū)域的位置:
@media screen and (max-width: 800px) {
body {
grid-template-rows: auto;
grid-template-columns: auto;
}
header,
main,
nav,
aside,
footer {
grid-column: 1 / 2;
min-height: auto;
}
main {
grid-row: 3 / 4;
margin: 0;
}
nav {
grid-row: 2 / 3;
}
aside {
grid-row: 4 / 5;
}
footer {
grid-row: 5 / 6;
}
}
除了 grid-template(即 grid-template-columns 和 grid-template-rows)之外,在Grid布局中還可以使用 grid-area 和 grid-template-areas 屬性的結合,也能很方便的實現CSS圣杯布局?;谏厦娴氖纠?,只需要把你的CSS調整為:
body {
display: grid;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
}
header {
grid-area: header;
}
main {
grid-area: main;
}
nav {
grid-area: nav;
}
aside {
grid-area: aside;
}
footer {
grid-area: footer;
}
@media screen and (max-width: 800px) {
body {
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
}
}
效果如下:
你可能發(fā)現了它們之間的差異性:
后面這個示例中,<nav>、<main> 和 <aside> 區(qū)域寬度相等。這是因為我們示例中通過 grid-template-areas 來聲明網格,在使用 grid-template-areas 創(chuàng)建網格時,其實也隱式的創(chuàng)建了網格線,只不過他和 grid-template 不同的是 grid-template 可以顯式的指定網格軌道大小,而grid-template-areas 在該示例中相當于網格軌道大小都是 1fr。
如果我們希望 <main> 的區(qū)域變得更大,那么可以在 grid-template-areas 上做個調整:
body {
display: grid;
grid-template-areas:
"header header header header header"
"nav main main main aside"
"footer footer footer footer footer";
}
效果如下:
這個時候網格區(qū)域的劃分像下圖這樣:
雖然在效果有所調整了,但還是均分狀態(tài)。更好的解決方案是,將 grid-template-areas 和 grid-template 結合起來使用:
body {
display: grid;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
grid-template-columns: 220px 1fr 220px;
grid-template-rows: auto 1fr auto;
}
header {
grid-area: header;
}
main {
grid-area: main;
}
nav {
grid-area: nav;
}
aside {
grid-area: aside;
}
footer {
grid-area: footer;
}
@media screen and (max-width: 800px) {
body {
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
grid-template-columns: 1fr;
grid-template-rows: auto auto 1fr auto auto;
}
main {
margin-left: 0;
margin-right: 0;
}
}
效果如下:
你可以發(fā)現,這個時候,網格線的區(qū)域的命名像下圖這樣:
六 12列網格布局
12列網格布局最早是由960.gs提出的網格布局系統:
12列網格布局在設計系統和CSS Framework中經常使用,比如業(yè)內經典的Bootstrap就采用了12列網格布局系統:
在社區(qū)中也有很多在線工具,幫助我們快速構建12列網格系統,比如 Free CSS Grid Tools & Resources For Developers 一文中羅列的工具。
不過這里主要是想和大家一起看看在Flexbox和Grid布局模塊中是如何實現12列的網格布局系統。
先來看Flexbox布局模塊。12列網格布局的HTMl結構一般類似于下面這樣:
<!-- HTML -->
<flex__grid>
<flex__row>
<flex__item col4></flex__item col4>
<flex__item col4></flex__item col4>
<flex__item col4></flex__item col4>
</flex__row>
</flex__grid>
注意,12列網格中,一般同一行的列數值和剛好等于12。比如上面的HTML結構,行中有三列,每列的寬度剛好四個網格寬度加兩個列間距。并且在計算的時候有一套成熟的計算公式:
而且還設計上也會有所差異,比如說距離容器兩側有沒有間距等:
這些的差異對于計算公式和樣式代碼的設計都略有差異。我們用其中一個為例:
:root {
--gutter: 10px;
--columns: 12;
--span: 1;
}
.flex__container {
display: flex;
flex-direction: column;
padding-left: var(--gutter);
padding-right: var(--gutter);
}
.flex__row {
display: flex;
margin-left: calc(var(--gutter) * -1);
margin-right: calc(var(--gutter) * -1);
}
.flex__row + .flex__row {
margin-top: 2vh;
}
.flex__item {
flex: 1 1
calc((100% / var(--columns) - var(--gutter)) * var(--span));
margin: 0 var(--gutter);
}
.flex__item1 {
--span: 1;
}
.flex__item2 {
--span: 2;
}
.flex__item3 {
--span: 3;
}
.flex__item4 {
--span: 4;
}
.flex__item5 {
--span: 5;
}
.flex__item6 {
--span: 6;
}
.flex__item7 {
--span: 7;
}
.flex__item8 {
--span: 8;
}
.flex__item9 {
--span: 9;
}
.flex__item10 {
--span: 10;
}
.flex__item11 {
--span: 11;
}
.flex__item12 {
--span: 12;
}
你會看到的效果如下:
在該示例中采用了CSS自定義屬性相關的特性,讓整個計算變得更容易一些。
對于使用CSS Grid布局模塊來實現12列網格布局,相對而言,不管是HTML結構還是CSS代碼都會更簡易一些。在使用CSS Grid布局模塊實現12列網格布局,將會運用到repeat()、minmax()、gap 和 fr 等特性。具體的來看一個示例吧。
<!-- HTML -->
<grid__container>
<grid__item></grid__item>
</grid__container>
我們來看CSS代碼:
具體的代碼如下:
:root {
--columns: 12;
--gap: 10px;
--span: 1;
}
.grid__container {
display: grid;
grid-template-columns: repeat(var(--columns), 1fr);
grid-template-rows: 1fr;
gap: var(--gap);
padding-left: calc(var(--gap) / 2);
padding-right: calc(var(--gap) / 2);
}
.grid__item {
min-block-size: 10vh;
grid-column: span var(--span);
}
.col1 {
--span: 1;
}
.col2 {
--span: 2;
}
.col3 {
--span: 3;
}
.col4 {
--span: 4;
}
.col5 {
--span: 5;
}
.col6 {
--span: 6;
}
.col7 {
--span: 7;
}
.col8 {
--span: 8;
}
.col9 {
--span: 9;
}
.col10 {
--span: 10;
}
.col11 {
--span: 11;
}
.col12 {
--span: 12;
}
你將看到的效果如下:
就該示例而言,grid-template-columns: repeat(12, 1fr) 創(chuàng)建網格如下圖所示:
除了上述這種粗暴的方式,還可以更靈活一些,將 auto-fit、minmax() 以及 grid-auto-flow: dense 等來創(chuàng)建:
.grid__container {
padding: 1em;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(60px, 1fr));
gap: 1em;
grid-auto-flow: dense;
}
對于 .grid__item 可以通過 grid-column、grid-row 來控制網格項目的位置:
加上 grid-auto-flow: dense 會根據Grid容器空間,Grid項目會自動流到合適的位置:
這種布局對于雜志類的布局非常的適用。有關于這方面更詳細的介紹可以閱讀@Keir Watson的《Responsive Grid Magazine Layout in Just 20 Lines of CSS》一文。
七 兩端對齊
在Web布局中時常碰到兩端對齊的需求。在Flexbox布局中,時常在Flex容器中顯式設置 justify-content 的值:
.flex__container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
width: 100%;
}
但在末尾行,如果和前面行的個數不相同(Flex項目)就會出現下圖這樣的效果:
像上圖這樣的效果,并不是我們所需要的,因為我們希望在最后一行的Flex項目不足夠排列滿一行時,希望Flex項目一個緊挨一個的排列:
在Flexbox要實現上圖這樣的效果,只需要在Flex容器中添加一個偽元素:
.flex__container::after {
content: "";
display: flex;
flex: 0 1 32vw;
}
注意,偽元素的 flex-basis 建議設置的和卡片的 flex-basis(或寬度)等同。這個時候你將看到像下面這樣的示例:
不過這種方式也不是最佳的方式,當末尾行的個數不只少一個時,就會出現下圖這樣的效果:
面對這樣的場景,我們需要給Flex容器添加額外的空標簽元素:
占位符元素數量 = 每行最大的列數 - 2
但是 gap屬性出現之后,要實現這樣的效果就不難了:
body {
padding: 1vh;
}
.flex__container {
display: flex;
flex-wrap: wrap;
gap: 2vh;
width: 100%;
}
.flex__item {
flex: 0 1 calc((100vw - 8vh) / 4);
}
效果如下:
注意,gap 運用在Flexbox中到目前為止,僅得到了Firefox瀏覽器的支持。上面的示例,使用Firefox瀏覽器,你看到的效果如下:
在CSS Grid布局中,就可以直接使用 gap:
body {
padding: 1vh;
}
.grid__container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1vh;
}
效果如下:
八 選擇最佳的值
很多時候,針對不同的場景,設計師會為我們提供不同的設計風格,比如元素大小:
隨著 clam() 函數的到來,這一切都變得容易地多。
clam() 函數接受三個參數,即 clam(MIN, VAL, MAX),其中 MIN 表示最小值,VAL 表示首選值,MAX 表示最大值。它們之間:
我們來看一個示例:
.element {
/**
* MIN = 100px
* VAL = 50vw ? 根據視窗的寬度計算
* MAX = 500px
**/
width: clamp(100px, 50vw, 500px);
}
比如瀏覽器視窗現在所處的位置是1200px的寬度,那么 .element 渲染的結果如下:
這個時候 .element 元素的 width 是 500px。此時,clamp(100px, 50vw, 500px) 相當于clamp(100px, 600px, 500px),對應的 VAL 值是 600px,大于 MAX 值,那么這個時候clamp() 函數返回的值是 MAX,即 500px,這個時候 .element 的 width 值就是 500px(即MAX 的值)。
如果我們把瀏覽器視窗縮小至 760px:
這個時候 .element 元素的 width 是 50vw。此時,clamp(100px, 50vw, 500px) 相當于clamp(100px, 380px, 500px),對應的 VAL 值是 380px,該值大于 MIN 值(100px),小于MAX 值(500px),那么這個時候 clamp() 函數返回的值是 VAL,即 50vw,這個時候.element 的 width 值就是 50vw(即 VAL 的值)。
如果繼續(xù)將瀏覽器的視窗縮小至 170px:
這個時候 .element 元素的 width 是 100px。此時,clamp(100px, 50vw, 500px) 相當于clamp(100px, 85px, 500px),對應的 VAL 值是 85px,該值小于 MIN 值(100px),那么這個時候 clamp() 函數返回的值是 MIN,即 100px,這個時候 .element 的 width 值就是100px(即 MIN 的值)。
就該示例而言,clamp(100px, 50vw, 500px) 還可以這樣來理解:
九 Logo圖標的對齊
我想你在Web開發(fā)中可能碰到過類似下圖的這樣的場景:
正像上圖所示,Logo圖像的有大有?。▽挾群透叨榷疾灰粯樱C鎸@樣的業(yè)務場景,很多時候都希望設計師能提供相同尺寸的圖像。但這樣勢必會影響Logo圖像的外觀。
前段時間看到@Ahmad Shadeed專門寫了一篇博文《Aligning Logo Images in CSS》,就是介紹如何實現上圖這樣的布局效果。
其實實現這樣的布局效果,主要運用到的就是CSS的 object-fit 屬性,而這個屬性早在多年前就得到了各大主流瀏覽器的支持。
這里我們用一個簡單的示例,來看看具體實現過程。先來看HTML結構:
<!-- HTML -->
<ul class="brands">
<li class="brands__item">
<a href="#">
<img src="img/logo.png" alt="">
</a>
</li>
<li> <!-- ... --> </li>
</ul>
居中對齊前面已經介紹過了,這里主要是看圖像大小方面的處理:
.brands {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
grid-gap: 1rem;
}
.brands__item {
background: #eee;
}
.brands__item a {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
.brands__item img {
width: 130px;
height: 75px;
object-fit: contain;
}
這樣就能實現上圖的效果。你可能發(fā)現了,有些Logo圖像帶有背景顏色,如果讓效果更好一些,可以把CSS混合模式相關的特性運用進來:
.brands__item img {
width: 130px;
height: 75px;
object-fit: contain;
mix-blend-mode: multiply;
}
這個時候,你看到的效果如下:
object-fit 除了取值 contain 之外,還有其他幾個值:
其實這個方案也適用于產品圖片,人物頭像等布局。
小結
文章中主要介紹了Web中一些布局的實現思路和具體方案。其實文章提到的效果,比如水平垂直居中、等高布局、平均分布列和Sticky Footer等,在CSS中一直有多種解決方案,只不過隨著CSS Flexbox布局模塊和CSS Grid布局模塊的到來,實現這些效果變得更為靈活和簡潔。
當然,文章中提到的只是一些最為常見的一些效果,其實在Web布局中,特別是Flexbox布局和Grid布局中還存在著很多有意思的東西,只不過因為篇幅的原因沒有一一羅列。如果你感興趣可以再挖掘一些出來,如果你在這方面有更好的經驗或方案,歡迎在下面的評論中分享。最后希望這篇文章對你平時的工作有所幫助。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。