整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

CSS盒子模型,排版布局的基石

简介

在HTML中,有一个很重要的理论:块元素和行内元素。在CSS中极其重要的一个理论——CSS盒子模型。 在“CSS盒子模型”理论中,页面中的所有元素都可以看成一个盒子,并且占据着一定的页面空间。

一个页面由很多盒子组成,这些盒子之间会互相影响,因此掌握盒子模型需要从两个方面来理解:一是理解单独一个盒子的内部结构(往往是padding),二是理解多个盒子之间的相互关系(往往是margin)。

2 盒子模型概念

盒模型指的是网页元素的结构。当指定一个元素的宽度或高度时,便设置了元素内容的尺寸,可以把每个元素都看成一个盒子,盒子模型是由4个属性组成,号称“盒尺寸四大家族”:

  • content(内容区),可以是文本或图片 —— 变化多端
  • padding(内边距),用于定义内容与边框之间的距离 —— 温和向内
  • margin(外边距),用于定义当前元素与其它元素之间的距离 —— 激进对外
  • border(边框),用于定义元素的边框 —— 功勋卓越

此外,在盒子模型中,还有宽度(width)和高度(height)两大辅助性属性。记住,所有的元素都可以看成一个盒子 。如下图所示:

2.1 内容区

内容区是CSS盒子模型的中心,它呈现了盒子的主要信息内容,这些内容可以是文本、图片等多种类型。内容区是盒子模型必备的组成部分,其他3个部分都是可选的。 内容区有3个属性:width、height和overflow。使用width和height属性可以指定盒子内容区的高度和宽度。在这里注意一点,width和height这两个属性是针对内容区content而言的,并不包括padding部分。 当内容过多,超出width和height时,可以使用overflow属性来指定溢出处理方式。

2.2 内边距

内边距,指的是内容区和边框之间的空间,可以看成是内容区的背景区域。padding属性接受长度值或百分比值,但不允许使用负值。 关于内边距的属性有5种:padding-top、padding-bottom、padding-left、padding-right,以及综合了以上4个方向的简写内边距属性padding。使用这5种属性可以指定内容区与各方向边框之间的距离。

2.2.1 元素的尺寸

因为CSS中默认的box-sizing是content-box,所以使用padding会增加元素的尺寸。

.box {
   width: 80px;   
    padding: 20px;
}

如果不考虑其他CSS干扰,此时.box元素所占据的宽度就应该是120像素(80px+20px×2),这其实是不符合现实世界的认知的,人们总是习惯把代码世界和现实世界做映射,因此,新人难免会在padding的尺寸问题上踩到点坑。这也导致很多人乐此不疲地设置box-sizing 为border-box,甚至全局设置。

2.2.2 标签元素内置的padding

  • ol/ul列表内置padding-left,但是单位是px不是em。
  • 很多表单元素都内置padding。例如:所有浏览器<input>/<textarea>输入框内置padding;所有浏览器<button>按钮内置padding;所有浏览器<radio>/<chexkbox>单复选框无内置padding。

2.3 外边距

外边距,指的是两个盒子之间的距离,它可能是子元素与父元素之间的距离,也可能是兄弟元素之间的距离。外边距使得元素之间不必紧凑地连接在一起,是CSS布局的一个重要手段。 外边距的属性也有5种:margin-top、margin-bottom、margin-left、margin-right,以及综合了以上4个方向的简写外边距属性margin。 同时,CSS允许给外边距属性指定负数值,当外边距为负值时,整个盒子将向指定负值的相反方向移动,以此产生盒子的重叠效果,这就是传说中的“负margin技术”。

2.3.1 margin与元素尺寸

  • 元素的内部尺寸

只有元素是“充分利用可用空间”状态的时候,margin才可以改变元素的可视尺寸。比方说,如下CSS:

.header {
 width: 160px; 
  margin: 0 -5px;
}

此时元素宽度还是160像素,尺寸无变化。因为只要宽度设定,margin就无法改变元素尺寸,这和padding是不一样的。

但是,如果是下面这样的HTML和CSS:

<div class="header">
   <div class="son">
