0
本例參考了網(wǎng)上的例子,唯一不一樣的是,我這里的操作是一步一步講解,網(wǎng)上僅是源碼。
一、我們先創(chuàng)建一張空白的網(wǎng)頁,網(wǎng)頁要自適應(yīng)手機(jī)。
圖1
二、我們?cè)賱?chuàng)建網(wǎng)頁的頭部。
圖2
圖3
三、做出來的網(wǎng)頁頭部太丑了,我們要去掉盒子與瀏覽器的間隙,還有給頭部加內(nèi)部距離。
圖4
圖5
四、給網(wǎng)頁頭部添加一些內(nèi)容。
圖6
圖7
五、接下來開始做導(dǎo)航條了。
圖8
圖9
六、發(fā)現(xiàn)沒,導(dǎo)航條居然看不見,沒有東西在里面自然是看不見的,我們加三個(gè)鏈接吧。
圖10
圖11
七、這回是看見了,不過樣式太丑,我們改改樣式。
圖12
圖13
八、加上內(nèi)部距離,就好看了許多,即然是鏈接,我們加點(diǎn)動(dòng)態(tài)吧,當(dāng)鼠標(biāo)在鏈接上面時(shí),鏈接塊變色。
圖14
圖15
九、開始做網(wǎng)頁內(nèi)容,網(wǎng)頁內(nèi)容我分為三塊,左右兩邊是側(cè)欄,中間是主要內(nèi)容。
圖16
圖17
十、我想讓它橫著排,它卻是豎著排,改改各個(gè)塊的樣式。
圖18
圖19
十一、給主體的各個(gè)塊加點(diǎn)內(nèi)容。
圖20
圖21
十二、內(nèi)容是有了,但你會(huì)發(fā)現(xiàn)各塊之間沒有間隙,貼得太近了,我們改一下樣式,加個(gè)內(nèi)部距離。
圖22
圖23
十三、距離是有了,但有一個(gè)側(cè)欄跑到了另一行,怎么回事?原來padding是會(huì)改變盒子的整體寬度,我們?cè)臼?00%,現(xiàn)在多了padding的寬度,自然就換行了,解決一下吧。
圖24
圖25
十四、這回終于在一行了,接下來可以做網(wǎng)頁底部了。
圖26
圖27
十五、改改樣式,讓底部好看一點(diǎn)。
圖28
圖29
十六,這個(gè)時(shí)候,網(wǎng)頁的整體版面就完成了,再補(bǔ)充一個(gè)小內(nèi)容,讓網(wǎng)頁瀏覽器在小于600像素寬的時(shí)候,主體內(nèi)容的三個(gè)塊由橫變豎。
圖30
圖31
前在項(xiàng)目的過程中遇到了一個(gè)問題,某個(gè) div 希望始終顯示在最上面,而在之后的元素都顯示在它之下,當(dāng)時(shí)設(shè)置了 z-index 也沒有效果,不知道什么原因,因此找了一下 CSS 相關(guān)資料,解決了這個(gè)問題的同時(shí),也學(xué)習(xí)了很多知識(shí),特此和大家分享一下。
屏幕是一個(gè)二維平面,然而 HTML 元素卻是排列在三維坐標(biāo)系中, x 為水平方向, y 為垂直方向, z為屏幕由內(nèi)向外方向,我們?cè)诳雌聊坏臅r(shí)候是沿著 z 軸方向從外向內(nèi)的。由此,元素在用戶視角就形成了層疊的關(guān)系,某個(gè)元素可能覆蓋了其他元素也可能被其他元素覆蓋;
這里有幾個(gè)重要的概念:層疊上下文 (堆疊上下文, Stacking Context)、層疊等級(jí) (層疊水平, Stacking Level)、層疊順序 (層疊次序, 堆疊順序, Stacking Order)、z-index、BFC(塊級(jí)格式化上下文,Block Formatting Context),這些概念共同決定了你看到元素的位置,下面我們就圍繞著這幾個(gè)概念來一起學(xué)習(xí)一下。
聲明:
1. 層疊上下文 (Stacking Context)
層疊上下文 (堆疊上下文, Stacking Context),是 HTML 中一個(gè)三維的概念。在 CSS2.1 規(guī)范中,每個(gè)元素的位置是三維的,當(dāng)元素發(fā)生層疊,這時(shí)它可能覆蓋了其他元素或者被其他元素覆蓋;排在 z 軸越靠上的位置,距離屏幕觀察者越近。
文章 <關(guān)于z-index 那些你不知道的事> 有一個(gè)很好的比喻,這里引用一下;
可以想象一張桌子,上面有一堆物品,這張桌子就代表著一個(gè)層疊上下文。如果在第一張桌子旁還有第二張桌子,那第二張桌子就代表著另一個(gè)層疊上下文。現(xiàn)在想象在第一張桌子上有四個(gè)小方塊,他們都直接放在桌子上。在這四個(gè)小方塊之上有一片玻璃,而在玻璃片上有一盤水果。這些方塊、玻璃片、水果盤,各自都代表著層疊上下文中一個(gè)不同的層疊層,而這個(gè)層疊上下文就是桌子。
每一個(gè)網(wǎng)頁都像一個(gè)房間,這個(gè)房間就是 <html></html>,其他層疊上下文就像這個(gè)房間里的桌子,HTML 標(biāo)簽中的一切都被置于這個(gè)房間中。
當(dāng)給一個(gè)元素的 position 值賦為 fixed 或 sticky 值時(shí),你就創(chuàng)建了一個(gè)新的層疊上下文,其中有著獨(dú)立于頁面上其他層疊上下文和層疊層的層疊層,這就相當(dāng)于你把另一張桌子帶到了房間里。
層疊上下文 1 (Stacking Context 1)是由文檔根元素形成的, 層疊上下文 2 和 3 (Stacking Context 2, 3) 都是層疊上下文 1 (Stacking Context 1) 上的層疊層。他們各自也都形成了新的層疊上下文,其中包含著新的層疊上下文。
在層疊上下文中,其子元素按照上面解釋的規(guī)則進(jìn)行層疊。形成層疊上下文的方法有:
總結(jié):
2. 層疊等級(jí) (Stacking Level)
層疊等級(jí) (層疊水平, Stacking Level) 決定了在同一個(gè)層疊上下文中,元素在 z 軸上的顯示的順序;
對(duì)于普通元素的層疊水平探討只局限于在當(dāng)前層疊上下文中:
層疊上下文本身是一個(gè)強(qiáng)力的「層疊結(jié)界」,普通的元素水平是無法突破這個(gè)結(jié)界和結(jié)界外的元素去較量層疊水平的。
— CSS 世界
另外,層疊等級(jí)并不一定由 z-index 決定,只有定位元素的層疊等級(jí)才由 z-index 決定,其他類型元素的層疊等級(jí)由層疊順序、他們?cè)?HTML 中出現(xiàn)的順序、他們的祖先元素的層疊等級(jí)一同決定,詳細(xì)的規(guī)則見下面層疊順序的介紹。
3. z-index
在 CSS 2.1 中, 所有的盒模型元素都處于三維坐標(biāo)系中。除了我們常用的橫坐標(biāo)和縱坐標(biāo), 盒模型元素還可以沿著「z 軸」層疊擺放,當(dāng)他們相互覆蓋時(shí),z 軸順序就變得十分重要。
-- CSS 2.1 Section 9.9.1 - Layered presentation
z-index 只適用于定位的元素,對(duì)非定位元素?zé)o效,它可以被設(shè)置為正整數(shù)、負(fù)整數(shù)、 0、 auto,如果一個(gè)定位元素沒有設(shè)置 z-index,那么默認(rèn)為 auto;
元素的 z-index 值只在同一個(gè)層疊上下文中有意義。如果父級(jí)層疊上下文的層疊等級(jí)低于另一個(gè)層疊上下文的,那么它 z-index 設(shè)的再高也沒用。所以如果你遇到 z-index 值設(shè)了很大,但是不起作用的話,就去看看它的父級(jí)層疊上下文是否被其他層疊上下文蓋住了。
4. 層疊順序 (Stacking Order)
層疊順序 (層疊次序, 堆疊順序, Stacking Order) 描述的是元素在同一個(gè)層疊上下文中的順序規(guī)則(之前的層疊上下文和層疊等級(jí)是概念),從層疊的底部開始,共有七種層疊順序:
第 7 級(jí)順序的元素會(huì)顯示在之前順序元素的上方,也就是看起來覆蓋了更低級(jí)的元素:
除層疊順序優(yōu)先級(jí)規(guī)則之外,還有一條后來居上規(guī)則:同一個(gè)層疊順序的元素按照在 HTML 里出現(xiàn)的順序依次層疊。這兩個(gè)規(guī)則共同決定瀏覽器元素在文檔中是如何層疊的。
5. 文檔流 (Document Flow)
5.1 常規(guī)流 (Normal flow)
5.2 浮動(dòng) (Floats)
5.3 絕對(duì)定位 (Absolute positioning)
6. BFC (Block Formatting Context)
6.1 什么是 BFC
BFC (Block Formatting Context) 塊級(jí)格式化上下文,是用于布局塊級(jí)盒子的一塊渲染區(qū)域,相對(duì)應(yīng)的還有 IFC(Inline Formatting Context)內(nèi)聯(lián)格式化上下文,不是本文重點(diǎn),讀者可以自行查閱相關(guān)知識(shí)。
BFC 是 Web 頁面 CSS 視覺渲染的一部分,用于決定塊盒子的布局及浮動(dòng)相互影響范圍的一個(gè)區(qū)域。
— MDN - 塊格式化上下文
一個(gè) BFC 的范圍包含創(chuàng)建該上下文元素的所有子元素,但不包括創(chuàng)建了新 BFC 的子元素的內(nèi)部元素。這從另一方角度說明,一個(gè)元素不能同時(shí)存在于兩個(gè) BFC 中。因?yàn)槿绻粋€(gè)元素能夠同時(shí)處于兩個(gè) BFC 中,那么就意味著這個(gè)元素能與兩個(gè) BFC 中的元素發(fā)生作用,就違反了 BFC 的隔離作用。
觸發(fā) BFC 的方式有:
注意: display:table 也可以生成 BFC 的原因在于 Table 會(huì)默認(rèn)生成一個(gè)匿名的 table-cell,是這個(gè)匿名的 table-cell 生成了 BFC。
6.2 用法
1. 阻止相鄰元素的 margin 合并
屬于同一個(gè) BFC 的兩個(gè)相鄰塊級(jí)子元素的上下 margin 會(huì)發(fā)生重疊,(設(shè)置 writing-mode:tb-rl時(shí),水平 margin 會(huì)發(fā)生重疊)。所以當(dāng)兩個(gè)相鄰塊級(jí)子元素分屬于不同的 BFC 時(shí)可以阻止 margin 重疊。可以給任一個(gè)相鄰塊級(jí)盒子的外面包一個(gè) div,通過改變此 div 的屬性使兩個(gè)原盒子分屬于兩個(gè)不同的 BFC,以此來阻止 margin 重疊。
代碼和預(yù)覽參見:Codepen - 使用BFC阻止margin合并:https://codepen.io/SHERlocked93/pen/eVOevN
2. 阻止元素被浮動(dòng)元素覆蓋
一個(gè)正常文檔流的塊級(jí)元素可能被一個(gè) float 元素覆蓋,擠占正常文檔流,因此可以設(shè)置一個(gè)元素的 float、 display、 position 值等方式觸發(fā) BFC,以阻止被浮動(dòng)盒子覆蓋。
代碼和預(yù)覽參見:Codepen - 使用BFC阻止元素被浮動(dòng)元素覆蓋:https://codepen.io/SHERlocked93/pen/pazdzB
3. 包含浮動(dòng)元素
通過改變包含浮動(dòng)子元素的父盒子的屬性值,觸發(fā) BFC,以此來包含子元素的浮動(dòng)盒子。
代碼和預(yù)覽參見:Codepen - 使用BFC包含浮動(dòng)元素:https://codepen.io/SHERlocked93/pen/OQLOqG
7. 實(shí)戰(zhàn)
下面一起來看幾個(gè)例子實(shí)戰(zhàn)一下,幫助理解。
7.1 普通情況
三個(gè) relative 定位的 div 塊中各有 absolute 的不同顏色的 span.red、 span.green、 span.blue,它們都設(shè)置了 position:absolute;
代碼和預(yù)覽參見:Codepen - 普通情況:https://codepen.io/SHERlocked93/pen/aaPord
那么當(dāng)沒有元素包含 z-index 屬性時(shí),這個(gè)例子中的元素按照如下順序?qū)盈B(從底到頂順序):
紅綠藍(lán)都屬于 z-index 為 auto 的定位元素,因此按照 7 層層疊順序規(guī)則來說同屬于層疊順序第 6 級(jí),所以按 HTML 中的出現(xiàn)順序?qū)盈B:紅->綠->藍(lán)
7.2 在相同層疊上下文的父元素內(nèi)的情況
紅綠位于一個(gè) div.first-box 下,藍(lán)位于 div.second-box 下,紅綠藍(lán)都設(shè)置了 position:absolute, first-box 與 second-box 都設(shè)置了 position:relative;
代碼和預(yù)覽參見:Codepen - 父元素不同但都位于根元素下:https://codepen.io/SHERlocked93/pen/RYENBw
這個(gè)例子中,紅藍(lán)綠元素的父元素 first-box 與 second-box 都沒有生成新的層疊上下文,都屬于根層疊上下文中的元素,且都是層疊順序第 6 級(jí),所以按 HTML 中的出現(xiàn)順序?qū)盈B:紅->綠->藍(lán)
7.3 給子元素增加 z-index
紅綠位于一個(gè) div.first-box 下,藍(lán)黃位于 div.second-box 下,紅綠藍(lán)都設(shè)置了 position:absolute,如果這時(shí)給綠加一個(gè)屬性 z-index:1,那么此時(shí) .green 位于最上面;
如果再在 .second-box 下 .green 后加一個(gè)絕對(duì)定位的 span.gold,設(shè)置 z-index:-1,那么它將位于紅綠藍(lán)的下面;
代碼和預(yù)覽參見:Codepen - 設(shè)置了z-index:https://codepen.io/SHERlocked93/pen/gdZOrK
這個(gè)例子中,紅藍(lán)綠黃元素的父元素中都沒有生成新的層疊上下文,都屬于根層疊上下文中的元素
所以這個(gè)例子中的從底到高顯示的順序就是:黃->紅->藍(lán)->綠
7.4 在不同層疊上下文的父元素內(nèi)的情況
紅綠位于一個(gè) div.first-box 下,藍(lán)位于 div.second-box 下,紅綠藍(lán)都設(shè)置了 position:absolute,如果 first-box 的 z-index 設(shè)置的比 second-box 的大,那么此時(shí)無論藍(lán)的 z-index 設(shè)置的多大 z-index:999,藍(lán)都位于紅綠的下面;如果我們只更改紅綠的 z-index 值,由于這兩個(gè)元素都在父元素 first-box 產(chǎn)生的層疊上下文中,此時(shí)誰的 z-index 值大,誰在上面;
代碼和預(yù)覽參見:Codepen - 不同層疊上下文的父元素:https://codepen.io/SHERlocked93/pen/gdZbOJ
這個(gè)例子中,紅綠藍(lán)都屬于設(shè)置了 z-index 的定位元素,不過他們的父元素創(chuàng)建了新的層疊上下文;
所以這個(gè)例子中從低到到顯示的順序:藍(lán)->紅->綠
(我遇到的的情況就屬于這個(gè)例子類似情形)
7.5 給子元素設(shè)置 opacity
紅綠位于 div.first-box 下,藍(lán)位于 div.second-box 下,紅綠藍(lán)都設(shè)置了 position:absolute,綠設(shè)置了 z-index:1,那么此時(shí)綠位于紅藍(lán)的最上面;
如果此時(shí)給 first-box 設(shè)置 opacity:.99,這時(shí)無論紅綠的 z-index 設(shè)置的多大 z-index:999,藍(lán)都位于紅綠的上面;
如果再在 .second-box 下 .green 后加一個(gè) span.gold,設(shè)置 z-index:-1,那么它將位于紅綠藍(lán)的下面;
代碼和預(yù)覽參見:Codepen - opacity的影響:https://codepen.io/SHERlocked93/pen/GXPRWB
之前已經(jīng)介紹了,設(shè)置 opacity 也可以形成層疊上下文,因此:
所以這個(gè)例子中從低到到顯示的順序:黃->紅->綠->藍(lán)
關(guān)注微信公眾號(hào):安徽思恒信息科技有限公司,了解更多技術(shù)內(nèi)容……
天寫前端的你,會(huì)自己寫一個(gè)輪播圖嗎,而且不能用js哦,知道輪播圖的原理嗎?
今天我們要講的是如何只用css實(shí)現(xiàn)輪播圖效果,也叫"banner",就是我們經(jīng)常在APP或網(wǎng)站首頁頂部看到的一系列圖片切換。就像淘寶官網(wǎng)首頁那樣:
一圖勝千言,先上圖:
解釋一下,輪播圖并排排列,組成一張很寬的圖片,而手機(jī)屏幕寬度是固定的,這樣每過一段時(shí)間,我們把寬的圖向左平移一些距離,一般是平移一個(gè)屏幕寬度,比如屏幕寬320px,就平移320px,這樣就達(dá)到了切換圖片的目的。
注意點(diǎn),由于每次都平移一個(gè)手機(jī)寬度,即每張輪播圖要適應(yīng)手機(jī)的尺寸,所以UI在做圖的時(shí)候要考慮這點(diǎn),不然顯示的圖片很丑。
html代碼如下:
<div class="banner">
<div class="banner-wrapper">
<ul class="banner-list">
<li class="item" id="item1">1</li>
<li class="item" id="item2">2</li>
<li class="item" id="item3">3</li>
<li class="item" id="item4">4</li>
</ul>
</div>
</div>
CSS代碼如下:
.banner {
border: 4px solid black;
width: 300px;
height: 150px;
box-sizing: content-box;
}
.banner .banner-wrapper {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
z-index: -1;
}
.banner-list {
width: 1200px;
height: 100%;
position: absolute;
left: 0;
top: 0;
padding: 0;
margin: 0;
list-style: none;
}
.banner-list .item {
width: 300px;
height: 100%;
display: inline-block;
float: left;
font-weight: bold;
font-size: 40px;
line-height: 150px;
}
.banner-list .item#item1{
background: #fee2b3;
}
.banner-list .item#item2 {
background: #ffa299;
}
.banner-list .item#item3 {
background: #ad6989;
}
.banner-list .item#item4 {
background: #562349;
}
圖中黑色框代表屏幕中顯示的區(qū)域,超出部分不可見。html代碼沒啥好說的,一個(gè)容器,里面套需要輪播的圖片,我們看css代碼,所謂輪播,就是不停的切換顯示區(qū)域,代碼操作就是左右移動(dòng)輪播列表,這里我們用left和right屬性操作,所以就要把輪播列表的position設(shè)置成absolute,它的父節(jié)點(diǎn)的position設(shè)置成relative,即輪播列表相對(duì)于父節(jié)點(diǎn)是絕對(duì)位置,比如left: 10px,就代表列表左邊距父節(jié)點(diǎn)一定是10px,不管你父節(jié)點(diǎn)如何變化,都是這么多。水平排列,不要忘記一個(gè)重要屬性float,把float: left設(shè)置到每一個(gè)輪播項(xiàng)中,代表排列的時(shí)候做對(duì)齊。
如上圖所示,最終輪播區(qū)域是在黑色框中,而外部區(qū)域是不希望看到的,現(xiàn)在需要把它隱藏掉:
.banner .banner-wrapper {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
}
使用overflow: hidden把溢出容器的部分隱藏。
前面的準(zhǔn)備操作基本都差不多了(沒看懂的小伙伴多看幾遍,最好是動(dòng)手敲一邊),現(xiàn)在是時(shí)候讓我們的輪播圖滾動(dòng)起來了。前面也說了,所謂滾動(dòng),就是不停的平移輪播列表,這時(shí)候需要使用CSS幀動(dòng)畫(keyframes) 代碼如下:
@keyframes banner-swipe {
0% { left: 0; }
33.33% { left: -300px; }
66.66% { left: -600px; }
100% { left: -900px; }
}
.banner-list {
width: 1500px;
height: 100%;
position: absolute;
left: 0;
top: 0;
padding: 0;
margin: 0;
list-style: none;
animation: banner-swipe 10s ease-in infinite;
}
定義了一個(gè)幀動(dòng)畫,因?yàn)橛?張圖,所以只要滾動(dòng)三次就能全部播放完圖片,把整個(gè)滾動(dòng)時(shí)間看作100%,那么一幀大約33.33%,而在banner-list上,我們給它綁定上幀動(dòng)畫banner-swipe,規(guī)定完成一次動(dòng)畫要10s,滾完之后不要停,一直無限循環(huán)(infinite),效果如下:
發(fā)現(xiàn)有缺陷,第四張圖和第一張圖之間切換時(shí),會(huì)很快,原因是到第四張圖停止?jié)L動(dòng)時(shí),整個(gè)動(dòng)畫已經(jīng)執(zhí)行完了,就會(huì)立馬回到第一張圖,從0開始,我們把隱藏部分打開看一下:
動(dòng)圖中很明顯了,4過后立馬跳到了1,解決辦法是在4后面加一個(gè)1,幀動(dòng)畫里面再插入一幀,代碼如下:
// html
<div class="banner-list">
<div class="item" id="item1">1</div>
<div class="item" id="item2">2</div>
<div class="item" id="item3">3</div>
<div class="item" id="item4">4</div>
<div class="item" id="item1">1</div>
</div>
// css
@keyframes banner-swipe {
0% { left: 0; }
25% { left: -300px; }
50% { left: -600px; }
75% { left: -900px; }
100% { left: -1200px; }
}
通過上面的修改,保證了滾動(dòng)的連續(xù)性。
現(xiàn)在還有一個(gè)問題,每張圖片幾乎沒有停過,一直在滾動(dòng),這樣肯定達(dá)不到推廣的作用而且也會(huì)使人眼花繚亂,需要再優(yōu)化,修改后的幀動(dòng)畫如下:
@keyframes banner-swipe {
0% { left: 0; }
23% {left: 0;}
25% { left: -300px; }
48% {left: -300px;}
50% { left: -600px; }
73% { left: -600px; }
75% { left: -900px; }
98% { left: -900px; }
100% { left: -1200px; }
}
效果:
————
最后,歡迎大家關(guān)注我哦
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。