移动web开发之flex布局及案例练习

学习完移动web开发的flex布局,给自己做下小结。

传统布局和flex布局对比

1.传统布局

  • 兼容性好
  • 布局繁琐
  • 局限性,不能再移动端很好的布局

2.flex布局

  • 操作方便,布局极其简单,移动端使用比较广泛
  • pc端浏览器支持情况比较差
  • IE11或更低版本不支持flex或仅支持部分

建议如果是开发移动端,或者不考虑兼容的pc端就可以使用flex布局哟。

flex布局原理

  • flex 是 flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性,任何一个容器都可以指定为 flex 布局。
  • 当我们为父盒子设为 flex 布局以后,子元素的 float、clear 和 vertical-align 属性将失效。
  • flex布局又叫伸缩布局 、弹性布局 、伸缩盒布局 、弹性盒布局
  • 采用 Flex 布局的元素,称为 Flex 容器(flexcontainer),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flexitem),简称"项目"。

所以总的来说flex布局就是通过给父盒子添加flex属性,来控制子盒子的位置和排列方式,这个父盒子可以是任何一个容器元素哟。
给父元素开启flex布局方式就是:
display:flex;
设置了这个属性就开启了哟。

父项常见属性

1.flex-direction:设置主轴的方向
在flex布局中有主轴和侧轴二个方位,结合数学里的x,y轴。
默认主轴是x轴,侧轴是y轴,但是我们可以通过该属性来改变主侧轴方向。
在布局里,我们经常就使用y轴为主轴,来让子flex项目垂直排列。
在这里插入图片描述
下面图片里是该属性对应的值及其效果:
在这里插入图片描述
其中,标红字体属性值较为常用哟~

2.justify-content :设置主轴上的子元素排列方式
下面图片里是该属性对应的值及其效果:
在这里插入图片描述
这个可以让我们来对主轴里的子元素排列顺序方式进行控制,为我们省下了不少功夫哟~

3.flex-wrap:设置是否换行
该属性的值只有二个:

  • nowrap :不换行
  • wrap :换行

默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,flex布局中默认是不换行的。
简单的说就是你会发现你在父级元素开启了flex布局后,你创建多少个子项目都会在一行显示,只是里面的子项目的宽度会减小,如果开启换行后,一行放不下后就会在第二行显示。

4.align-items :设置侧轴上的子元素排列方式(单行 )
该属性是控制子项在侧轴(默认是y轴)上的排列方式 在子项为单项(单行)的时候使用,记住哟,一定要是子项目是单行时哟,因为控制多行子项目时有别的属性来哟。

  • flex-start :从头部开始
  • flex-end :从尾部开始
  • center :居中显示
  • stretch :拉伸
    我们经常会将 设置主轴为y轴结合设置侧轴的子元素居中显示结合起来,就可以将水平的二个元素变为上下二个元素居中显示啦。

5.align-content 设置侧轴上的子元素的排列方式(多行)
设置子项在侧轴上的排列方式 并且只能用于子项出现 换行 的情况(多行),这个是对应多行的哟,在单行下是没有效果的。
在这里插入图片描述
align-content 和align-items区别:

  • align-items 适用于单行情况下, 只有上对齐、下对齐、居中和 拉伸
  • align-content适应于换行(多行)的情况下(单行情况下无效), 可以设置 上对齐、下对齐、居中、拉伸以及平均分配剩余空间等属性值。
  • 总结就是单行找align-items 多行找 align-content

6.flex-flow 属性是 flex-direction 和 flex-wrap 属性的复合属性
这个就不用多说啦,就是结合起来啦,示范一个:
flex-flow:row wrap; x为主轴,换行显示。

flex布局子项常见属性

1.flex 属性
flex 属性定义子项目分配剩余空间,用flex来表示占多少份数。
这里如果我们给每个子项目设为1,那么就是平分父元素的宽度哟。

.item {
    
    
    flex: <number>; /* 默认值 0 */
}

2.align-self:控制子项自己在侧轴上的排列方式

如果我们要让一个子项目有自己的在侧轴排列的方式,就是覆盖掉父元素的align-items 属性,就可以用该属性。
默认值为 auto,表示继承父元素的 align-items 属性,如果没有父元素,则等同于 stretch。

span:nth-child(2) {
    
    
      /* 设置自己在侧轴上的排列方式 */
      align-self: flex-end;
}

3.order 属性定义项目的排列顺序
这个的属性含义简单来说就是一堆子项目在按正常的顺序排队在,我们要定义的一个子元素在后面,我们想插队了,怎么办,我们就可以用这个属性,数值越小,排列越靠前,默认为0。当然,插队是不对的哟。
注意:和 z-index 不一样z-index是排列元素上下顺序的。