</div></div>
.header { width: 160px; }
.menu { margin: 0 -5px; }

则.menu元素的宽度就是165像素了,尺寸通过负值设置变大了,因为此时的宽度表现是“充分利用可用空间”。

  • 元素的外部尺寸

只要元素具有块状特性,无论有没有设置width/height,无论是水平方向还是垂直方向,即使发生了margin合并,margin对外部尺寸都着着实实发生了影响。

2.3.2 margin合并

块级元素的上外边距(margin-top)与下外边距(margin-bottom)有时会合并为单个外边距,这样的现象称为“margin合并”。

  • margin合并一般出现在以下3种场景:(1)相邻兄弟元素margin合并。这是margin合并中最常见、最基本的。(2)父级和第一个/最后一个子元素。(3)空块级元素的margin合并。
  • margin合并的计算规则把margin合并的计算规则总结为:“正正取大值”, “正负值相加” ,“负负最负值”。
  • margin合并的意义对于兄弟元素的margin合并其作用和em类似,都是让图文信息的排版更加舒服自然。父子margin合并的意义在于:在页面中任何地方嵌套或直接放入任何裸<div>,都不会影响原来的块状布局。<div>是网页布局中非常常用的一个元素,其语义是没有语义,也就是不代表任何特定类型的内容,是一个通用型的具有流体特性的容器,可以用来分组或分隔。由于其作用就是分组的,因此,从行为表现上来看,一个纯粹的<div>元素是不能够也不可以影响原先的布局的。自身margin合并的意义在于可以避免不小心遗落或者生成的空标签影响排版和布局。

2.3.3 margin:auto

margin:auto的填充规则如下。 (1)如果一侧定值,一侧auto,则auto为剩余空间大小。 (2)如果两侧均是auto,则平分剩余空间。

2.4 边框

在CSS盒子模型中,边框与我们之前学过的边框是一样的。 边框属性有border-width、border-style、border-color,以及综合了3类属性的简写边框属性border。

border属性总是能解决很多棘手的问题,在在图形构建、体验优化以及网页布局这块几大放异彩,,同时保证其良好的兼容性和稳定性。下面我们一起看看border都有哪些精彩的特性表现。

2.4.1 为什么border-width不支持百分比值

我们通过比对笔记本、手机发现,虽然两台设备的尺寸差异很大,但是边框的大小相比而言就可以忽略不计了。边框是不会因为设备大就按比例变大的。因此,如果支持百分比值,是不是就意味着设备大了边框也跟着变大?有一张图片,大片区域都是白色的,在白底背景上和文字混在一起,就会有一片奇怪的空白区域,会让人产生没对齐的假象,此时,我们给这张图片套个1px灰色边框,区域就明显了,对吧!设计的初衷就是为了这么点儿事,没有需要使用百分比值的场景。于是,综合这两点,造成了border-width不支持百分比值。

2.4.2 border与图形构建

border属性可以轻松实现兼容性非常好的三角图形效果,为什么可以呢?其底层原因受inset/outset 等看上去没有实用价值的border-style属性影响,边框3D效果在互联网早期其实还是挺潮的,那个时候人们喜欢有质感的东西,为了呈现逼真的3D效果,自然在边框转角的地方一定要等分平滑处理,然后不同的方向赋予不同的颜色。然后,这一转角规则也被solid类型的边框给沿用了。因此,我们就不难理解下面的4色边框的表现了:

div {
   width: 10px; height: 10px;    
    border: 10px solid;    
    border-color: #f30 #00f #396 #0f0;
}

运行一下上面的代码看一下效果吧!

2.4.3 border与透明边框技巧

这是提高用户体验的一个小技巧,尤其在移动端,我们的操作工具一般就是我们的手指,但是,我们的手指粗细可以媲美胡萝卜,而屏幕尺寸就那么点儿,如果我们正在走路,则一些精致的图标和按钮很容易就点不中甚至误点。

稳妥的方法是外部再嵌套一层标签,专门控制点击区域大小。如果对代码要求较高,则可以使用padding或者透明border增加元素的点击区域大小。

3 总结

