内在盒子和外在盒子

date
Nov 14, 2024
slug
css-box
status
Published
tags
css
type
Post
URL
summary
盒子
 
外在盒子和内在盒子。外在盒子负责元素是可以一行显示,还是只能换行显示;内在盒子负责 宽高、内容呈现什么的,因此,display:block 应该脑补成 display:block-block,而display:inline-table外在是一个 inline,内在是一个 table

width/height作用在哪里和具体的细节

  • 内在盒子

width:auto

四种宽度表现:
  1. 充分利用可用的空间,例如 div p,默认是100% 于父级的宽度
  1. 收缩与包裹,典型代表就是浮动、绝对定位、inline-block 元素或 table 元素
  1. 收缩到最小,这个比较容易出现在table-layout 为 auto 的 table 中
notion image
  1. 超出容器的限制,除非有特别设置 width,否则容器一般不会超出父级的宽度,但是存在特殊情况,内容很长的连续的英文和数字,或者内联元素被设置了 white-space:nowrap

内部尺寸和外部尺寸

上方的第一个场景属于外部元素决定的元素宽度,也就是外部尺寸,其他的都是内部尺寸
外部尺寸一旦设置了宽度,其本身的流动性就消失了
两个导航,前者没有设置 width,后者设置了 100%
notion image
所以在实际开发的时候,要尽量借助流动性的规则,做到“无宽度”
格式化宽度,这只会出现在绝对定位当中,其宽度由内部尺寸决定
有一种特殊的情况,宽度由外部尺寸决定
假设该<div>元素最近的具有定位特性的祖先元素的宽度是 1000 像素,则这个<div>元素的宽 度是 960(即 1000−20−20)像素。
上面的例子都是外部尺寸,那么如何判断一个元素的尺寸是内部尺寸决定的,当一个元素没有内容的时候,宽度是0,那么就是内部尺寸,内部尺寸有如下的三个表现形式
  1. 包裹性:元素尺寸由内部元素决定,但永远小于“包含块”容器的尺寸(除非容器尺寸小于元素的“首选最小宽度”)。换句话说就是,“包裹性”元素冥冥中有个 max-width:100%罩着的感觉,因此对于一个元素如果是display 的属性是inline-block,尽管里面的文本再多也不会超出容器
按钮就是包裹性最好的例子,一个按钮的文字内容越多宽度越宽,但是如果一旦到某个极限,就会自动进行换行
包裹性的应用:页面某个模块的文字内容是动态的,可能是几个字,也可能是一句话。然后,希望文字少的时候居中显示,文字超过一行的时候居左显示。
notion image
除了 inline-block,浮动元素和绝对定位元素都具有这种包裹性
inline-block 和 block 的区别
display: block 的特点:
  • 独占一行
  • 宽度默认是父容器的100%
  • 不受 text-align 属性的影响
display: inline-block 的特点:
  • 不独占一行
  • 宽度由内容决定
  • 能被 text-align 属性影响
关键区别:
如果设置为 block,那么容器一直是100%宽度,永远不会居中,因为已经占满整行
而 inline-block 则会:
  • 少量文字时:容器宽度随内容增加,被父容器的 text-align: center 居中
  • 多行文字时:容器变宽,但仍保持居中特性
这就像:
block 是一整块砖,永远占满空间
inline-block 是一个可伸缩的盒子,能够根据内容自适应宽度
  1. 首选最小宽度,使用上面的例子,如果外部容器的宽度是 240,假设宽度是0,那么 inline-block 的宽度是多少,基于 css 是服务于图文的理论,所以,是不会让文字的宽度变成0的,而是会发生这样的情况
notion image
  1. 最大宽度,最大宽度相当于包裹性的元素设置了white-sapce:nowrap,最大宽度是最大连续内联盒子的宽度
notion image
这里的使用场景例如,有一个横向排列的多图片展示的区域,可以给外部容器设置一个超大的宽度,避免内部因为宽度不够而发生换行
notion image

width 值作用的细节

notion image
当我们给一个元素加上了 padding 之后,会发现盒子的宽度变大了,这种宽度的设定实际上并不合理,这导致和实际期望的宽度不符合,为了避免这种情况出现,可以遵守宽度分离原则

宽度分离原则

在这个例子中,这个盒子的宽度本身是 102,但是因为需要留白,加上了 padding,结果宽度变成了 142,而为了不影响布局,就需要进行手动计算
如何不需要进行手动计算
  1. 再套一层 div,利用宽度分离原则,子元素的 content-box 会自动变成60
  1. 使用 box-sizing,用于改变盒子作用的 width
于是代码就可以修改成这样,宽度会被限制在 100

height:100%

这个属性想要生效,必须在其父元素有一个可以生效的高度,或者在绝对定位中,这个是生效的
绝对定位元素的百分比计算和非绝对定位元素的百分比计算是有区别的,绝对定位会把 padding 考虑在内,而非绝对定位只考虑 content-box
notion image
在如下的这个场景中,在图片上覆盖两个绝对定位,同时设 height:100%,则无论图片多高,我们的左右半区都能自动和图片高度一模一样,无须任何使用 JavaScript 的计算
notion image

min/max-width/height

在公众号中,经常会有图片,这些图片为了避免在各端差异过大,通常会有下面的限制,height 必须是 auto,可以保证图片自适应宽度,避免被压缩

初始值

max-width 和 max-height 的初始值是 none,而 min-width和 min-height 的初始值的 auto

超越 important

指的是在设置了 max-width的情况下,会覆盖掉 width

任意元素的展开收起

很多时候展开的元素的高度是不固定的,使用 auto 无法计算从0到 auto,动画就无法生效
这个时候就可以使用 max-height,给一个足够大的高度,因为 max-height 计算后就是等于 height 的,但是要尽量避免过大,因为会存在效果延迟

内联元素

块级负责结构,内联负责内容

哪些元素是内联的

内联元素的内联特指的是外在盒子,从行为表现来看典型的特征就是可以和文字在一行显示,因此,文字是内联元素,图片是内联元素,按钮是内联元素,输入框、下拉框等原生表单控件也是内联元素。

内联盒模型

  1. 内容区域:文字选中的区域,也就是 content-box
notion image
  1. 内联盒子:不会让内容成块显示,而是排成一行,这里实际指的就是外在盒子,用于决定元素是内联还是块级
notion image
如果外部含内联标签(span em 和a等),则属于“内联盒子”(实线框标注);如果是个光秃秃的文字,则属于“匿名内联盒子”(虚线框标注)。
  1. 行框盒子:每一行就是一个行框盒子,每个行框盒子是一个个内联盒子组成的,p 标签内是一个行框盒子
  1. 包含盒子(包含块):p 标签就是一个包含盒子,由一行行的行框盒子

幽灵空白节点

内联元素的所有解析和渲染表现就如同每个行框盒子的前面有一个“空白节点”一样。这个“空白节点”永远透明,不占据任何宽度,看不见也无法通过脚本获取,就好像幽灵一样,这种情况只存在于 html5 当中

© Jayden 2024