.item {
    
    
    order: <number>;  还可以取负数哟。
}

携程网移动端首页案例练习

1.先将项目环境搭建好。

在这里插入图片描述
然后我们就开始设置初始化。

<!DOCTYPE html>
<html lang="zh">
	<head>
		<meta charset="UTF-8">
		<!--视图标签 设置手机端和pc端一比一,不允许用户缩放,最大和最小缩放都是1 -->
		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no,maximum-scale=1.0,minimum-scale=1.0">
		<meta http-equiv="X-UA-Compatible" content="ie=edge">
		<!-- 引入css初始化文件 -->
		<link rel="stylesheet" type="text/css" href="css/normalize.css" />
		<!-- 引入首页css样式文件 -->
		<link rel="stylesheet" type="text/css" href="css/index.css" />
		<title></title>
	</head>
	<body>
	</body>
</html>

给body结合具体需求方案添加默认样式,以及其他一些标签默认样式。

/* 初始化body标签 */
body {
    
    
    max-width: 540px;
    min-width: 320px;
    margin: 0 auto;
    font: normal 14px/1.5 Tahoma, "Lucida Grande", Verdana, "Microsoft Yahei", STXihei, hei;
    color: #000;
    background: #fff;
    overflow-x: hidden;
    -webkit-tap-highlight-color: transparent;
	height: 1000px;
}

a {
    
    
	text-decoration: none;
	color: #222;
}
div {
    
    
	box-sizing: border-box;   /* 将div都转换为css3盒子模型 */
}
ul {
    
    
	margin: 0;
	padding: 0;    /* 出去ul默认的样式 */
	list-style: none;
}

2. 搜索栏部分制作
html部分:

<div class="search-index">
			<div class="search">
				<span>搜索:目的地/酒店/景点/航班号</span>
			</div>
			<a href="#" class="user">
				<span>我 的</span>
			</a>
		</div>

css部分:

/* 搜索栏部分 */
.search-index {
    
    
	display: flex;
	position: fixed;
	width: 100%;      /* 固定定位的元素要给宽度哟 */
	max-width: 540px;
	min-width: 320px;
	height: 44px;
	transform: translateX(-50%);
	left: 50%;            /* 这里运用到了另一种居中的方法  向左偏移屏幕50%,然后向右偏移自身的50% */
	color: #666;
	font-size: .94rem;
	
}

.search {
    
    
	flex: 1;   /* 运用flex布局,左边部分直接划分为剩余的全部空间 */
	height: 28px;
	line-height: 28px;
	background-color: #fff;
	border-radius: 15px;
	margin: 7px 3px 0 11px;
	padding-left: 40px;
	position: relative;
}
.search::before {
    
    
	content: "";
	position: absolute;
	left: 0;
	top: 0;
	width: 35px;
	height: 100%;
	background: url(../images/un_ico.png) no-repeat 15px 7px;
	background-size: 21px auto;
}


.user {
    
    
	display: block;
	width: 51px;
	height: 44px;
	font-size: 12px;
	text-align: center;
	color: #fff;
}
.user::before {
    
    
	content: "";
	display: block;
	width: 22px;
	height: 22px;
	background: url(../images/un_ico.png) no-repeat 1px -36px;
	background-size: 21px auto;
	margin: 4px auto 1px;
}

在这里插入图片描述
这个部分是要固定定位,我们给最外面的盒子一个宽度是100%,能自适应,但是我们还要给一个最大宽度和最小宽度,不然固定定位元素是相对屏幕来说,会和屏幕一样宽。
我们又发现该盒子没有居中,那么我们就要让居中,这里采用的是让该元素向左浮动50%,在让其向右浮动其自身宽度的一半(transform: translateX(-50%);)就可以实现啦。
在看里面有子元素,我们让父盒子开启flex布局,给右边部分一个固定宽度,然后二个块级元素会是上下二行,左边部分我们直接设置flex:1;这样就会自动占用剩余的空间啦,然后给其margin值,让其宽度变小,padding值,让其向右移动,给里面的放大镜腾出位置,里面的放大镜是用绝对定位,让其脱离普通文档流。

3.背景图部分
html部分:

<!-- 背景图 -->
		<div class="header-bg">
		</div>

css部分:

/* 背景图 */
.header-bg {
    
    
	width: 100%;
	height: 198.72px;
	background: url(../images/bg.jpg) no-repeat;
	background-size: 100% 100%;
	border-radius: 0 0 30px 30px;
}