现实生活中看到的盒子,有正方形、长方形、圆柱形等,依据形状特点,可包裹不同物件。CSS中的盒子虽然没有那么多的形状,但在视觉呈现上不同类型的盒子还是会有很大的不同,有的盒子要占据一行,有的盒子不能定义外边距、宽度和高度,有的盒子宽度和高度能自适应。CSS中用display指定盒类型(即框类型),常用的有 block(块)、inline(行内)、inline-block(行内块)、table(表格),以及CSS3新增的flexbox(伸缩盒)。 HTML 元素只有两种默认的盒类型,即块级元素(block-level element)和行内元素(inline-level element)。其中行内元素不可定义CSS属性width、height、上下margin和上下padding。常用的span和div分别是行内元素和块级元素。

由此可见,需要掌握的内容太多,要想学会所有布局相关的技术不太现实。高级的布局话题基于文档流和盒模型等概念,这些是决定网页元素的大小和位置的基本规则。因此理解和掌握如何设置元素的大小和位置至关重要。

4 最后的最后

为初学者提供学习指南,为从业者提供参考价值。我坚信码农也具有产生洞见的能力。关注【码农洞见】,一起学习和交流吧!

TML

  1. 基本概念

  • HTML 是网页内容的载体。内容就是网页制作者放在页面上想要让用户浏览的信息,可以包含文字、图片、视频等。

  • CSS 样式是表现。比如,标题字体、颜色变化,或为标题加入背景图片、边框等,所有这些用来改变内容外观的东西称之为表现。

  • JavaScript 是用来实现网页上的特效效果。如:鼠标滑过弹出下拉菜单,或鼠标滑过表格的背景颜色改变,还有焦点新闻(新闻图片)的轮换。有动画的,有交互的一般都是用 JavaScript 来实现的。

2.常用标签

  • 强调语气:<em>是斜体,<strong>是加粗

  • 引用:<q>短文本引用,<blockquote>长文本引用

  • 换行 <br />

  • 水平横线 <hr />

  • 空格 &nbsp;

  • 表格 <table><tbody>

  • 加上后表格内容全部下载完才会显示

  • <tr>

  • <td>

  • 表格表头 <th>

  • 标题 <caption>

  • 超链 <a>

  • 例子:<a href="目标网址" title="鼠标滑过显示的文本">链接显示的文本</a>

  • 新标签打开:target="_blank"

  • 图片 <img>,图像可以是 GIF,PNG,JPEG 格式的图像文件

  • 例子:<img src="图片地址" alt="下载失败时的替换文本" title = "提示文本">

  • 表单 <form>

  • 文本域 <textarea>

  • 例子 <textarea rows="行数" cols="列数">文本</textarea>

  • cols 多行输入域的列数;rows 多行输入域的行数。这两个属性可用 CSS 样式的 width 和 height 来代替:col 用 width、row 用 height 来代替

  • 输入框 <input type="text/password" name="名称" value="文本" />

  • 当 type=”text” 时,输入框为文本输入框

  • 当 type=”password” 时, 输入框为密码输入框

  • 单/复选框 <input type="radio/checkbox" value="值" name="名称" checked="checked"/>

  • 当 type=”radio” 时,控件为单选框,同一组单选框 name 命名要一致

  • 当 type=”checkbox” 时,控件为复选框

  • 提交按钮 <input type="submit" value="提交">

  • 重置按钮 <input type="reset" value="重置">

  • 下拉列表框 ` `

  • value <option value="提交值">选项</option>

  • 选中 selected="selected"

  • 多选 multiple="multiple"

  • 标签 <label for="控件id名称">,标签的 for 属性中的值应当与相关控件的 id 属性 值一定要相同

CSS

基本知识

CSS 样式由选择符和声明组成,而声明又由属性和值组成。

  • 选择符:又称选择器,指明网页中要应用样式规则的元素。

  • 声明:在英文大括号{}中的的就是声明,属性和值之间用英文冒号{}分隔。当有多条声明时,中间可以英文分号;分隔。

从CSS 样式代码插入的形式来看基本可以分为以下3种:内联式、嵌入式和外部式三种。优先级遵循就近原则,一般来说,内联式 > 嵌入式 > 外部式

  • 内联式

