17个场景,带你入门CSS布局
CSS 布局本质就是控制元素的位置和大小。比方这样的布局:元素宽960px,水平居中。宽960px是大小。水平居中是位置。又如这样的布局:两个元素在一行,左侧元素固定宽200px,右侧元素撑满剩余空间。固定宽200px,撑满剩余空间是大小。两个元素在一行是位置。
下面,我们从大小和位置两个方面,结合场景来看CSS布局。
大小
大小指元素的占的空间。空间包含水平空间和垂直空间。大部分情况下(注1),
- 所占水平空间 = width值 + 左右padding值 + 左右border宽度值
- 所占垂直空间 = height值 + 上下padding值 + 上下border宽度值
这其实满反直觉的。直觉认为:
- 所占水平空间 = width值
- 所占垂直空间 = height值
要让上面的等式成立,只要给元素设置样式 box-sizing: border-box。这样做,算空间比较容易。因而,我们常常能在项目的通用样式中发现这样的代码:
* { box-sizing: border-box;}box-sizing 设置的是元素的盒模型(Box Model)。页面上的每个元素都被描绘成矩形盒子,用这个盒子来形容其占用空间,这个模型称为盒模型。盒模型由 4 部分组成,从内到外分别是 内容(content),内边距(padding),边框(border)和外边框(margin)。
盒模型
当 box-sizing 设置为 border-box 时,所占水平空间 = width值,内容宽度 = width值 – 左右padding值 – 左右边框宽度值。 例如:
box-sizing: border-box;width: 100px;padding-left: 10px;所占水平空间是 100px,内容宽度值是 90px(width: 100px – padding-left: 10px)。把 padding-left 改成 20px。所占水平空间依然是 100px,内容宽度值是 80px(width: 100px – padding-left: 20px)。
box-sizing 的默认值是 content-box, 水平空间 = width值 + 左右padding值 + 左右border宽度值。
场景01 元素的宽高是固定值
给元素设置固定的宽高,只要设置。如:
width: 100px;height: 100px;注意:给行内元素设置宽高值不会生效。常见的行内元素有a,strong,span。给元素设置样式:display: inline,会将该元素变为行内元素。因而,当发现给元素设置宽高无效时,检查这元素能否是行内元素。
场景02 全屏:元素宽高与浏览器可视区域大小一致
可以用单位 vw 和 vh 实现元素宽高与浏览器可视区域大小一致。1vw 等于浏览器可视区域宽度的1%,1vh 等于浏览器可视区域高度的1%。因而,实现全屏只要要这么写:
{ width: 100vw; height: 100vh;}主流浏览器均兼容 vw 和 vh。PC端,IE9及以上支持,手机端 ios 8 以上以及 Android 4.4 以上取得支持,并且在微信 x5 内核中也得到完美的全面支持。
场景03 撑满父元素的剩余可用宽度
撑满父元素的剩余可用宽度的常见的具体场景是:页面左右结构,左侧是固定宽度的菜单导航,右侧是撑满剩余部分的主题内容。如下图:
撑满父元素的剩余可用宽度
下面列举2种实现方法。毋庸兼容旧浏览器的用方法1,否则用方法2。
方法1 Flex 布局
可以用 Flex 布局中的 flex-grow 来实现宽度撑满父元素的剩余部分。
我们先来简单理解下 Flex 布局。Flex 是 Flexible Box 的缩写,意为”弹性布局”。该布局能为盒模型提供最大的灵活性,是目前主流的布局技术。
采用 Flex 布局的元素,称为 Flex 容器(flex container),简称”容器”。将元素设置为 Flex 容器,只要设置样式display: flex;或者display: inline-flex;。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称”项目”。
flex-grow 属性定义项目的放大比例,默认为0,即假如存在剩余空间,也不放大。值大于0时,就会撑满父元素宽度的剩余部分。具体实现如下:
HTML:
<div class="container"> <div class="left">固定宽度的菜单导航</div> <div class="right">撑满剩余部分的主题内容</div></div>CSS
.ly { display: flex;}.left { width: 300px;}.right: { flex-grow: 1;}垂直方向,假如要实现撑满父元素的剩余可用高度,只要在Flex容器上加样式flex-direction: column,并设置好高度。撑满父元素的剩余可用高度元素上加样式flex-grow: 1。是不是很容易~
想理解更多关于Flex布局的内容,推荐阅读阮一峰老师写的Flex 布局教程:语法篇。
方法2 table 布局
table元素中的 td,假如没有设置宽度,其宽度是弹性的:table的宽度大,td的宽度也变大;table的宽度小,td的宽度也变小。用 table 这特性,正好可以实现我们的场景。但table 的语义是来展现二维数据的,而我们展现的并不是二维数据。幸运的是,CSS 支持模拟 table 的这特性。做法:在父元素上设置display:table,子元素设置 display:table-cell。
HTML:
<div class="container"> <div class="left">固定宽度的菜单导航</div> <div class="right">撑满剩余部分的主题内容</div></div>CSS
.container { display: table; width: 100%;}.left,.right { display:table-cell;}.left { width: 300px;}场景04 父元素剩余空间小于元素宽度,元素宽度变小
可以用 Flex 布局中的 flex-shirk 实现。flex-shrink 属性定义了项目的缩小比例,默认为1,即假如空间不足,该项目将缩小。
假如要兼容旧的浏览器,也可以用 table 布局,具体见上个场景的方法2。
场景05 响应式宽高:元素的宽度和高度和设施的大小有关
移动设施有大有小。为了提高客户体验,在大的设施上,元素就显示的大一点,小的设施,元素就显示的小一点。主要有两种方式来实现:js配合rem实现和媒体查询。
这两种方法,都需要加上设置 viewport 的代码:
<meta name="viewport" content="width=device-width, initial-scale=1.0">想理解这代码的原理,可以阅读在移动浏览器中使用viewport元标签控制布局。
方法1: js配合rem
rem 是尺寸单位。 1rem = 根元素(即html元素)的字体大小值。当根元素的字体大小变化,1rem的大小也会跟着变。假如元素的宽高值用rem做单位,用js获取当前设施的宽度来设置根元素的字体大小,那么,就能实现元素的宽高和设施的大小有关。
为了能将设计稿中的 px 方便的转换为页面中 rem,我设置 1rem 为 宽度为 750px 的设计稿中的 100px。代码如下:
;(function(win) { var doc = win.document; var docEl = doc.documentElement; var tid; function refreshRem() { var width = docEl.getBoundingClientRect().width; if (width > 540) { // 最大宽度 width = 540; } var rem = width / 7.5; docEl.style.fontSize = rem + 'px'; } win.addEventListener('resize', function() { clearTimeout(tid); tid = setTimeout(refreshRem, 300); }, false); win.addEventListener('pageshow', function(e) { if (e.persisted) { clearTimeout(tid); tid = setTimeout(refreshRem, 300); } }, false); refreshRem();})(window);方法2: 媒体查询(Media Queries)
通过媒体查询,我们对不同设施的特性来应用不同的样式。支持的设施特性包括:设施宽度,设施高度,设施是处于横屏还是竖屏等。写法如下:
/* 括号里的是设施特性。 */@media (max-width: 600px) { /* 设施宽度小于600px时,才左右下面的样式 */ .facet_sidebar { display: none; }}通过媒体查询,给不同的设施宽度设置不同的样式,就能实现元素的宽高和设施的大小有关。如
.tar { width: 110px;}@media (max-width: 600px) { .tar { width: 100px; }}@media (max-width: 500px) { .tar { width: 90px; }}@media (max-width: 500px) { .tar { width: 80px; }}控制元素的大小是离散的,比较糙。
场景06 宽高值是表达式的计算结果
怎样了解:表达式的计算结果?如,我们需要实现,一个元素的高度是:浏览器可视区域高度-10px。浏览器可视区域高度-10px 就是表达式的计算结果。
calc() 允许在公告 CSS 属性值时执行少量计算。语法:
css属性: calc(表达式);实现元素的高度是:浏览器可视区域高度-10px。只需给元素加下面的样式:
height: calc(100vh - 10px);注意:
- 操作符
-的两边必需有空格。 - 表达式只支持 加(+),减(-),乘(*),除(/)操作。
主流浏览器均支持calc()。详细的兼容性情况见Can I use calc。
假如要兼容不支持的浏览器,可以用 js 来实现。如,要设置元素的高度是:比浏览器可视区域小10px。只要在DOM加载好后,执行
document.querySelector('要设置的元素选择器').style.height = `${window.innerHeight - 10}px`位置
场景07 文字的水平对齐
文字的水平左对齐,居中对齐,右对齐。可以用 text-align 来实现。代码如下:
text-align: left; // 左对齐text-align: center; // 居中对齐text-align: right; // 右对齐场景08 文字的垂直居中
单行文本和多行文本的垂直居中的解决方式不一样。
单行文本的垂直居中。只要设置高度等于行高。如
height: 25px;line-height: 25px;多行文本的垂直居中可以用 “场景12 多个元素的垂直居中” 中的方法。
场景09 多个块级元素的在一行或者多行中显示
用 Flex 布局可以实现多个块级元素的在一行或者多行中显示。Flex 布局的 Flex项目,会在一行中显示。多行显示的方法是,在 Flex 容器上设置 flex-wrap: wrap。完整代码:
.container { display: flex; flex-wrap: wrap;}用 inline-block, float 等技术也可以实现多个元素在一行中显示。这边就不详情了。
场景10 多个元素的水平居中
用 Flex 布局可以实现多个元素的水平居中。代码:
.container { display: flex; justify-content: center;}假如是一个固定宽度元素的水平居中,可以用
width: 960px; /* 必需设置 */margin-left: auto;margin-right: auto;场景11 多个元素的水平两端对齐
用 Flex 布局可以实现多个元素的水平两端对齐。代码:
.container { display: flex; justify-content: space-between;}还有2个分配多个元素间的方式,也可以理解下:
justify-content: space-around: 每行上均匀分配弹性元素。相邻元素间距离相同。每行第一个元素到行首的距离和每行最后一个元素到行尾的距离将会是相邻元素之间距离的一半。justify-content: space-evenly: 每行上均匀分配弹性元素。相邻元素间距离,第一个元素距行首的间距,最后一个元素距行尾的间距均相同。注意:IE 不支持该样式。
场景12 多个元素的垂直居中
用 Flex 布局可以实现多个元素的垂直居中。代码:
.container { display: flex; align-items: center;}场景13 元素始终位于父元素右上角
可以用 绝对定位 来实现元素始终位于父元素右上角。
使用绝对定位前,我们要先理解position的知识。 CSS 的position属性用于指定一个元素在文档中的定位方式。top,right,bottom 和 left 属性则决定了该元素的最终位置。常见的定位类型有:
- 定位元素(positioned element)是其position的值不为static的元素。position的默认值为static。
- 相对定位元素(relatively positioned element)是position的值为 relative 的元素。
- 绝对定位元素(absolutely positioned element)是position的值为 absolute 或者 fixed 的元素。
- 粘性定位元素(stickily positioned element)是position的值为 sticky 的元素。
实现元素始终位于父元素右上角的做法:将父元素设置为定位元素,子元素设置为绝对定位元素就可。代码:
HTML:
<div class="container"> <a class="child">关闭按钮</a></div>.container { position: relative;}.child { position: absolute; top: 0; right: 0;}场景14 元素始终位于页面的右下角
可以用 固定定位 来实现元素始终位于页面的右下角。给元素设置样式 position: fixed,来实现固定定位。用 top,right,bottom 和 left 来控制该元素的最终位置。下面代码实现了返回顶部的按钮样式:
HTML:
<a href="javascript:void(0);" class="back-to-top">返回顶部</a>CSS:
.back-to-top { position: fixed; right: calc(50vw - 480px - 100px); /* 480px 是主体内容宽度的一半 ,100px 按钮宽度加修正值。 bottom: 100px;}场景15 绝对定位元素的水平居中
用left和transform可以实现绝对定位元素的水平居中。绝对定位元素水平居中时,距定位元素左侧的值为 50%*定位元素宽度 – 50%*元素宽度。50%*定位元素宽度的值为left: 50%,-50%*元素宽度的值为 transform: translateX(-50%)。如下图所示:
绝对定位元素的水平居中原理
实现代码:
position: absolute;left: 50%;transform: translateX(-50%);场景16 绝对定位元素的垂直居中
该场景和上个场景很相似。用top和transform实现绝对定位元素的垂直居中。实现代码:
position: absolute;top: 50%;transform: translateY(-50%);场景17 文字环绕图片
用浮动(float)可以实现文字环绕图片的效果。
图片在左边,文字在右边。给图片设置 float:left。
图片在左边,文字在右边效果
图片在右边,文字在左边。给图片设置 float:right。
图片在右边,文字在左边
在 IE6 流行的年代,浮动是主流的布局技术。后来 inline-block 成了主流的布局技术。现在,Flex 成了主流布局技术。未来,主流的布局技术会是更强大的 网格(grid) 布局(目前的浏览器兼容性还不好)。各种技术在历史舞台上轮转,一代“新人”换“旧人”,莫名的伤感。。。
总结一下
掌握CSS布局,要掌握以下几点重点:
- boxing-sizing的值为 border-box 和 content-box 对应的空间计算规则是怎么的。
- 给行内元素设置宽高值不会生效。
- 实现单行文字的垂直居中,只要设置高度等于行高。
- 一个固定宽度元素的水平居中,只要设置宽度值和左右margin值为auto。
- Flex布局是目前主流的布局技术。多个元素占一行(或者列)或者多行(或者列),居中对齐,居右对齐,弹性的宽度或者高度。都可以用Flex布局来实现。
- 元素相对父元素定位或者相对页面定位。可以用Position来实现。
- 实现宽高和设施宽度有关。可以用 js 配合 rem 实现。
注
- 注1: 大部分情况之外的情况包括: Flex 布局中,假如项目的的 flex-grow 或者 flex-shirk 的值不为0,则Flex项目的大小不由是CSS设置的width和height决定。
参考&推荐阅读
- Flex 布局教程:语法篇
- 学习CSS布局
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 17个场景,带你入门CSS布局