CSS 实现元素固定宽高比

此文档是关于高度随宽度变化的固定宽高比。关于英文单词的学习和记忆,大家可以访问这个网站。

一个简单固定宽高比的例子

我们知道 display: block 的元素 (即块级元素) 的宽度会占满父元素的 content area/box 宽度,当我们在 body 元素下放一个 div 元素设置其高度为0并且设置 padding-bottom 的值为百分比时就得到了一个“高度随宽度变化的固定宽高比的 div”。比例的值即为 padding-bottom 的值。

实现上面 gif 里的效果,用到的 HTML 是在 body 元素里添加

<div class="container">div>

CSS 是

body {
  margin: 0;
}

div.container {
  height: 0;
  padding-bottom: 20%;
  background-image: linear-gradient(45deg, #2989d8 0%, #7db9e8 100%);
}

原理

这种形式的固定宽高比的原理是因为当元素的上下 padding 值用百分比的形式时是相对于包含块的宽度而言的。

div.container 元素的包含块就是 body 元素,判断依据是这的第一条,div.container 元素的默认 positionstatic,它的父元素 body 是一个 block 元素,所以 body 就是它的包含块。设置在 div.container 上的 padding-bottom 的值当用百分比时就是相对于 body 的宽度而言的。

在浏览器里,当通过调整窗口大小使页面 body 的宽度变化时,div.container 的高度会按照 padding-bottom 设置的百分比相对应 body 的宽度来变化,又由于 div.container 的宽度始终是父元素 body 的宽度,所以实际上 div.container 的高度是按照 padding-bottom 设置的百分比相对自身的宽度来变化的,这样就实现了 div.container 的固定宽高比。

注意事项

这里面需要注意区分一点的是:在 CSS 里我们设置元素的 width 或者 height 值并不是在浏览器端检查元素时看到的元素的宽度或者高度值。我们在浏览器端检查元素时看到的宽度或者高度始终等于内容区 (content area/box)、内边距 (padding) 和边框 (border) 之和的,而 CSS 里设置元素的 widthheight 包不包括内边距和边框受 box-sizing 的影响,默认 box-sizing: content-box 是不包括内边距和边框的。

我们平时说的一个元素的宽度或者高度是指在浏览器端检查元素时看到的宽度或者高度,始终是内容区、内边距和边框之和。

由于 div.containerheight 设置为0,在浏览器端我们看到 div.container 高度的大小就是 padding-bottom 的大小。div.container 显示背景图是因为 background-image 默认会在内边距里显示,跟 background-color 一样都受 background-clip (默认值为 border-box) 的影响。

一个有内容的固定宽高比例子

因为 div.containerheight 为0,即没有 content area/box 无法容下文字。

这时如果我们想在 div.container 里嵌一个元素放置文字并且也让该元素固定宽高比该怎么做呢?有的同学可能会回答说:嵌入一个块级元素 div 时设置它的 height 为 100% 不就行了。尝试过的同学会知道这样做是不行的,当

div.container {
  height: 0;
  padding-bottom: 20%;
}

div.container div {
  height: 100%;
  background-image: linear-gradient(45deg, #2989d8 0%, #7db9e8 100%);
}

由这的第一条:

…, the containing block is formed by the edge of the content box of the nearest ancestor element…

可知,嵌入的 div.container div 元素的 height 用百分比写时是相对包含块内容区的高度而言的。而嵌入元素 div.container div 的包含块 div.container 元素内容区的高度默认就是 height 的值,这里设置的是0。所以“嵌入一个块级元素 div 时设置它的 height 为 100%”是不行的。

这里我们需要嵌入的元素的 height 用百分比写时是相对包含块内容区加上内边距的高度而言,这的第二条

If the position property is absolute, the containing block is formed by the edge of the padding box of the nearest ancestor element that has a position value other than static (fixed, absolute, relative, or sticky).

就是我们需要的。CSS 改成下面即可。

div.container {
  position: relative;
  height: 0;
  padding-bottom: 20%;
}

div.container div {
  position: absolute;
  height: 100%;
  width: 100%;
  background-image: linear-gradient(45deg, #2989d8 0%, #7db9e8 100%);
}

由这的 absolute 解释 (… no space is created for the element in the page layout …) 可知 div.container divwidth 为 0,并非占满父元素的 content area/box 宽度,所以需要添加 width: 100%;

接下来,我们可以将文字放入 div.container div 里并添加额外的样式。比如这里我们加入文字 “Hello World!” 并向 div.container div 额外添加以下 CSS

display: flex;
justify-content: center;
align-items: center;
font-size: 5vw;

就可以得到下面的效果。

你可能感兴趣的:(css,html,前端)