例子 <p style="color:red;font-size:12px">这里文字是红色。</p>

  • 嵌入式

  • 外部式

例子:<link href="base.css" rel="stylesheet" type="text/css" />

CSS 选择器

常见的类选择器类型有如下几种:

  • 标签选择器,.标签选择器名称{css样式代码;}

  • 类选择器,.类选器名称{css样式代码;}

  • ID 选择器,#类选器名称{css样式代码;}

  • 子选择器,即大于符号(>),用于选择指定标签元素的第一代子元素

  • 包含选择器,即加入空格 ,用于选择指定标签元素下的后辈元素

  • 通用选择器,匹配html中所有标签元素,* {css样式代码;}类选择器和ID选择器都可以应用于任何元素,但 ID 选择器只能在文档中使用一次,可以使用类选择器词列表方法为一个元素同时设置多个样式,ID 选择器是不可以的。

子选择器和包含选择器区别:>作用于元素的第一代后代,空格作用于元素的所有后代。

另外还有两种选择符:

  • 伪类选择符,允许给 HTML 不存在的标签(标签的某种状态)设置样式。常用的有 a:hover{color:red;}

  • 分组选择符,为 HTML 中多个标签元素设置同一个样式时,可以使用分组选择符,

。例如h1,span{color:red;}

CSS 的继承、层叠和特殊性

  • CSS 的某些样式是具有继承性的,继承是一种规则,它允许样式不仅应用于某个特定 HTML 标签元素,而且应用于其后代。

  • 特殊性:不同选择器具有不同权值,标签的权值为 1,类选择符的权值为 10,ID选择符的权值最高为 100。

  • 层叠 就是在 HTML 文件中对于同一个元素可以有多个 CSS 样式存在,当有相同权重的样式存在时,会根据这些 CSS 样式的前后顺序来决定,处于最后面的 CSS 样式会被应用。

CSS 格式化排版

