【百度前端学院学习笔记】Day5 盒子模型


内容来自于:

菜鸟教程
MDN盒模型
注:这一节MDN的中文翻译质量不佳。

一、什么是盒子?

所有HTML元素可以看作盒子,在CSS中,"box model"这一术语是用来设计和布局时使用。

CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距,边框,填充,和实际内容。

盒模型允许我们在其它元素和周围元素边框之间的空间放置元素。

下面的图片说明了盒子模型(Box Model):
在这里插入图片描述

  • Margin(外边距) - 清除边框外的区域,外边距是透明的。
  • Border(边框) - 围绕在内边距和内容外的边框。
  • Padding(内边距) - 清除内容周围的区域,内边距是透明的。
  • Content(内容) -盒子的内容,显示文本和图像。

1.1 标准盒模型

当指定一个 CSS 元素的 宽度(Width)高度属性(Height) 时,你只是设置 内容(Content) 区域的宽度和高度。要知道,完整大小的元素,你还必须添加内边距,边框和边距。
例如:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"> 
<title>菜鸟教程(runoob.com)</title>
<style>
div{border: 2px dashed black;}
div.test {
   background-color: lightgrey;
   width: 300px;
   border: 25px solid green;
   padding: 25px;
   margin: 25px;
}
</style>
</head>
<body>

<h2>盒子模型演示</h2>

<p>CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距,边框,填充,和实际内容。</p>
   <div>
<div class="test">这里是盒子内的实际内容。有 25px 内间距,25px 外间距、25px 绿色边框。</div>
   </div>

</body>
</html>

呈现的效果如下:在这里插入图片描述
计算<div class = "test">这个元素的宽度:
300px (width)
+50px (左 + 右padding)
+50px (左 + 右border)
+50px (左 + 右margin)
= 450px
【注意】:margin 不计入实际大小 —— 当然,它会影响盒子在页面所占空间,但是影响的是盒子外部空间。盒子的范围到边框为止 —— 不会延伸到margin。

1.2 替代盒模型(IE风格)

一旦为页面设置了恰当的 DTD,大多数浏览器都会按照上面的图示来呈现内容。然而 IE 5 和 6 的呈现却是不正确的。根据 W3C 的规范,元素内容占据的空间是由 width 属性设置的,而内容周围的 padding 和 border 值是另外计算的。不幸的是,IE5.X 和 6 在怪异模式中使用自己的非标准模型。这些浏览器的 width 属性不是内容的宽度,而是内容、内边距和边框的宽度(注意没有外边框margin的宽度)的总和。 这种模式就是替代盒模型

  • 标准盒模型(standard box model):
    在这里插入图片描述
  • 替代盒模型(alternative box model):
    在这里插入图片描述

默认浏览器会使用标准模型。如果需要使用替代模型,可以通过为其设置 box-sizing: border-box来实现。 这样就可以告诉浏览器使用 border-box 来定义区域,从而设定您想要的大小。

.box { 
  box-sizing: border-box; 
} 

或者设置整个网页采用替代模型,并设置所有元素继承这个属性。

html { //注:html5是所有元素的父元素
  box-sizing: border-box;
}
*, *::before, *::after {
  box-sizing: inherit;
}

Internet Explorer默认使用替代盒模型,没有可用的机制来切换。(IE8+ 支持使用box-sizing 进行切换 )

虽然有方法解决这个问题。但是目前最好的解决方案是回避这个问题。也就是,不要给元素添加具有指定宽度的内边距 (padding) ,而是尝试将内边距或外边距添加到元素的父元素和子元素。

IE8 及更早IE版本不支持设置填充的宽度和边框的宽度属性。

解决IE8及更早版本不兼容问题可以在HTML页面声明<!DOCTYPE html>即可。

二、盒子的应用

2.1 block、inline和inline-block:

就像html5里有块元素和行内元素一样,css3里的盒子也有blockinline两种属性。这两种盒子会在**页面流(page flow)**和元素之间的关系方面表现出不同的行为:

1.display=block
一个被定义成 块级的(block),即 display = block盒子会表现出以下行为:

  • 盒子会在水平方向扩展并占据父容器水平方向的所有可用空间,在绝大数情况下意味着盒子会和父容器一样宽
  • 每个盒子都会换行;
  • width 和 height 属性可以发挥作用;
  • 内边距(padding), 外边距(margin) 和 边框(border) 会将其他元素从当前盒子周围“推开”

除非特殊指定,诸如标题(<h1>等)和段落(<p>)这样的块元素默认情况下都是块级的盒子。

2.display=block
如果一个盒子对外显示为 行内(inline),那么他的行为如下:

  • 盒子不会产生换行;
  • width 和 height 属性将不起作用;(因为一个行内元素的width默认靠字距,height默认靠行距)
  • 垂直方向内边距(padding)外边距(margin)以及边框(border)会被应用但是不会把其他处于 inline 状态的盒子推开;(因为说到底它被视作行内盒子,只能在水平方向影响别的元素)
  • 水平方向的内边距(padding)外边距(margin)以及边框(border)会被应用而且也把其他处于 inline 状态的盒子推开。(行内盒子当然可以在水平方向影响别的元素)

