Flexbox 实战:使用 Flexbox 轻松实现下拉导航菜单
CSS3弹性盒子(Flexible Box 或 Flexbox),是一种用于在页面上布置元素的布局模式,使得当页面布局必须适应不同的屏幕尺寸和不同的显示设备时,元素可预测地运行。对于许多应用程序,弹性盒子模型提供了对块模型的改进,因为它不使用浮动,flex容器的边缘也不会与其内容的边缘折叠。
浏览器对Flexbox的支持越来越好。使用它可以轻松实现一些复杂的UI用户界面,不需要任何的CSS或者是javascript的黑科技。
使用Flexbox可以轻松实现各种水平或者是垂直的布局,对于不同尺寸的屏幕,不需要很多的媒体查询就可以轻松做到自适应。
这篇教程,我们使用Flexbox来实现一个复杂一点的下拉导航菜单。当然这里不会花太多文字放在Flexbox的一些基本属性的介绍,Flexbox基本的介绍和使用可以去下面这些文章看看:
Flexbox Course by Guy Routledge
A Friendly Introduction to Flexbox for Beginners
下来看看我们要做的导航菜单,如下图所示:
demo地址
下载地址
主要用到了下面三个方面的知识:
1、使用Flexbox实现一个包含下拉菜单的水平方向导航栏
2、实现一个单栏的下拉菜单
3、实现一个多栏的下拉菜单
使用Flexbox实现一个水平菜单
导航菜单的结构非常简单,主要是由navbar和menu两个类结构组成。
< nav
class = "navbar" >
< ul
class = "menu" >
< li >
< a
href = "#" >
Electronics
<!--
FontAwesome icon -->
< i
class = "fa
fa-angle-down" ></ i >
</ a >
</ li >
<!--
... More nav items here... -->
< ul >
</ ul ></ ul ></ nav >
|
首先导航菜单是水平方向的布局,我们期望的是每个导航栏目在没有足够的空间时,也能自动的根据空间来进行响应式适用。
这种布局使用Flexbox来实现再好不过了。首先要声明menu这个元素的flex属性,可以使用display:flex来声明,这样menu元素的所有子元素都具有来flex属性。
现在设置flex的值为1,即如果空间不足,该项目将缩小。
.navbar
.menu {
display :
flex;
position :
relative ;
}
.navbar
.menu li {
flex:
1 ;
display :
flex;
text-align :
center ;
}
.navbar
.menu a {
flex:
1 ;
justify- content :
center ;
color :
#ffffff ;
padding :
20px ;
}
|
从上面的代码可以看到,对于.navbar .menu li和.navbar .menu两个元素都设置了display:flex的属性。从demo可以看到,当鼠标滑过菜单选项的时候可以看到背景颜色发生了改变。如果不设置display的值为flex,那么li元素只会占据本身内容所占的宽度,而不是根据整个导航栏的宽度来平分了。
为了使导航菜单的子元素能根据父级元素的宽度来扩展自己的宽度,所以在li元素和a元素上都声明了flex:1属性,这样可以使子元素能占满整个宽度了。
目前导航栏的基本布局完成了,代码预览地址。
demo地址
下载地址
可以看到使用Flexbox可以非常轻松的完成这样类型的布局,而且简洁高效。
下面来实现下拉菜单这一项。
单栏下拉菜单
下面是下拉菜单的结构,当然它可以复用到其它地方。
< ul
class = "container" >
<!--
single column -->
< div
class = "container__list" >
<!--
menu item -->
< div
class = "container__listItem" >
< div >Televisions</ div >
</ div >
<!--
... other menu items here -->
</ div >
</ ul >
|
类名为container是flex容器而且每一个子元素(containerlist)都是容器成员,即Flex项目。而且每一个**containerlist项目都有多个导航栏目,所以我使用了一个div**来包裹它。
下面是CSS代码:
.container
{
/*
initially hidden; display:flex on hover */
display:
none;
position:
absolute;
top:
56px;
left:
0;
right:
0;
background-color:
#ffffff;
padding:
20px;
text-align:
left;
}
.container__list
{
flex:
1;
display:
flex;
flex-wrap:
wrap;
}
.container__listItem
{
flex:
0 0 25%;
padding:
10px 30px;
}
.container__listItem
> div {
color:
#DB6356;
}
|
从上面代码可以注意到我在container__list容器上使用了flex-wrap属性,我们想它的宽度是占整个宽度的25%,当空间不够时,它就自动换行。
flex-grow属性定义项目的放大比例,我们设置它的值为0,即如果存在剩余空间,也不放大。
对于container__listItem元素,为了使文字太宽而影响布局的美观,需要做一下截断处理,比如超过指定的宽度,就显示省略号,可以使用下面的代码来实现:
.container__list
{
flex:
1;
display:
flex;
flex-wrap:
wrap;
/*
updated */
min-width:
0;
}
.container__listItem
{
flex:
0 0 25%;
padding:
10px 30px;
/*
updated */
overflow:
hidden;
white-space:
nowrap;
text-overflow:
ellipsis;
}
.container__listItem
> div {
color:
#DB6356;
/*
updated */
overflow:
hidden;
white-space:
nowrap;
text-overflow:
ellipsis;
}
|
实现多栏下拉菜单
在上面单栏菜单的基础上实现多栏菜单,就非常简单了。在这里,直接复用单栏菜单的结构即container__list的结构到菜单选项Appliances里面。当然这里只是简单的复制结构实现一个实例,在实际开发中,一般会使用到javascript来动态生成这些菜单选项。
这里会额外的增加一个has-multi类来区分开单栏与多栏的区别,并且来针对多栏菜单声明一些单独的属性的值。
.container.has-multi
.container__list {
flex-basis:
33.333%;
}
.container.has-multi
.container__list:not(:last-child) {
border-right:
solid 1px #f3f3f3;
margin-right:
20px;
}
.container.has-multi
.container__listItem {
flex-basis:
100%;
}
|
这里指定了多栏菜单选项的flex-basis的值为33.333,即多栏菜单选项占据的宽度为33.333,这样可以显示为三栏菜单。
当然,这个菜单并不是完全是响应式的。在小屏幕上只是简单垂直显示选项,而且选项下的子菜单并没有显示,还有很多改进的余地。总之通过这一个下拉导航菜单的实例,可以充分的证明Flexbox这个属性在布局上的威力,这里只是抛砖引玉下,在实际开发中还有很多的实用的地方。
本文主要是从Building Mega Menus with Flexbox这篇文章整理而来,有删减,有疏漏或者理解不到位的地方,还请多多指教!
原文地址:http://svgtrick.com/tricks/d172c31188f427a598b00148337a621d