CSS中的盒模型

高级的布局话题基于文档流和盒模型等概念,这些是决定网页元素的大小和位置的基本规则。

一、元素宽度问题

IE有一个bug,它会默认将<main>元素渲染成行内元素,而不是块级元素,所以代码中我们用声明display: block来纠正。

当给一个元素设置宽或高的时候,指定的是内容的宽或高,所有内边距、边框、外边距都是追加到该宽度上的。

1.1 避免魔术数值

在编程中不推荐魔术数值,因为往往难以解释一个魔术数值生效的原因。如果不理解这个数值是怎么来的,就不会知道在不同的情况下会产生什么样的结果。

1.2 调整盒模型

box-sizing的默认值为content-box,这意味任何指定的宽或高都只会设置内容盒子的大小。将box-sizing设置为border-box后,height和width属性会设置内容、内边距以及边框的大小总和,这刚好符合示例的要求。

盒模型:CSS盒模型有两种类型:标准盒模型和IE盒模型。标准盒模型中,元素的宽度和高度只包括内容区域,不包括内边距、边框和外边距。而在IE盒模型中,元素的宽度和高度包括内容区域、内边距和边框,但不包括外边距。

1.3 全局设置border-box

用通用选择器(*)选中了页面上所有元素,并用两个选择器选中了网页的所有伪元素。并将这段代码放到样式表开头。

ee8e71f2fe944291b96e53073eb46d87.jpg

 加上这段代码,height和width会指定元素的实际宽和高。改变边框和内边距不会影响它们。

但是全局设置border-box为固定值可能会在使用第三方组件时出现适配问题,而使用继承方式来修改盒模型则更为灵活,可以通过修改顶级容器中的border-box值来更改。

因此,可利用继承来修改盒模型。

3ef2563669d149ad9965c8fa7837779b.jpg

 盒模型通常不会被继承,但是使用inherit关键字可以强制继承。建议将代码添加到新网站的开发中,但是注意已有的样式表代码不可随意添加。

1.4 给列之间加上间隔

百分比是相对于父元素的完整宽度的。

如果想用其他单位指定间距呢?(用em指定间距,因为em单位的一致性更好。)可以用calc()来实现。

dd21546966954322a8701b56848a221e.jpg

 二、元素高度的问题

为什么将高度区别于宽度单提出来学习?因为两者处理方式不同,宽度是有限制的,而通常是避免给高度明确限制的。

普通文档流是为限定的宽度和无限的高度设计的。容器的高度由内容天然地决定,而不是容器自己决定。

普通文档流——指的是网页元素的默认布局行为。行内元素跟随文字的方向从左到右排列,当到达容器边缘时会换行。块级元素会占据完整的一行,前后都有换行。

2.1 控制溢出行为

当明确设置一个元素的高度时,内容可能会溢出容器。

用overflow可以控制溢出的行为:

  • visible(默认值)——所有内容可见,即使溢出容器边缘。
  • hidden——溢出容器内边距边缘的内容被裁剪,无法看见。
  • scroll——容器出现滚动条,用户可以通过滚动查看剩余内容。
  • auto——只有内容溢出时容器才会出现滚动条。(推荐使用)

请谨慎使用滚动条,因为网页外部存在滚动条,网页内容设置滚动条影响用户体验。

除了垂直溢出,内容也可能在水平方向溢出。可以用overflow-x属性单独控制水平方向的溢出,或者用overflow-y控制垂直方向溢出。

2.2 百分比高度的备选方案

  • 要想让百分比高度生效,必须给父元素明确定义一个高度。
  • 更好的方式是用视口的相对单位vh,100vh等于视口高度。
  • 更常见方法——创造等高列。

1. 等高列

这里等高列的原意是不明确设置容器元素的高度,容器元素的高度随着子元素列的内容而改变,通常就是具有更高的列作为容器元素的高度,而内容较少的列会留白,拉到与最高列的高度,同时保持底部对齐。

以下是通过CSS表格和Flexbox两种方式实现等高列效果。

2. CSS表格布局

首先,用CSS表格布局替代浮动布局。给容器设置display: table,给每一列设置display:table-cell。

不像block的元素,默认情况下,显示为table的元素宽度不会扩展到100%,因此需要明确指定宽度❶。外边距❷并不会作用于table-cell元素,导致缺少间隔。

7c044965612542f7a672fd739ac23fd1.jpg

 可以用表格元素的border-spacing属性来定义单元格的间距,设置水平间距和垂直间距。但是注意这个值会作用于表格的外边缘。

可以用负外边距解决问题。正的外边距会将容器的边缘往里推,而负的外边距则会将边缘往外拉。

de6e34bf049a4a3e9bd5089b46070f26.jpg

 3. Flexbox

Flexbox不需要一个额外的div包裹元素,它默认会产生等高的元素。此外也不需要使用负外边距。给容器设置display: flex,它就变成了一个弹性容器(flex container),子元素默认等高。

a4de4e1ce6244abf8e1665eca416c582.jpg

 给子元素设置宽度和外边距,尽管加起来可能超过100%, Flexbox也能妥善处理,不用calc()计算。

注意:除非别无选择,否则不要明确设置元素的高度。先寻找一个替代方案。设置高度一定会导致更复杂的情况。

2.3 使用min-height和max-height

min-height和max-height:可以用这两个属性指定最小或最大值,而不是明确定义高度,这样元素就可以在这些界限内自动决定高度。

afc0aa94c744481186cc5e37712da3ba.jpg

 这意味着元素至少等于指定的高度,如果内容太多,浏览器就会允许元素自己扩展高度,以免内容溢出。

同理,max-height允许元素自然地增高到一个特定界限。如果到达这个界限,元素就不再增高,内容会溢出。还有类似的属性是min-width和max-width,用于限制元素的宽度。