例如:

<p>
    I am a paragraph and this is a <span>span</span> inside that paragraph. A span is an inline element and so does not respect width and height.
</p>  
span {
  margin: 20px;
  padding: 15px;
  width: 800000px;
  height: 500000px;
  background-color: lightblue;
  border: 2px solid blue;
}

显示的效果如下:
在这里插入图片描述
可以看到,widthheight这两个非常夸张的属性被忽略了,因为段落本来就有自己的字距和行距嘛。

  width: 800000px;
  height: 500000px;

margin,paddingborder则生效了,但是他们只推开了水平方向上下文"inside…",竖向的行距还是一样的,这导致了边框和文字的重合。(这里还有个很有趣的东西:<span>这个元素只遮挡了上面的行,没有遮挡下面的行。)

用做链接的<a>元素、 <span><em>以及 <strong>这样的行内元素都是默认处于 inline 状态的。

3.display: inline-block
display有一个特殊的值,它在内联和块之间提供了一个中间状态。这对于以下情况非常有用:我不希望一个项切换到新行,但希望它可以设定宽度和高度,并避免上面看到的重叠。

一个元素使用 display: inline-block,实现我们需要的块级的部分效果

  • 设置width 和height 属性会生效。
  • padding, margin, 以及border 会推开其他元素。

上面的例子稍作修改,改变display属性的值,

span {
  margin: 20px;
  padding: 20px;
  width: 80px;
  height: 50px;
  background-color: lightblue;
  border: 2px solid blue;
  display: inline-block;
}

将会产生如下效果:
在这里插入图片描述
可以看到,在保留不换行的基础上,<span>元素在水平和竖直方向上都推开了周围的文字,并且widthheight属性得到了应用。

另一个display: inline-block的应用如下:
一个导航栏的元素<a>由于是行内元素,通过padding属性使它扩大之后会导致覆盖了边框:
在这里插入图片描述

<nav>
  <ul class="links-list">
    <li><a href="">Link one</a></li>
    <li><a href="">Link two</a></li>
    <li><a href="">Link three</a></li>
  </ul>
</nav> 
.links-list a {
  background-color: rgb(179,57,81);
  color: #fff;
  text-decoration: none;
  padding: 1em 2em;
}

.links-list a:hover {
  background-color: rgb(66, 28, 40);
  color: #fff;
}

使用.links-list a选择器将display: inline-block添加到样式规则中,即可通过内边距推开其他元素来修复这个问题。
在这里插入图片描述

2.2 改变内部样式布局:display: flex

上述的block,inlineinline-block是元素对外的显示模式,而元素内部也有显示的模式,它决定了子元素是按照正常文档流(normal flow) 还是按照 弹性盒子(Flexbox) 布局。

下面三个html元素,都有同样的外部显示类型 block

<p>I am a paragraph. A short one.</p>
<ul>
  <li>Item One</li>
  <li>Item Two</li>
  <li>Item Three</li>
</ul>
<p>I am another paragraph. Some of the <span class="block">words</span> have been wrapped in a <span>span element</span>.</p>
p, 
ul {
  border: 2px solid rebeccapurple;
  padding: .5em;
  .block,
li {
  border: 2px solid blue;
  padding: .5em;
}

ul {
  display: flex;
  list-style: none;
}

.block {
  display: block;
} 
}

第一个是一个段落,在 CSS 中加了边框。浏览器把它渲染成一个块级盒子,所以段落从新的一行开始,而且宽度占满一行。

第二个是一个列表,布局属性是 display: flex。 将在容器中建立一个flex布局,可以看到虽然每个<li>是块元素,但是依然没有换行,这是因为它不是按照正常文档流(normal flow) 而是按照 弹性盒子(Flexbox) 布局。

第三个是个块级段落,里面有两个 元素。正常情况下是 inline,但是其中一个加了block类,设置属性 display: block。

在这里插入图片描述

2.3 外边距折叠(Margin collapsing)

如果你有两个外边距相接的元素,这些外边距将合并为一个外边距,即最大的单个外边距的大小。
这其实不难理解,相邻的两个元素都想通过margin把对方推开,肯定是手长的人(margin大) 决定了二者的距离。

<div class="container">
  <p class="one">I am paragraph one.</p>
  <p class="two">I am paragraph two.</p>
</div>
.one {
  margin-bottom: 50px;
}

.two {
  margin-top: 1px;//手短,即使只想把对方推开1px,奈何对方想把你推开50px
}

在这里插入图片描述
但是当margin出现负值的时候,表示靠近,这个时候手长的人也**“来者不拒”**了。

.one {
  margin-bottom: 50px;
}

.two {
  margin-top: -50px; //下面的元素主动往上凑,这时候两个元素的边框正好紧贴着,所以显得很厚。
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值