在这里插入图片描述
这个部分没有太多要说的,上面一个模块脱离了普通文档流,我们这个设置个宽和高,插入背景图片就可以自动在上面一个模块的下面了。

4. 局部导航栏
先说一点小知识:
在这里插入图片描述
我们在flex布局中,将水平的二个元素变为垂直居中的二个元素,就可以采用如上图的方法。
html部分:

<ul class="local-nav">
			<li>
				<a href="#" title="攻略景点">
					<span class="local-nav-icon-icon1"></span>
					<span>攻略·景点</span>
				</a>
			</li>
			<li>
				<a href="#" title="门票玩乐">
					<span class="local-nav-icon-icon2"></span>
					<span>门票·玩乐</span>
				</a>
			</li>
			<li>
				<a href="#" title="美食林">
					<span class="local-nav-icon-icon3"></span>
					<span>美食林</span>
				</a>
			</li>
			<li>
				<a href="#" title="周边游">
					<span class="local-nav-icon-icon4"></span>
					<span>周边游</span>
				</a>
			</li>
			<li>
				<a href="#" title="一日游">
					<span class="local-nav-icon-icon5"></span>
					<span>一日游</span>
				</a>
			</li>
		</ul>

css部分:

* 局部导航栏 */
.local-nav {
    
    
	display: flex;
	margin: -35px 12px 10px;
	padding: 4px 0 8px;
	border-radius: 8px;
	box-shadow: 0 2px 6px rgba(0,0,0,.1);
	background-color: #fff;
}
.local-nav li {
    
    
	flex: 1;
	
}
.local-nav a {
    
    
	display: flex;
	flex-direction: column;   /* 这里将内部flex布局主轴变为y,在将侧轴居中对齐 */
	align-items: center;
	font-size: 12px;
}

.local-nav li [class^="local-nav-icon"] {
    
    
	width: 40px;
	height: 40px;
	background: url(../images/home-fivemain.15.png) 0 0 no-repeat;
	background-size: 40px auto;
}
.local-nav li .local-nav-icon-icon2 {
    
    
	background-position: 0 -40px;
}
.local-nav li .local-nav-icon-icon3 {
    
    
	background-position: 0 -80px;
}
.local-nav li .local-nav-icon-icon4 {
    
    
	background-position: 0 -120px;
}
.local-nav li .local-nav-icon-icon5 {
    
    
	background-position: 0 -160px;
}

在这里插入图片描述
这里我们开启父盒子flex布局,然后让子项目flex:1;,一下子就让里面的小li平均划分啦,由于父盒宽度是继承body,所以这些子元素也是自适应的啦。
小li里面是a标签,在a标签里是二个span,我们这里采用上面介绍的方法,让a标签开启flex布局,主轴变为y轴,侧轴对齐方式为居中对齐,这样图标和文字就垂直居中对齐啦。
还有一点要说明的是,这里面的图标都不相同,但他们是精灵图,我们只需要改变精灵图的位置就可以切换背景图效果,不用直接换图片。这里我们是用的一个属性选择器,选择class=‘local-nav-icon’开头的,因为这些子元素都有这个开头,给他们设置公共样式,然后单独给每个子元素设置背景图位置。

5.主导航栏
html部分:

<!-- 主导航栏 -->
		<nav>
			<div class="nav-common">
				<a href="#" class="nav-items">
					<span>酒店</span>
				</a>
				<a href="#" class="nav-items">
					<span>民宿·客栈</span>
				</a>
				<a href="#" class="nav-items">
					<span>机票/火车票+酒店 </span>
				</a>
			</div>
			<div class="nav-common">
				<a href="#" class="nav-items">
					<span>机票</span>
				</a>
				<a href="#" class="nav-items">
					<span>火车票</span>
				</a>
				<a href="#" class="nav-items car">
					<span>汽车·船票</span>
					<span>专车·租车</span>
				</a>
			</div>
			<div class="nav-common">
				<a href="#" class="nav-items">
					<span>酒店</span>
				</a>
				<a href="#" class="nav-items">
					<span>民宿·客栈</span>
				</a>
				<a href="#" class="nav-items car">
					<span>邮轮游</span>
					<span>定制游</span>
				</a>
			</div>
		</nav>

css部分:

