深入css布局(1)—— 盒模型 & 元素分类

    “ 在css知识体系中,除了css选择器,样式属性等基础知识外,css布局相关的知识才是css比较核心和重要的点。今天我们来深入学习一下css布局相关的知识。”

首先来列下大纲

  • 盒模型

    • IE盒模型
    • W3C盒模型
    • box-sizing
  • 元素的分类
    • 块级元素
    • 行内元素
    • 行内块级元素
    • 行框
  • 定位与浮动
    • 文档流
    • 包含块
    • 浮动清除
  • margin问题
  • 格式化上下文(formatting context)
    • BFC、IFC、FFC、GFC
  • 常见布局实战
    • 水平垂直居中
    • 两栏 & 三栏布局

一、css盒模型

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标准盒模型。

我们来看下面这张图

在图的上半部分中展示的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种方法。

  • 再包裹一层div,让外层div宽度为50%,然后让内层div有一个10px边框,由于内层div没有是个块级元素所以宽度会默认撑满父元素。代码如下
<!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>
  • 另一种方法是使用css3的计算属性calc(),将div的宽度设为

    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属性就可以改变他们的类型。

接下来我们看看他们都有什么特点,很简单

块级元素

  1. 独占一行显示(width默认为100%,height为0);
  2. 可以设置尺寸属性(width、height等);

行内元素

  1. 一行可以显示多个;
  2. 不能设置宽高或者说设置的width,height无效;
  3. 受父元素的text-align属性和自身vertical-align属性的控制,在水平方向上默认左对齐,在垂直方向上默认在行框的baseline基线上显示(“行框”的概念,会在后面深入讲解)

行内块级元素( 结合了块级元素和行内元素的特征 )

  1. 一行可以显示多个;
  2. 可以设置尺寸属性(width、height等);
  3. 受父元素的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之间就跟存在着一个空格一样。

那么我们这里介绍两个方法来消除这个间距

  1. 很简单,我们直接把span在一行里书写就好了,像这样:
<div><span>LearnInPro1</span><span>LearnInPro2</span><span>LearnInPro3</span>
</div>
  1. 由于渲染引擎认为换行符是一种文本,那我把文本的font-size设为0不就可以了么。
注意:由于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等,这个比较简单就不多介绍了。

要特别注意的点有两个

  1. 我们说过行内元素是不能设置高度的,那么他的高度是如何决定的呢? 任何一个行内元素,他的高度是由font-size和line-height共同决定的。
  • 首先,文本的高度是跟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决定。

 2. 当行内元素和行内块级元素在一个行框内排列的时候,比如:

<!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

可以伴随你从入门到专家。

深入css布局 (1) — 盒模型 元素分类相关推荐

  1. CSS 基础框盒模型介绍

    当对一个文档进行布局(lay out)的时候,浏览器的渲染引擎会根据标准之一的 CSS 基础框盒模型(CSS basic box model),将所有元素表示为一个个矩形的盒子(box).CSS 决定 ...

  2. CSS 学习笔记 - 盒模型

    CSS学习笔记 - 盒模型 外边距margin 内边距padding 背景background 背景图background-image 边框border 样式 宽度 颜色 圆角 边框图片border- ...

  3. CSS之布局(盒模型)

    盒模型: <!DOCTYPE html> <html><head><meta charset="UTF-8"><title&g ...

  4. CSS布局(二) 盒子模型属性

    盒子模型的属性 宽高width/height 在CSS中,可以对任何块级元素设置显式高度. 如果指定高度大于显示内容所需高度,多余的高度会产生一个视觉效果,就好像有额外的内边距一样: 如果指定高度小于 ...

  5. CSS基础必备盒模型及清除浮动

    盒模型 盒模型是有两种标准的,一个是标准模型,一个是IE模型. css如何设置两种模型 这里用到了CSS3 的属性 box-sizing /* 标准模型 */ box-sizing:content-b ...

  6. css --- [读书笔记] 盒模型(边框、内外边距)

    说明 源代码 学习 盒子模型(css重点) css学习三大重点: css盒子模型. 浮动. 定位 目标: 能说出盒子模型由哪四部分组成: 内容.边框.内外边距 能说出内边距的作用,设置不同数值分别代表 ...

  7. (10)CSS 常用样式--盒模型扩展应用

    一.清除默认样式 大部分标签都有一个浏览器加载的默认样式,会对布局造成一些影响.为了避免默认样式对整体布局效果造成影响,一定要清除默认样式. 盒模型属性中内外边距:大部分容器级标签都有默认边距,要么用 ...

  8. CSS基础(二)--盒模型与浮动

    盒模型 认识width和height 一个盒子中主要的属性有5个:width.height.padding.border.margin. width是"宽度"的意思,CSS中wid ...

  9. 前端笔记之移动端响应式(中)视口百分比布局弹性盒模型remfillpage

    一.viewport视口 1.1什么是屏幕尺寸.屏幕分辨率.屏幕像素密度? 屏幕尺寸:指屏幕的对角线的长度,单位是英寸,常见的屏幕尺寸有3.5.3.7.4.2.4.7.5.0.5.5.6.0等. 屏幕 ...

最新文章

  1. SAP MM 103 + 105 移动类型组合初探
  2. android sina oauth2.0 code认证,Android通过第三方登录理解oauth2.0机制
  3. mysql 垂直拆分 原因_mysql的水平拆分和垂直拆分 (转)
  4. 树莓派和windows的FileZillla文件共享,补充:树莓派图形Xrdp界面登录
  5. iOS --高仿QQ空间页面
  6. 2018年自然语言处理最值得关注的研究、论文和代码
  7. 漫步数学分析番外六(上)
  8. 补习系列(21)-SpringBoot初始化之7招式
  9. oracle日期的sql,Oracle中一些和日期有关的SQL查询
  10. oj2894(贝尔曼福特模板)
  11. 数据分析师,数据挖掘工程师和数据研发工程师有什么区别?
  12. GBASE应用 | “天擎”出鞘 GBase 8a助力气象行业进入大数据时代
  13. FOJ1303——Calendar
  14. [IDE]vs code更新后变成英文版
  15. 这是我见过最牛逼的滑动加载前端框架
  16. JS验证邮箱合理性(初级版)
  17. 单面打印机=》双面打印
  18. Lonza X-VIVO 15 无血清培养基使用攻略
  19. 2018中国十大品牌在线英语培训机构排行榜暴风来袭
  20. Oracle 设置 密码可以重复使用 the password cannot be reused

热门文章

  1. 三句话介绍清楚滑动窗口协议/GBN/SR
  2. PHP ERROR_PHP 处理错误函数
  3. Spring Boot 1:Introduction
  4. 欧拉函数 euler
  5. CentOS下mysql数据库常用命令总结
  6. web.xml上监听器作用
  7. 九度OJ 1437 To Fill or Not to Fill -- 贪心算法
  8. Android工具HierarchyViewer 代码导读(3) -- 后台代码
  9. 微软Visual Studio2005开发工具路线图详解
  10. mysql 横向排列,mysql横向转纵向、纵向转横向排列的方法