在css知识体系中,除了css选择器,样式属性等基础知识外,css布局相关的知识才是css比较核心和重要的点。今天咱们来深刻学习一下css布局相关的知识。
盒模型css
- IE盒模型
- W3C盒模型
- box-sizing
元素的分类html
- 块级元素
- 行内元素
- 行内块级元素
- 行框
定位与浮动前端
- 文档流
- 包含块
- 浮动清除
- margin问题
**格式化上下文(formatting context)css3
- BFC、IFC、FFC、GFC
常见布局实战浏览器
- 水平垂直居中
- 两栏 & 三栏布局
- ...
1.1 IE盒模型与W3C盒模型
首先你们都知道一个页面是由众多HTML元素组成的,每个元素都有本身的一个矩形的显示区域,这就是咱们平时常常说起的css盒模型。微信
这个盒模型或者说这个矩形的显示区域呢 就是向下面这张图同样,包括四部分:布局
margin(外边距)+border(边框)+padding(内边距)+content(内容)
在css的发展历程中,有两种版本的盒模型,一个叫IE盒模型
(又叫怪异盒模型),一个叫W3C标准盒模型
,在早期的微软出的IE浏览器中采用的是本身的盒模型标准成为IE盒模型或者叫怪异盒模型。学习
规定:元素width和height属性是包含元素的border(边框)+padding(内边距)+content(内容)的。
然后来W3C组织(中文叫作万维网联盟,是一家中立性的技术标准指定机构),一个专门制定互联网技术标准的机构,为了标准化前端的技术规范,他规定了个标准称为W3C标准盒模型。字体
规定:元素width和height属性只包含元素的content(内容)。
后来微软也慢慢转向了W3C的标准,在IE6之后支持了W3C标准盒模型。在咱们如今的主流浏览器里面默认都是使用w3c标准盒模型。flex
咱们来看下面这张图
在图的上半部分中展现的W3C盒模型标准,好比我声明一个div的width属性为100px,那我只是规定了这个div的content内容显示区域的大小为100px,若是以后我再声明div的padding为10px, border为15px solid black, 那么这个div最终的总体宽度就会变成 100 + 10 * 2 + 15 * 2 = 150px
了。
而若是一样的css运用到了IE盒模型身上那么当我规定div的width属性为100px时,他总体的宽度就已经肯定了,就是100px,再以后我去声明div的padding为10px,border为15px solid black,也不会影响我这个div的总体宽度,只是会压缩这个div的content内容显示区域的大小。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> #div1{ width: 100px; height: 100px; padding: 10px; border: 15px solid black; } /* 在W3C盒模型下 #div的总体宽度是150px; 在IE盒模型下 #div的总体宽度是100px; */ </style> </head> <body> <div id="div1"></div> </body> </html>
1.2 box-sizing
box-sizing干吗用的?
咱们刚在说道目前主流浏览器默认都是采用W3C盒模型,若是你就是想在这些浏览器里使用IE盒模型呢?你就须要使用box-sizing这个属性,这是个css3中新出的属性:默认值是content-box就是指的使用W3C盒模型标准,另一个值是border-box,指的就是我要在这个元素上使用IE盒模型标准。
#div1 { box-sizing: border-box || content-box(默认值) }
那么这里就有个问题了,为啥W3C组织好不容易将IE盒模型摒弃调,统一了前端这个盒模型标准并且全部浏览器厂商也都默认支持了,如今反而在css3中加入了box-sizing属性让咱们能够自由选择盒模型标准了呢?
答案就是W3C忽然发如今某些状况下,IE盒模型比本身家的那个盒模型标准更好用。 =。=...(这就很尴尬了...) 因而在css3中加入了box-sizing这个属性让开发者能够自由选择要使用哪一种标准(估计是被喷惨了...)
咱们来看这样一个例子:若是如今咱们要实现这样一个简单布局,我要一个div的总体宽度是页面的50%,而且呢这个div还带有一个10px的边框。咱们要怎么作呢?
若是咱们用IE盒模型标准的话就很简单
div{ width: 50%; border: 10px solid black; box-sizing: border-box; /* 设置为IE盒模型标准 */ }
就能够了 是吧。
那么若是咱们使用W3C盒模型呢。
咱们知道若是咱们声明这个div宽度为50%,而后声明border为10px的话 那么这个div实际宽度应该是50% + 20px
对吧 因此这样不符合咱们的要求,那么要怎么作呢。
有2种方法。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> #div1{ width: 50%; } #div1{ border: 10px solid black; } </style> </head> <body> <div id="div1"> <div id="div2"></div> </div> </body> </html>
50% - 20px
,可是这个属性兼容性通常。代码以下div{ width: calc(50% - 20px); border: 10px solid black; }
....显然,IE盒模型的实现方案更加简洁和直观。后来W3C也意识到了这个问题 因而为了从新支持IE盒模型,W3C组织在CSS3中添加了box-sizing属性,用于让开发者能够随意切换这两种盒模型。
2.1 块级元素 & 行内元素 & 行内块级元素
元素除了本身的盒模型外还有本身的分类。从元素的布局特性来分,主要能够分为三类元素:块级元素
,行内元素
,行内块级元素
。
咱们如今看下他们的定义:
块级元素:display属性取block、table、flex、grid和list-item的元素。
行内级元素:display属性取inline的元素。
行内块级元素:display属性取inline-block、inline-table、inline-flex和inline-grid的元素
不少网上或者书上说: div是个块级元素,span是个行内元素。这样的说法是不正确的,或者说是不严谨的。咱们只能说div默认是个块级元素,span默认是个行内元素。就是由于每一个元素初始都会带有一些样式属性,而div默认的display是block,span的display是inline。可是若是咱们在css中去设置他们的display属性就能够改变他们的类型。
接下来咱们看看他们都有什么特色,很简单
块级元素
- 独占一行显示(width默认为100%,height为0);
- 能够设置尺寸属性(width、height等);
行内元素
- 一行能够显示多个;
- 不能设置宽高或者说设置的width,height无效;
- 受父元素的text-align属性和自身vertical-align属性的控制,在水平方向上默认左对齐,在垂直方向上默认在行框的baseline基线上显示(“行框”的概念,会在后面深刻讲解)
行内块级元素( 结合了块级元素和行内元素的特征 )
- 一行能够显示多个;
- 能够设置尺寸属性(width、height等);
- 受父元素的text-align属性和自身vertical-align属性的控制
对于块级元素很简单,没有什么可说的。就是一点,不管咱们把块级元素的宽度设置多小,他们也只能在一行里单独显示,而不会跟这个元素的兄弟元素在同一行显现。
对于行内或者行内块级元素来讲,有个小注意点。当有多个这样的元素并排排列时 你会发现他们之间是有几像素的间距
的,咱们来看下面的代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> span{ background: blue; } </style> </head> <body> <div> <span>LearnInPro1</span> <span>LearnInPro2</span> <span>LearnInPro3</span> </div> </body> </html>
咱们会发现 他们之间会有间距 像这样:
这是因为咱们为了代码的整洁和直观,通常把每一个标签在单独一行里书写,这样就形成了,标签之间会存在换行符,在渲染过程当中,渲染引擎会认为换行符是一种文本,因此致使了咱们每一个span之间就跟存在着一个空格同样。
那么咱们这里介绍两个方法来消除这个间距
<div> <span>LearnInPro1</span><span>LearnInPro2</span><span>LearnInPro3</span> </div>
注意:因为font-size属性是一个可继承属性,因此在div上将font-size设为0后还须要再span上把font-size设回来,不然span里的文本的font-size也会变成0。像这样:
div { font-size: 0; } span{ font-size: 16px; background: blue; }
2.2 行框
关于元素分类,咱们再来说一个概念,叫作行框
。
咱们如今看下行框的概念:子元素的虚拟矩形区域,造成的每一行。这个概念有点抽象,咱们结合下面这张图来理解下。
咱们能够看到,
- 当行内元素或者行内块级元素并排排列的时候,可能他们的字体大小,高度都是不同的。那么行框就是包裹他们的一个框。就是图中Line box所指的区域。
- 行框规定了这些元素排列时候的对齐方式。默认他们的对齐方式是根据baseline基准线对齐。就如同图上的对齐方式同样。
- 在行框中,咱们利用vertical-align来改变他们的对齐方式。他的值有不少,经常使用的有top,middle,bottom等,这个比较简单就很少介绍了。
要特别注意的点有两个
首先,文本的高度是跟line-height无关的。咱们能够给span设置一个背景色,而后咱们改变他的line-height会发现,不管line-height设置成多高,span的背景色的高度都不会改变,可是span总体的高度会随line-height的增大而变高。因此说文本的高度是跟line-height无关的(注意这里说的是文本)。
- 那么,文本的高度只跟font-size有关,可是注意,文本的高度永远会大于font-size的值,就像下面这张图。font-size的大小只是规定了text-top到text-bottom的距离,而文本高度是top到bottom的距离,而这之间的距离是多少,每一个浏览器都不太同样。总之是为了保护文本,不但愿行与行之间产生重叠。( 若是你强行将line-height设置的特别小,但愿产生重叠,在大部分现代浏览器中是无效的,也就是在大部分浏览器中line-height的值最小等于文本的高度,因此不建议将line-height设的比文本高度小。 )
- 因此,行内元素的高度(不折行的状况下)当没设置line-height或者line-height小于等于文本的内容高度时,行内元素高度取决于font-size,等于文本的高度。 当line-height大于文本高度时,则由line-height决定。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> *{ margin: 0; padding: 0; } span{ background: blue; font-size: 20px; } .inline-block{ height: 100px; width: 100px; background: red; display: inline-block; } </style> </head> <body> <div style="background: gray;"> <span>LearnInPro</span> <div class="inline-block"></div> </div> </body> </html>
就会变成下图这样
咱们前面说过 这两个元素中间的空隙是因为换行符致使的,而且也介绍了解决方案,而此次要说的是这个红色的行内块级元素下方的空隙,这个就是因为行框默认的对齐方式致使的。因为行框默认是baseline对齐,行内块级元素也要遵照因此这个红框的底部会骑在baseline线上。致使baseline到bottom的区域空着,产生空隙。那么解决方案也很简单,只要改变行框的对齐方式,在这两个元素上都加上vertical-align: top || middle || bottom
等就能够把这个空隙消除掉。
因为css布局相关知识,比较重要,知识点也比较多。咱们下篇文章再来介绍其余的知识点。
最后你以为咱们的文章对你有帮助,欢迎关注咱们的
微信公众号LearnInPro,在上面你能够第一时间获取到咱们的技术文章,而且你能够随时在上面向咱们提问,把你在学习前端过程当中所遇到的问题发给咱们。咱们天天都会按时回复你们的每个问题,但愿
LearnInPro
能够伴随你从入门到专家。