/* 主导航栏部分 */
nav {
    
    
	margin: 0 12px 1px;
	border-radius: 8px;
	overflow: hidden;
}
.nav-common {
    
    
	display: flex;
	height: 66px;
}
.nav-common:nth-child(2) {
    
    
	margin: 1px 0;
}
.nav-common a {
    
    
	color: #fff;
	font-size: 14px;
	line-height: 66px;
}
/* 第一行 */
.nav-items:nth-child(1) {
    
    
	flex: 30%;
	padding-left: 12px;
	border-right: 1px solid #fff;
	background: url(../images/grid-nav-items-hotel.png) no-repeat;
	background-size: 73px auto;
	background-position: right bottom;
	background-color: #fa6b53;
}
.nav-items:nth-child(2) {
    
    
	flex: 23%;
	text-align: center;
	border-right: 1px solid #fff;
	background: url(../images/grid-nav-items-minsu.png) no-repeat;
	background-size: 37px auto;
	background-position: left bottom;
	background-color: #fb8251;
}
.nav-items:nth-child(3) {
    
    
	flex: 47%;
	text-align: center;
	background: url(../images/grid-nav-items-jhj.png) no-repeat;
	background-size: 86px auto;
	background-position: right bottom;
	background-color: #ffbd49;
}

/* 第二行及第三行 */ 

.car {
    
    
	display: flex;
}
.car span {
    
    
	flex: 1;
}
.car span:nth-child(1) {
    
    
	border-right: 1px solid #fff;
}
.nav-common:nth-child(2) .nav-items {
    
    
	background-color: #4d99ed;
}
.nav-common:nth-child(3) .nav-items {
    
    
	background-color: #47c88d;
}

在这里插入图片描述
这个部分每行背景颜色真实做法是用的背景线性渐变,我的做法错啦,嘿嘿,看看就好了啦,毕竟我是小白啦,练习过程就是认错改错啦。
背景线性渐变语法:

background: linear-gradient(起始方向, 颜色1, 颜色2, ...);
background: -webkit-linear-gradient(left, red , blue);
background: -webkit-linear-gradient(left top, red , blue);
背景渐变必须添加浏览器私有前缀 起始方向可以是: 方位名词 或者 度数 , 如果省略默认就是 top

做这一板块也是用的flex属性,给子元素划分大小,按照具体项目来划分各个子元素的大小,可能还需要在子元素里面在进行划分哟。这里是第二行给的1px的上线外边距,里面子元素是给中间二个给了1px白色的左右边框。

6.图标导航部分
html部分:

<!-- 图标导航部分 -->
		<ul class="subnav-entry">
			<li>
				<a href="#">
					<span class="subnav-entry-icon-icon1"></span>
					<span>自由行</span>
				</a>
			</li>
			<li>
				<a href="#">
					<span class="subnav-entry-icon-icon2"></span>
					<span>WiFi电话卡</span>
				</a>
			</li>
			<li>
				<a href="#">
					<span class="subnav-entry-icon-icon3"></span>
					<span>保险·签证</span>
				</a>
			</li>
			<li>
				<a href="#">
					<span class="subnav-entry-icon-icon4"></span>
					<span>换钞·购物</span>
				</a>
			</li>
			<li>
				<a href="#">
					<span class="subnav-entry-icon-icon5"></span>
					<span>当地向导</span>
				</a>
			</li>
			<li>
				<a href="#">
					<span class="subnav-entry-icon-icon6"></span>
					<span>特价机票</span>
				</a>
			</li>
			<li>
				<a href="#">
					<span class="subnav-entry-icon-icon7"></span>
					<span>礼品卡</span>
				</a>
			</li>
			<li>
				<a href="#">
					<span class="subnav-entry-icon-icon8"></span>
					<span>申卡·借钱</span>
				</a>
			</li>
			<li>
				<a href="#">
					<span class="subnav-entry-icon-icon9"></span>
					<span>旅拍</span>
				</a>
			</li>
			<li>
				<a href="#">
					<span class="subnav-entry-icon-icon10"></span>
					<span>更多</span>
				</a>
			</li>
			
		</ul>

css部分:

/* 图标导航部分 这一部分和上面底部导航栏类似 */
.subnav-entry {
    
    
	display: flex;
	flex-wrap: wrap;    /* 让小li换行显示 */
	margin: 0 12px 12px;
	border-radius: 8px;
	overflow: hidden;
}
.subnav-entry li {
    
    
	flex: 20%;  /* 这里让每个小li占百分之20,就可以让10个小li分二行显示 */
}