文字排版

  • 字体,body{font-family:"Microsoft Yahei";}

  • 字号、颜色,body{font-size:12px;color:#666}

  • 粗体,body{font-weight:bold;}

  • 斜体,body{font-style:italic;}

  • 下划线,body{font-style:italic;}

  • 删除线,body{text-decoration:line-through;}

段落排版

  • 缩进,p{text-indent:2em;}

  • 行间距(行高),p{line-height:1.5em;}

  • 中文字间距、字母间距,letter-spacing:50px;word-spacing:50px;

  • 对齐,div{text-align:center;}

CSS 盒模型

元素分类

在 CSS 中,HTML 中的标签元素大体被分为三种不同的类型:块状元素、内联元素(又叫行内元素)和内联块状元素。

  • 常用的块状元素有:

块级元素特点:

  1. 每个块级元素都从新的一行开始,并且其后的元素也另起一行。

  2. 元素的高度、宽度、行高以及顶和底边距都可设置。

  3. 元素宽度在不设置的情况下,是它本身父容器的 100%(和父元素的宽度一致),除非设定一个宽度。

设置 display:block就是将元素显示为块级元素,从而使元素具有块状元素特点。

注:img 标签与 div 层之间会有空隙的解决方法是:使用 display:block 就可以消除间隙。

  • 常用的内联元素有:

内联元素特点:

  1. 和其他元素都在一行上;

  2. 元素的高度、宽度及顶部和底部边距不可设置;

  3. 元素的宽度就是它包含的文字或图片的宽度,不可改变。

块状元素也可以通过代码 display:inline将元素设置为内联元素。

  • 常用的内联块状元素有:

inline-block 元素特点:

  1. 和其他元素都在一行上;

  2. 元素的高度、宽度、行高以及顶和底边距都可设置。

内联块状元素(inline-block)就是同时具备内联元素、块状元素的特点,代码 display:inline-block就是将元素设置为内联块状元素。

盒模型

  • 边框

盒子模型的边框就是围绕着内容补白的线,这条线你可以设置它的粗细样式颜色(边框三个属性)。

单独设置下边框的例子 div{border-bottom:1px solid red;}

  • 宽度和高度

CSS 内定义的宽(width)和高(height),指的是 填充以里的内容范围。一个元素实际宽度(盒子的宽度)=左边界+左边框+左填充+内容宽度+右填充+右边框+右边界。

W3C 的标准 Box Model:

所以有时会设置 box-sizing: border-box;来避免计算内部元素大小

  • 填充(padding)

元素内容与边框之间是可以设置距离的,称之为“填充”。填充也可分为上、右、下、左(顺时针)。

例子:

  • 边界(margin)

元素与其它元素之间的距离可以使用边界(margin)来设置,顺序和填充一样是上,右,下,左。padding 在边框里,margin 在边框外。

CSS 布局模型

CSS 包含 3 种基本的布局模型,用英文概括为:Flow、Layer 和 Float。 在网页中,元素有三种布局模型:

  1. 流动模型(Flow)

  2. 浮动模型 (Float)

  3. 层模型(Layer)

流动模型

流动模型,流动(Flow)是默认的网页布局模式。

流动布局模型具有2个比较典型的特征:

  1. 块状元素 都会在所处的包含元素内自上而下按顺序垂直延伸分布,因为在默认状态下,块状元素的宽度都为 100%。实际上,块状元素都会以行的形式占据位置。

  2. 在流动模型下,内联元素 都会在所处的包含元素内从左到右水平分布显示。

浮动模型

任何元素在默认情况下是不能浮动的,但可以用 CSS 定义为浮动。例子:#div1{float:left;}

层模型

CSS 定义了一组定位(positioning)属性来支持层布局模型。

层模型有三种形式:

  1. 绝对定位(position: absolute)

  2. 相对定位(position: relative)

  3. 固定定位(position: fixed)

  • 绝对定位(position: absolute)

如果想为元素设置层模型中的绝对定位,需要设置 position:absolute(表示绝对定位),这条语句的作用将元素从文档流中拖出来,然后使用 left、right、top、bottom 属性相对于其最接近的一个具有定位属性的父包含块进行绝对定位。如果不存在这样的包含块,则相对于 body 元素,即相对于浏览器窗口

  • 相对定位(position: relative)

如果想为元素设置层模型中的相对定位,需要设置 position:relative(表示相对定位),它通过 left、right、top、bottom 属性确定元素在正常文档流中的偏移位置。相对定位完成的过程是首先按 static(float) 方式生成一个元素(并且元素像层一样浮动了起来),然后相对于以前的位置移动,移动的方向和幅度由left、right、top、bottom属性确定,偏移前的位置保留不动

简单来说,就是相对元素原来的位置进行移动,元素本身所占的位置会保留。

  • 固定定位(position: fixed)

设置 position:fixed;。fixed:表示固定定位,与 absolute 定位类型类似,但它的相对移动的坐标是视图(屏幕内的网页窗口)本身。由于视图本身是固定的,它不会随浏览器窗口的滚动条滚动而变化,除非你在屏幕中移动浏览器窗口的屏幕位置,或改变浏览器窗口的显示大小,因此固定定位的元素会始终位于浏览器窗口内视图的某个位置,不会受文档流动影响,这与 background-attachment:fixed; 属性功能相同。

Relative 与 Absolute 组合使用,必须遵守下面规范:

  1. 参照定位的元素必须是相对定位元素的前辈元素

  2. 参照定位的元素必须加入 position:relative;

  3. 定位元素加入 position:absolute,便可以使用 top、bottom、left、right 来进行偏移定位了

例子(HTML 和 CSS 代码分别为):

颜色和长度

设置颜色的方法也有很多种:

  • 英文命令颜色,p{color:red;}

  • RGB颜色,p{color:rgb(133,45,200);}p{color:rgb(20%,33%,25%);}

  • 十六进制颜色, 这种颜色设置方法是现在比较普遍使用的方法,其原理其实也是 RGB 设置,但是其每一项的值由 0-255 变成了十六进制 00-ff。p{color:#00ffff;}(当你设置的颜色是 16 进制的色彩值时,如果每两位的值相同,可以缩写一半,#0ff)RGB 配色表参考 RGB颜色对照表 - 在线工具 - 开源中国 或者 RGB 配色表长度单位总结一下,目前比较常用到px(像素)、em、% 百分比,要注意其实这三种单位都是相对单位。

  • 像素

  • em,就是本元素给定字体的 font-size 值

  • % 百分比

设置小技巧

水平居中设置

  • 行内元素。如果被设置元素为文本、图片等行内元素时,水平居中是通过给父元素设置 text-align:center来实现的。

  • 定宽块状元素(块状元素的宽度 width 为固定值)。满足定宽块状两个条件的元素是可以通过设置“左右 margin”值为 auto 来实现居中的。

  • 不定宽块状元素。

  • 加入 table 标签(包括 <tbody>、<tr>、<td>),为这个 table 设置“左右 margin 居中”

  • 设置 display: inline方法:与第一种类似,显示类型设为 行内元素,然后使用 text-align:center来实现居中效果,进行不定宽元素的属性设置。

  • 给父元素设置 float 和 position:relative; left:50%,子元素设置 position:relativeleft: -50% 来实现水平居中。

垂直居中设置

  • 父元素高度确定的单行文本。通过设置父元素的 height 和 line-height 高度一致来实现的。(height: 该元素的高度;line-height: 顾名思义,行高(行间距),指在文本中,行与行之间的 基线间的距离 )。

  • 父元素高度确定的多行文本。使用插入 table (包括 tbody、tr、td)标签,同时设置 vertical-align:middle

另外,为元素设置以下两个属性之一会隐形改变 display 类型,元素的display显示类型就会自动变为以display:inline-block(块状元素)的方式显示,当然就可以设置元素的 width 和 height 了,且默认宽度不占满父元素。

position: absolute

float: leftfloat:right

近忙里偷闲,给自己加油充电的时候,发现自己脑海中布局这块非常的凌乱混杂,于是花了一些时间将一些常用的布局及其实现方法整理梳理了出来,在这里,分享给大家。

单列布局

单列布局是最常用的一种布局,一般是将一个元素作为容器,设置一个固定的宽度,水平居中对齐。

单列布局一般有两种形式:



(图片来源:https://blog.csdn.net/Ace_Arm/article/details/81036129)

一栏布局

一栏布局头部、内容、底部宽度一致

效果图


代码实现

html

<header></header>
<main></main>
<footer></footer>
复制代码

css

header,footer{
    width: 1200px;
    height: 100px;
    margin: 0 auto;
    background: black;
}
main{
    width: 1200px;
    height: 600px;
    background: red;
    margin: 0 auto;
}
复制代码

一栏布局(通栏)

一栏布局(通栏)头部和底部宽度一致,占满整个页面,中间内容区域宽度较小不占满屏幕。

效果图

代码实现

html

<header></header>
<main></main>
<footer></footer>
复制代码

css

header,footer{
    width: 100%;
    height: 100px;
    background: black;
}
main{
    width: 1200px;
    height: 600px;
    background: red;
    margin: 0 auto;
}
复制代码

单列布局是最为基础和简单的一种,实现方法并不局限于以上两种,大家可自由发挥,找到更多的方法来实现。

2列布局

2列布局的使用频率也非常高,其实现效果主要就是将页面分割成左右宽度不等的两列。一般宽度较小的一列会设置为固定宽度,作为侧边栏之类的,而另一列则充满剩余宽度,作为内容区。

在后台管理系统及api文档中使用较为广泛。

效果图

先来看看效果:

代码实现

实现两列布局的方法有很多,这里主要介绍两种方法。

calc函数

calc() 函数用于动态计算长度值。实现思路很简单,侧边栏宽度固定,设置绝对定位,使其脱离文档流,内容区域通过calc()函数计算剩余宽度并设置宽度,再加一个margin-left,值为侧边栏的宽度。

代码如下:

html

<div class="slider"></div>
<div class="main"></div>
复制代码

css

*{
    margin: 0;
    padding: 0;
}
body,html{
    width: 100%;
    height: 100%;
}
.slider,.main{
    height: 100%;
}
.slider{
    position: absolute;
    left: 0;
    top: 0;
    width: 100px;
    background: black;
}
.main{
    width: calc(100% - 100px);
    background: red;
    margin-left: 100px;
}
复制代码

flex属性

通过flex属性实现思路也很简单,将父元素设置为flex,侧边栏宽度固定,内容区域设置flex:1即可充满剩余区域。

代码如下:

html

<div class="slider"></div>
<div class="main"></div>
复制代码

css

*{
    margin: 0;
    padding: 0;
}
body,html{
    width: 100%;
    height: 100%;
}
body{
    display: flex;
}
.slider,.main{
    height: 100%;
}
.slider{
    width: 100px;
    background: black;
}
.main{
    flex: 1;   
    background: red;
}
复制代码

3列布局

3 列布局在日常开发中使用频率也是很高的,其按照左中右的顺序进行排列,通常中间列最宽,左右两列次之。左右两边定宽,中间自适应,能根据屏幕大小做响应。

效果图

还是先来看看效果图

代码实现

三列布局的实现方法也很多,这里主要介绍两种(双飞翼布局、圣杯布局、flex布局)

在介绍双飞翼布局和圣杯布局之前要先说一下margin设置负值的作用:

当margin的值设为负值的时候,元素会对应的像那个放向移动,比如margin-left为负值,元素则会左移

双飞翼布局

代码如下:

html

<div class="main">
    <div class="middle">
        <div class="content">
            中间
        </div>
    </div>
    <div class="left">
        左边
    </div>
    <div class="right">
        右边
    </div>
</div>
复制代码

css

* {
    margin: 0;
    padding: 0;
}

body,
html {
    width: 100%;
    height: 100%;
}
div{
    height: 100%;
}
.main>div {
    float: left;
}

.left {
    width: 200px;
    background: red;
    margin-left: -100%;
}

.right {
    width: 200px;
    background: blue;
    margin-left: -200px;
}

.middle {
    width: 100%;
    background: yellow;

}

.content {
    margin-left: 200px;
    margin-right: 200px;
}
复制代码

圣杯布局

代码如下: html

<div class="main">
    <div class="center">中间中间中间中间中间中间中间后</div>
    <div class="left">左边</div>
    <div class="right">右边</div>
</div>
复制代码

css

* {
    margin: 0;
    padding: 0;
}

.main {
    height: 200px;
    padding: 0 150px 0 200px;
    background: greenyellow;
    *zoom: 1;
}

.left,
.center,
.right {
    float: left;
}

.center {
    width: 100%;
    height: 200px;
    background: red;
}

.left {
    width: 200px;
    height: 200px;
    background: yellow;
    margin-left: -100%;
    position: relative;
    left: -200px;
}

.right {
    width: 150px;
    height: 200px;
    background: gainsboro;
    margin-left: -150px;
    position: relative;
    left: 150px;
}
复制代码

双飞翼布局其实和圣杯布局的精髓是一样的,都是通过设置负margin来实现元素的排布,不同的就是html结构,双飞翼是在center元素内部又设置了一层inner-center的元素并设置它的左右margin,而非圣杯布局的padding,来排除两边元素的覆盖。所以这两种布局原理基本一样,关键就是在于设置负margin的技巧,和元素浮动的相对定位技巧来实现。

flex布局

代码如下: html

<div class="main">
    <div id="left">左边定宽</div>
    <div id="main">中间自适应</div>
    <div id="right">右边定宽</div>
</div>
复制代码

css

* {
    padding: 0px;
    margin: 0px;
}
body,html{
    width: 100%;
    height: 100%;
}
body{
    display: flex;
}

#left,
#right {
    width: 100px;
    background-color: #0FC;
}
#main {
    flex: 1;
    background-color: #999;
}
复制代码

如果不考虑浏览器兼容问题的话,运用flex布局是最简单的方式。

垂直方向的布局(sticky footer)

这种布局将页面分成上、中、下三个部分,上、下部分都为固定高度,中间部分高度不定。当页面高度小于浏览器高度时,下部分应固定在屏幕底部;当页面高度超出浏览器高度时,下部分应该随中间部分被撑开,显示在页面最底部。

这种布局也称之为sticky footer,意思是下部分粘黏在屏幕底部。

代码实现

首先我们先构建简单的HTML代码

<body>
  <div class="content"></div>
  <div class="footer"></div>
</body>
复制代码

其中content为我们的内容区。下面开始介绍解决方法。

为内容区域添加最小的高度

这种方法重要用vh(viewpoint height)来计算整体视窗的高度(1vh等于视窗高度的1%),然后减去底部footer的高度,从而求得内容区域的最小高度。例如我们可以添加如下样式:

.content{
     min-height:calc(100vh-footer的高度);
     box-sizing:border-box;
}  
复制代码

从而这个问题就解决了,但是如果页面的footer高度不同怎么办?每一个页面都要重新计算一次,这是很麻烦的,所以这种方法虽然简单但却是不推荐的。

使用flex布局

这种方法就是利用flex布局对视窗高度进行分割。footer的flex设为0,这样footer获得其固有的高度;content的flex设为1,这样它会充满除去footer的其他部分。

代码如下:

body { 
    display: flex; 
    flex-flow: column; 
    min-height: 100vh;
 }
 .content {
    flex: 1; 
}
.footer{
    flex: 0;      
}
复制代码

这样的布局简单使用,比较推荐。

在content的外面可以添加一个wrapper

这种方法就是在content的外面添加一个包裹容易,将html代码改成这样:

<body>
    <div class="wrapper">
        <div class="content"></div>
    </div> 
  <div class="footer"></div>
</body>
复制代码

然后添加以下样式:

html, body, .wrapper {
     height: 100%;
}
body > .wrapper {
     height: auto; 
     min-height: 100%;
}
.content {
    padding-bottom: 150px; /* 必须使用和footer相同的高度 */
}  
.footer {
    position: relative;
    margin-top: -150px; /* footer高度的负值 */
    height: 150px;
    clear:both;
}
复制代码

另外,为了保证兼容性,需要在wrapper上添加clearfix类。其代码如下:

<body>
    <div class="wrapper clearfix">
        <div class="content"></div>
    </div> 
  <div class="footer"></div>
</body>
复制代码
.clearfix{
     display: inline-block;
}
.clearfix:after {
     content: ".";
     display: block;
     height: 0;
     clear: both;
     visibility: hidden;
}    
复制代码

ok,好,完成了,这种方法也比较推荐,但就是加入的代码比较多,也改变了html的文档结构。

粘性布局(sticky)

粘性布局是什么呢?我们先来看看效果演示

没错,其实就是在页面滚动的时候保持元素(这里的是标题)在页面视图上方,也就是我们常常看到的 吸附效果。

标题行设置了背景色。如果不设置背景色(背景透明),正常文档流的文字就会和标题行文字重叠在一起显示。

sticky定位的元素会遮住滚动而来的“正常”的文档流;后面的sticky元素会覆盖前面的sticky元素,就好像一层层的便利贴,是不是很酷~~。

代码实现

实现粘性布局主要依靠position的sticky属性。

position: sticky;
复制代码

先来看看兼容性:



从Can I use上查询可以看出,sticky的兼容性并不是太好,所以大家使用的时候要慎重考虑,如果不要求兼容的情况,用这个还是相当的舒服了。

下面给出一个简单的示例。

html:

<main>
    <header>标题一</header>
    <div class="content">
    </div>
    <header>标题二</header>
    <div class="content">
    </div>
    <header>标题三</header>
    <div class="content">
    </div>
    <header>标题四</header>
    <div class="content">
    </div>
</main>
复制代码

js(不想写太多p标签,所以用js生成,偷个懒):

let num = 20
let html = ''
for (var i = 0; i < num; i++) {
    html += `<p>${i + 1}</p>`
}
Array.prototype.slice.call(document.getElementsByClassName('content')).forEach(item=>{
    item.innerHTML = html
})
复制代码

css:

main {
    width: 400px;
    height: 300px;
    margin: 200px auto;
    overflow: auto;
}
header {
    position: sticky;
    top: 0;
    height: 30px;
    background-color: blanchedalmond;
}
复制代码


作者:monkeysoft
链接:https://juejin.cn/post/6907027007318687751
来源:掘金