2.4 垂直居中内容

过去有好几种方式实现垂直居中,但是每一种方式都有一定的局限性。在CSS中,回答一个问题的答案通常是“这得看情况”,垂直居中就是如此。


vertical-align声明:只会影响行内元素或者table-cell元素。

  • 对于行内元素,它控制着该元素跟同一行内其他元素之间的对齐关系。
  • 对于显示为table-cell的元素,vertical-align控制了内容在单元格内的对齐。如果你的页面用了CSS表格布局,那么可以用vertical-align来实现垂直居中。

在容器里让内容居中最好的方式是根据特定场景考虑不同因素。

1. 可以用一个自然高度的容器吗?

给容器加上相等的上下内边距让内容居中。

2. 容器需要指定高度或者避免使用内边距吗?对容器使用display: table-cell和vertical-align: middle。

3. 可以用Flexbox吗? 如果不需要支持IE9,可以用Flexbox+align-items: center;+justify-content: center; 居中内容。

4. 容器里面的内容只有一行文字吗?

设置一个大的行高,让它等于理想的容器高度。这样会让容器高度扩展到能够容纳行高line-hight。如果内容不是行内元素,可以设置为inline-block。

5. 容器和内容的高度都知道吗?

将内容绝对定位。(只有当前面提到的方法都无效时才推荐这种方式。)父元素relative相对定位,子元素absolute绝对定位;

6. 不知道内部元素的高度?

用绝对定位结合变形(transform)。(还是只有当前面提到的方法都无效时才推荐该方法。)

7. 还不确定的话?

参考howtocenterincss网站。这个网站很不错,可以根据自己的场景填写几个选项,然后它会相应地生成垂直居中的代码。


三、负外边距

外边距不同于内边距和边框宽度,可以为负值。

负外边距的具体行为取决于设置在元素的哪边。

  • 如果设置左边或顶部的负外边距,元素就会相应地向左或向上移动,导致元素与它前面的元素重叠;
  • 如果设置右边或者底部的负外边距,并不会移动元素,而是将它后面的元素拉过来(元素指定宽度或者长度时);元素指定宽度时设置右边的负外边距会将元素右边拓展到容器外。

负外边距都使文档流向前流动,但是不会改变元素本身在文档流中所占的内容大小。

如果元素被别的元素遮挡,利用负外边距让元素重叠的做法可能导致元素不可点击。

四、外边距折叠

当顶部和/或底部的外边距相邻时,就会重叠,产生单个外边距。这种现象被称作折叠。

4.1 文字折叠

外边距折叠的主要原因与包含文字的块之间的间隔相关。折叠外边距的大小等于相邻外边距中的最大值。

4.2 多个外边距折叠

即使两个元素不是相邻的兄弟节点也会产生外边距折叠。在没有其他CSS的影响下,所有相邻的顶部和底部外边距都会折叠。如果在页面中添加一个空的、无样式的div(没有高度、边框和内边距),它自己的顶部和底部外边距就会折叠。

注意:只有上下外边距会产生折叠,左右外边距不会折叠。

4.3 容器外部折叠

如果元素的容器有背景色,元素的外边距在容器外面折叠通常会产生不想要的效果。外边距会在不想的地方重叠。

防止外边距重叠的方法:

  • 对容器使用overflow: auto(或者非visible的值),防止内部元素的外边距跟容器外部的外边距折叠。这种方式副作用最小。———创建了BFC
  • 在两个外边距之间加上边框或者内边距,防止它们折叠。
  •  如果容器为浮动元素、内联块、绝对定位或固定定位时,外边距不会在它外面折叠。
  • 当使用Flexbox布局时,弹性布局内的元素之间不会发生外边距折叠。网格布局同理。
  • 当元素显示为table-cell时不具备外边距属性,因此它们不会折叠。此外还有table-row和大部分其他表格显示类型,但不包括table、table-inline、table-caption。

BFC的特点: 可避免盒子塌陷和外边距重叠BFC内部布局不影响外部布局。

创造BFC的条件: 元素设置绝对定位:position (absolute、fixed);

display 值为:inline-block、table-cell、table-caption、flex、float等;

overflow 值为:hidden、auto、scroll;

五、容器内的元素间距

容器的内边距和内容的外边距之间的相互作用处理起来很棘手。

5.1 如果内容改变了

每一次改变HTML,得确保每个元素之间有间距,但是容器的顶部(或底部)没有多余的间距。

5.2 更通用的解决方案:猫头鹰选择器

不要给网页当前的内容固定外边距,而是应该采取更通用的方式,不管网页结构如何变化都能够生效。

这就是Heydon Pickering所说的迟钝的猫头鹰选择器(lobotomized owl selector)(以下简称猫头鹰选择器),因为它长这样:* + *。该选择器开头是一个通用选择器(*),它可以选中所有元素,后面是一个相邻兄弟组合器(+),最后是另一个通用选择器。也就是说,它会选中页面上有着相同父级的非第一个子元素。

使用猫头鹰选择器是需要权衡的。它省去了许多的需要设置外边距的地方,但是在某些不想加外边距的地方则需要覆盖。通常只在有并列元素,或者有多列布局时这样使用。有时还需要根据设计,给段落和标题设置特定的外边距。

六、总结

  • 总是全局设置border-box,以便得到预期的元素大小。
  • 避免明确设置元素的高度,以免出现溢出问题。
  • 使用现代的布局技术,比如display: table或者Flexbox实现列等高或者垂直居中内容。
  • 如果外边距的行为很奇怪,就采取措施防止外边距折叠。
  • 使用猫头鹰选择器全局设置堆叠元素之间的外边距。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值