.subnav-entry a {
    
    
	display: flex;
	flex-direction: column;
	align-items: center;
	font-size: 12px;
}
.subnav-entry a [class^="subnav-entry-icon"] {
    
    
	width: 28px;
	height: 28px;
	background: url(../images/un_ico_subnav2x.png) no-repeat;
	background-size: 28px auto; 
}
.subnav-entry a .subnav-entry-icon-icon2 {
    
    
	background-position: 0 -28px ;
}
.subnav-entry a .subnav-entry-icon-icon3 {
    
    
	background-position: 0 -56px ;
}
.subnav-entry a .subnav-entry-icon-icon4 {
    
    
	background-position: 0 -84px ;
}
.subnav-entry a .subnav-entry-icon-icon5 {
    
    
	background-position: 0 -112px ;
}
.subnav-entry a .subnav-entry-icon-icon6 {
    
    
	background-position: 0 -140px ;
}
.subnav-entry a .subnav-entry-icon-icon7 {
    
    
	background-position: 0 -168px ;
}
.subnav-entry a .subnav-entry-icon-icon8 {
    
    
	background-position: 0 -196px ;
}
.subnav-entry a .subnav-entry-icon-icon9 {
    
    
	background-position: 0 -224px ;
}
.subnav-entry a .subnav-entry-icon-icon10 {
    
    
	background-position: 0 -252px ;
}

在这里插入图片描述
这一部分和上面的导航很相似,这里要说的是让父元素开启换行,然后给每个子元素flex:20%,就可以让10个小li在二行平分显示,当然这里是计算得来的,十个二行,那么每个宽度就是0.2呀。然后就是垂直居中显示文字和图标也是上面的方法,这里图标的切换也是用的上面的方法,因为这里也是用的精灵图做背景。

7.销售部分。
html部分:

<!-- 销售板块 -->
		<div class="sales-box">
		    <div class="sales-hd">
		        <h2>热门活动</h2>
		        <a href="#" class="more">获取更多福利</a>
		    </div>
		    <div class="sales-bd">
		        <div class="row">
		            <a href="#">
		                <img src="upload/pic1.jpg" alt="">
		            </a>
		            <a href="#">
		                <img src="upload/pic2.jpg" alt="">
		
		            </a>
		        </div>
		        <div class="row">
		            <a href="#">
		                <img src="upload/pic3.jpg" alt="">
		            </a>
		            <a href="#">
		                <img src="upload/pic4.jpg" alt="">
		
		            </a>
		        </div>
		        <div class="row">
		            <a href="#">
		                <img src="upload/pic5.jpg" alt="">
		            </a>
		            <a href="#">
		                <img src="upload/pic6.jpg" alt="">
		
		            </a>
		        </div>
		
		    </div>
		</div>

css部分:

/* sales-box */

.sales-box {
    
    
    border-top: 1px solid #bbb;
    background-color: #fff;
    margin: 4px;
}

.sales-hd {
    
    
    position: relative;
    height: 44px;
    border-bottom: 1px solid #ccc;
}

.sales-hd h2 {
    
    
    position: relative;
    text-indent: -999px;
    overflow: hidden;
}

.sales-hd h2::after {
    
    
    position: absolute;
    top: 5px;
    left: 8px;
    content: "";
    width: 79px;
    height: 15px;
    background: url(../images/hot.png) no-repeat 0 -20px;
    background-size: 79px auto;
}

.more {
    
    
    position: absolute;
    right: 5px;
    top: 0px;
    background: -webkit-linear-gradient(left, #FF506C, #FF6BC6);
    border-radius: 15px;
    padding: 3px 20px 3px 10px;
    color: #fff;
}

.more::after {
    
    
    content: "";
    position: absolute;
    top: 9px;
    right: 9px;
    width: 7px;
    height: 7px;
    border-top: 2px solid #fff;
    border-right: 2px solid #fff;
    transform: rotate(45deg);
}

.row {
    
    
    display: flex;
}

.row a {
    
    
    flex: 1;
    border-bottom: 1px solid #eee;
}

.row a:nth-child(1) {
    
    
    border-right: 1px solid #eee;
}

.row a img {
    
    
    width: 100%;
}

在这里插入图片描述

这一板块是分为上下二个部分,上面部分是我们给整个大盒子一个上边框,然后给上面部分盒子一个下边框就有了上面二个边框的效果,里面是二个背景图,然后都是绝对定位,定位到二侧,还要说一下,那个右侧图片里面的小三角是用的css3里面的旋转45°,然后设置上和右边框就可以实现啦。
下面部分就更简单啦,每一行是二个图片,然后在父元素上启动flex布局,给每行二个子元素flex为1就可以平分一行的宽度,然后插入图片,记得给每行的子元素设置下边框,然后每行第一个子元素设置右边框即可。
做完这个练习还是获益匪浅,有点熟悉flex布局的用法,对比学习的流式布局更加的简单方便,更加有利于我们进行移动网页的开发。

猜你喜欢

转载自blog.csdn.net/xia_zai_ya/article/details/105934701