從本篇教程開始,將會以網(wǎng)站中常用的一些組件為例,來幫助大家了解和熟悉PbootCMS的標(biāo)簽。
因為習(xí)慣從上往下寫頁面代碼,所以就從網(wǎng)頁頭部的導(dǎo)航菜單開始。
本篇教程所需要掌握的知識點:CSS盒子模型、CSS選擇器、浮動、清除浮動、**定位、相對定位、CSS3 2D轉(zhuǎn)換、CSS3 過渡、導(dǎo)航菜單列表標(biāo)簽、當(dāng)前欄目標(biāo)簽、if條件語句、PHP運(yùn)算符。
每個人都有自己的代碼習(xí)慣,比如我就喜歡先寫HTML(結(jié)構(gòu)),再寫模板標(biāo)簽(數(shù)據(jù)),接著寫CSS(樣式),醉后寫JS(交互)。
所以,先開始寫導(dǎo)航菜單的HTML部分:
<!-- 演示就只寫二級導(dǎo)航,更多級導(dǎo)航大家可以依葫蘆畫瓢 --> <nav class="menu"> <ul> <li> <a href="#"></a> <ul> <li> <a href=""></a> </li> </ul> </li> </ul> </nav>
是不是很簡單?就是ul和li的無序列表嵌套而已。如果不想寫CSS的時候進(jìn)行復(fù)雜的子元素選擇,還可以給二級菜單的ul加個class,比如實例代碼:
接下來,使用PbootCMS的模板標(biāo)簽來填充數(shù)據(jù):
<nav class="menu"> <ul> {pboot:nav} <li> <a href="[nav:link]">[nav:name]</a> <ul class="sub-menu"> {pboot:2nav parent=[nav:scode]} <li> <a href="[2nav:link]">[2nav:name]</a> </li> {/pboot:2nav} </ul> </li> {/pboot:nav} </ul> </nav>
看一下前端頁面:
可以看到,二級菜單已經(jīng)調(diào)用出來了,接下來處理一下導(dǎo)航高亮。
導(dǎo)航高亮:
原理:判斷當(dāng)前欄目的ID和導(dǎo)航的ID是否一致,如果一致,則添加class,然后CSS中給這個class設(shè)置高亮樣式。
方案:使用if條件語句結(jié)合當(dāng)前欄目標(biāo)簽以及導(dǎo)航菜單列表標(biāo)簽進(jìn)行判斷。
代碼:
<nav class="menu"> <ul> {pboot:nav} <li class="{pboot:if('[nav:scode]'=='{sort:tcode}')}active{/pboot:if}"> <a href="[nav:link]">[nav:name]</a> <ul class="sub-menu"> {pboot:2nav parent=[nav:scode]} <li class="{pboot:if('[2nav:scode]'=='{sort:scode}')}active{/pboot:if}"> <a href="[2nav:link]">[2nav:name]</a> </li> {/pboot:2nav} </ul> </li> {/pboot:nav} </ul> </nav>
說明:[nav:scode]是導(dǎo)航列表標(biāo)簽中調(diào)用的欄目id,{sort:tcode}是當(dāng)前欄目的頂極欄目編碼。那么,這里為什么不用{sort:scode}這個當(dāng)前欄目編碼呢?雖然在一級導(dǎo)航中,當(dāng)前欄目{sort:scode}和頂極欄目{sort:tcode}的值是一樣的,能起到一樣的效果。但是導(dǎo)航是需要整站通用的,在子欄目頁面,{sort:scode}的值就是子欄目的id了,主導(dǎo)航的一級欄目就得不到高亮樣式了。同理,這里也不用{sort:pcode}父級欄目編碼。在醉下級的導(dǎo)航中則只需要判斷[nav:scode]等于{sort:scode}就可以了。留一個思考題吧:如果是三級或者更多級導(dǎo)航的時候應(yīng)該怎么樣判斷?提示:利用PHP運(yùn)算符來組合多個if條件。
到此為之,多級導(dǎo)航所需要的東西都存在了,接下來就交給CSS來把這個多級導(dǎo)航美化一下了。
一、磨刀不誤砍柴工,先做一些準(zhǔn)備(關(guān)于涉及到的一些CSS概念,大家可以自行百度或者去看CSS參考手冊)。
1、設(shè)置盒模型(方便padding和margin的計算)
//演示就簡單粗暴地使用*來 * { box-sizing: border-box; }
2、浮動與清除浮動
//左浮動 .float-left { float: left; } //右浮動 .float-right { float: right; } //清除浮動 .clearfix::before { content: ""; display: table-cell; } .clearfix::after { content: ""; display: table; clear: both; }
3、設(shè)置字體
body { margin: 0; padding: 0; color: #333; font: 16px/24px "-apple-system", "Helvetica", "Microsoft YaHei", "PingFang SC"; outline: none; }
4、清除ul和li的默認(rèn)樣式
ul, li { margin: 0; padding: 0; list-style: none; }
5、設(shè)置a標(biāo)簽的默認(rèn)樣式
a, a:after, a:before { text-decoration: none; color: #333; cursor: pointer; outline: none; -webkit-transition: all 0.5s; -moz-transition: all 0.5s; -ms-transition: all 0.5s; -o-transition: all 0.5s; transition: all 0.5s; } a:hover { color: #8667F7; }
以上樣式,算是初始化整體頁面樣式,不僅能用在導(dǎo)航,也影響整站。
看一下初始化樣式后的頁面:
可以看到,扎眼的鏈接藍(lán)色和下劃線,以及不同瀏覽器下body不同寬度的邊距,ul和li默認(rèn)的樣式都不見了,鼠標(biāo)移到鏈接上,還有一個顏色漸變效果。
二、先整體后局部,先給導(dǎo)航整體添加樣式美化
1、設(shè)置導(dǎo)航高度和寬度,以及背景顏色和文字顏色
/* - 設(shè)置導(dǎo)航高度寬度和背景色 - 沒有邊距,文字貼著邊不好看,給個內(nèi)邊距padding: 16px; */ .menu { padding: 0 16px; width: 100%; height: 48px; background: #000; } /* 一級菜單設(shè)置為相對定位 */ .menu > ul > li { position: relative; } /* - 因為導(dǎo)航背景顏色是黑色,所以設(shè)置一級導(dǎo)航的文字顏色是白色 - 導(dǎo)航高48px,一級導(dǎo)航的文字要垂直居中,可以計算(48-文字行高)/2,然后設(shè)置外邊距或者內(nèi)邊距,讓文字剛好居中。 - 上面的居中方式太復(fù)雜了,不如line-height: 48px;讓文字行高和導(dǎo)航高度一樣,自然就居中了。 */ .menu > ul > li > a { line-height: 48px; color: #FFF; }
2、現(xiàn)在導(dǎo)航是垂直排列的,讓他們浮動起來
還記得前面定義的float-left和float-right以及clearfix嗎?直接把他們放在class里面吧。
看一下現(xiàn)在前端是什么樣子了:
看起來是有點像那么回事了。
三、美化一級導(dǎo)航
1、調(diào)整一級導(dǎo)航的間距
.menu > ul > li > a { display: block; padding: 0 32px; line-height: 48px; color: #FFF; }
思考:為什么要display: block?同樣是邊距,為什么使用padding而不用margin?
2、給一級導(dǎo)航高亮
.menu > ul > li:hover > a, .menu > ul > li.active > a { background: #8667F7; }
思考:為什么hover放在li處而不是a處?
看一下現(xiàn)在的前端樣式:
四、美化二級導(dǎo)航
1、二級導(dǎo)航背景色,陰影
/* - 二級菜單會占用高度,因此需要給它設(shè)置**定位,因為一級菜單是相對定位,因此二級菜單的位置是根據(jù)一級菜單來的 - 二級菜單的寬度100%也是根據(jù)一級菜單來的 */ .sub-menu { position: absolute; width: 100%; top: 48px; left: 0; background: #8667F7; box-shadow: 0 0 8px rgba(0,0,0,0.1); }
2、調(diào)整二級導(dǎo)航文字
.sub-menu > li > a { display: block; padding: 8px; text-align: center; font-size: 14px; color: #FFF; }
3、二級導(dǎo)航之間添加分割線
.sub-menu > li + li > a { border-top: 1px solid #7256D8; }
4、二級導(dǎo)航鼠標(biāo)hover效果
.sub-menu > li:hover > a { background: #000; }
再來看一下現(xiàn)在的效果:
看起來不錯,就差一步了。
五、CSS實現(xiàn)下拉效果
要實現(xiàn)二級導(dǎo)航的下拉效果有很多方法,這里只介紹使用CSS3的2D轉(zhuǎn)換來實現(xiàn)。
CSS3中的transform能夠?qū)崿F(xiàn)元素的2D或3D轉(zhuǎn)換。
實際上,translateY是定義Y軸轉(zhuǎn)換,是醉適合的一個。不過考慮到二級菜單的高度不一,還需要使用js來判斷,有點麻煩。因此使用scaleY(Y軸縮放)來實現(xiàn)二級菜單的下拉效果。
1、先給二級菜單加一個過渡
-webkit-transition: all 0.5s; -moz-transition: all 0.5s; -ms-transition: all 0.5s; -o-transition: all 0.5s; transition: all 0.5s;
2、設(shè)置2D轉(zhuǎn)換的基點位置
-webkit-transform-origin: 0 0; -moz-transform-origin: 0 0; -ms-transform-origin: 0 0; -o-transform-origin: 0 0; transform-origin: 0 0;
3、默認(rèn)狀態(tài)Y軸縮放為0
-webkit-transform:scaleY( 0 ); -moz-transform:scaleY( 0 ); -ms-transform:scaleY( 0 ); -o-transform:scaleY( 0 ); transform:scaleY( 0 );
4、默認(rèn)狀態(tài)隱藏,并且因為二級導(dǎo)航要覆蓋在其他層上面,設(shè)置z-index
opacity: 0; //默認(rèn)透明 z-index: 999; //在其他層上面 visibility: hidden; //不可見
綜合樣式:
.sub-menu { position: absolute; width: 100%; top: 48px; left: 0; background: #8667F7; box-shadow: 0 0 8px rgba(0,0,0,0.1); opacity: 0; z-index: 999; visibility: hidden; -webkit-transition: all 0.5s; -moz-transition: all 0.5s; -ms-transition: all 0.5s; -o-transition: all 0.5s; transition: all 0.5s; -webkit-transform-origin: 0 0; -moz-transform-origin: 0 0; -ms-transform-origin: 0 0; -o-transform-origin: 0 0; transform-origin: 0 0; -webkit-transform:scaleY( 0 ); -moz-transform:scaleY( 0 ); -ms-transform:scaleY( 0 ); -o-transform:scaleY( 0 ); transform:scaleY( 0 ); }
5、鼠標(biāo)hover的時候取消透明和不可見,Y軸縮放為1
/* 注意:一級導(dǎo)航hover時觸發(fā) */ .menu > ul > li:hover .sub-menu { opacity: 1; visibility: visible; -webkit-transform:scaleY( 1 ); -moz-transform:scaleY( 1 ); -ms-transform:scaleY( 1 ); -o-transform:scaleY( 1 ); transform:scaleY( 1 ); }
到此為止,一個有簡單動畫效果的下拉二級導(dǎo)航完成。
總結(jié):二級導(dǎo)航雖然看起來代碼量不大,但涉及的知識點還是比較多的,需要花點時間好好研究一下。