最近把《CSS实战手册:the missing manual》的基础部分看得差不多了,也想实践一下子。其实该从哪些部分开始下手实践我也不知道,偶然看见“二级导航”这几个字便趁空一试。
成果图:
代码在最下方。
大致思路:
使用嵌套列表,子菜单使用<li>标签中的<ul>实现。
<ul class="nav">
<li class="menu"><a href="" class="menuLink">菜单一</a>
<ul class="submenu">
<li><a href="">子菜单一</a></li>
<li><a href="">子菜单二</a></li>
<li><a href="">子菜单三</a></li>
</ul>
</li>
重点在于如何处理同一<li>元素中<ul>和<a>的关系,以及如何将所有单元中的主选项另外组合形成导航栏,因为开始感觉毕竟是同一个<li>中的元素,总存在些依附关系。
不过我发现一个重要的法则是“从外到内”依次处理,也不断将处理范围缩小。所以首先将每个单元看做整体,此例中存在四个单元。此处的处理重点是,将主菜单选项和子菜单装饰成相同的外观,如果不处理的话就会有默认的表示等级关系的错位,不过处理也简单,消除margin就行。(反正我现在不管是咋回事先把margin和padding全清了嘻嘻)
【此处回忆一下导航栏要点:<a>设置成block,如需横向导航栏将<li>设置成inline。】
现在将四个整齐的单元放在最外层的<ul>中来看,设置相互间的间距,然后使用text-align:center将<ul>于页面居中。
将子菜单隐藏的要点就是display:none/block. 但是就算已经知道这一点,我还是面临了两个挫折。
1.如何使用:hover。如果不了解:hover的真正用法会很疑惑在不同元素关系下的使用方式,不过我在此处找到了解释:css:hover状态改变另一个元素样式的使用
2.我最开始是使用padding之类的属性来定位,后来也成功使得子菜单消失,但在其重新显示时,其它主菜单选项都下坠了。后来我想应该是出现的子菜单将盒子向下撑大了,使得菜单选项坠到了底部。而且如果在这时加上:hover效果(产生border-bottom)会使得子菜单下降,因为子菜单和主菜单选项之间又插入了几个像素,把它给挤下去了...所以又重写换成了相对和绝对定位。具体就是主菜单使用绝对定位,子菜单使用margin-top(这样还可将border-bottom的几像素空出来). 此处也用上了很好用的>符号用以选择第一级后代,可以帮助我把每个单元中的第一个<a>元素即主菜单选项提取出来绝对定位在导航栏的位置。(我突然发现好像不用提取???)
然后就成功了。
总结一下本次小小实践的收获:
b."从外到内"
c.其实margin和padding也给我造成了不小的麻烦。有时会因为继承造成奇怪的错位,这时我就只能用border把每个元素框出来看是哪儿出现的问题。我觉得为了更好地处理这样的问题,手持设计稿定会相当有效。
HTML:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>fantasia</title>
<link href="style.css" rel="stylesheet">
</head>
<body>
<nav>
</nav>
<ul class="nav">
<li class="menu"><a href="" class="menuLink">菜单一</a>
<ul class="submenu">
<li><a href="">子菜单一</a></li>
<li><a href="">子菜单二</a></li>
<li><a href="">子菜单三</a></li>
</ul>
</li>
<li class="menu"><a href="" class="menuLink">菜单二</a>
<ul class="submenu">
<li><a href="">子菜单一</a></li>
<li><a href="">子菜单二</a></li>
<li><a href="">子菜单三</a></li>
</ul>
</li>
<li class="menu"><a href="" class="menuLink">菜单三</a>
<ul class="submenu">
<li><a href="">子菜单一</a></li>
<li><a href="">子菜单二</a></li>
<li><a href="">子菜单三</a></li>
</ul>
</li>
<li class="menu"><a href="" class="menuLink">菜单四</a>
<ul class="submenu">
<li><a href="">子菜单一</a></li>
<li><a href="">子菜单二</a></li>
<li><a href="">子菜单三</a></li>
</ul>
</li>
</ul>
</body>
</html>
CSS部分:
* {
box-sizing: border-box;
}
html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp,small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
vertical-align: baseline;
}
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1.2;
}
ol {
padding-left: 1.4em;
list-style: decimal;
}
a{
text-decoration:none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
ul, li{
padding:0;
margin:0;
}
/*以上是别处复制来的预处理*/
/*code begins*/
body{
background-color:#C4C4C4;
}
.nav{
width:100%;
height:50px;
background-color:#DDDDDD;
margin-top:50px;
box-shadow:0px 5px 5px #888888;
position:relative;
text-align:center;/*让一级导航居中*/
}
.nav li{
list-style:none;
width:100px;/*无论一级还是二级*/
}
.nav>li{
display:inline-block;
/*border:1px solid black;*/
margin:0 50px;/*相当于每个单元的margin*/
}
.nav a{
display:block;
line-height:50px;
text-align:center;
/*border:1px solid black;*/
}
.nav ul{
position:absolute;
top:54px;
/*border:1px solid black;*/
display:none;
background-color:#DDDDDD;
}
.menu:hover ul.submenu{
display:block;
}
.menu a:hover{
color:#008B8B;
}
.menu>a:hover{
border-bottom:3px solid rgba(183, 56, 183, 1);
transition:border-bottom 0.8s;
}
18/4/8
今天把代码转移到codepen时,发现一个不足,从主菜单滑到子菜单时如果碰到了中间预留给下划线的缝隙会导致子菜单消失。