css相对单位

em和rem

1em 等于当前元素的字号,其准确值取决于作用的元素。谈到 font-size 属性时, em 表现得不太一样。如果声明 font-size: 1.2em,会发生什么呢?一个字号当然不能等于自己的 1.2 倍。实际上,这个 font-size 是根据继承的字号来计算的。

rem 是 root em 的缩写。 rem 不是相对于当前元素,而是相对于根元素的单位。不管在文档的什么位置使用 rem, 1.2rem 都会有相同的计算值: 1.2 乘以根元素的字号。

经验

用 rem 设置字号,用 px 设置边框,用 em 设置其他大部分属性,尤其是内边距、外边距和圆角,(有时用百分比设置容器宽度)。

响应式面板

小屏幕用较小的默认字号,在 800px、 1200px 以及更大的屏幕上逐渐增大字号。

css 复制代码
    :root {
      font-size: 0.75em;
    }
    @media (min-width: 800px) {
      :root {
        font-size: 0.875em;
      }
    }
    @media (min-width: 1200px) {
      :root {
        font-size: 1em;
      }
    }
缩放单个组件

有时,需要让同一个组件在页面的某些部分显示不同的大小,你可以用 em 来单独缩放一个组件。

首先,给每个面板添加父元素声明 font-size: 1rem,这样无论面板位于页面何处,都有一个可预测的字号。

其次,改用 em 而不是用 rem,重新定义标题的字号,使其相对于刚刚在 1rem 时创建的父元素的字号

css 复制代码
    :root {
      font-size: 0.75em;
    }
    @media (min-width: 800px) {
      :root {
        font-size: 0.875em;
      }
    }
    @media (min-width: 1200px) {
      :root {
        font-size: 1em;
      }
    }

    body {
      font-family: Helvetica, Arial, sans-serif;
    }

    .panel {
      font-size: 1rem;
      padding: 1em;
      border: 1px solid #999;
      border-radius: 0.5em;
    }

    .panel > h2 {
      margin-top: 0;
      font-size: 0.8em;
      font-weight: bold;
      text-transform: uppercase;
    }

    .panel.large {
      font-size: 1.2em;
    }
视口相对单位

视口------浏览器窗口里网页可见部分的边框区域。它不包括浏览器的地址栏、工具栏、状态栏。

vh:视口高度的 1/100。

vw:视口宽度的 1/100。

vmin:视口宽、高中较小的一方的 1/100

vmax:视口宽、高中较大的一方的 1/100

提示

相对视口的单位对大部分浏览器而言是较新的特性,因此当你将它跟其他样式结合使用时,会有一些奇怪的 bug。

用 calc()结合 em 和 vh 两种单位定义 font-size
css 复制代码
:root {
font-size: calc(0.5em + 1vw);
}

现在打开网页,慢慢缩放浏览器,字体会平滑地缩放。 0.5em 保证了最小字号, 1vw 则确保了字体会随着视口缩放。这段代码保证基础字号从 iPhone 6 里的 11.75px 一直过渡到 1200px 的浏览器窗口里的 20px。可以按照自己的喜好调整这个值。

无单位的数值和行高

有些属性允许无单位的值(即一个不指定单位的数)。支持这种值的属性包括 line-height、z-index、 font-weight( 700 等于 bold, 400 等于 normal,等等)。任何长度单位(如 px、 em、rem)都可以用无单位的值 0,因为这些情况下单位不影响计算值,即 0px、 0%、 0em 均相等。警告 一个无单位的 0 只能用于长度值和百分比,比如内边距、边框和宽度等,而不能用于角度值,比如度,或者时间相关的值,比如秒。

line-height 属性比较特殊,它的值既可以有单位也可以无单位。通常我们应该使用无单位的数值,因为它们继承的方式不一样。

当一个元素的值定义为长度( px、 em、 rem,等等)时,子元素会继承它的计算值。当使用 em 等单位定义行高时,它们的值是计算值,传递到了任何继承子元素上。如果子元素有不同的字号,并且继承了 line-height 属性,就会造成意想不到的结果,比如文字重叠。

使用无单位的数值时,继承的是声明值,即在每个继承子元素上会重新算它的计算值。这样得到的结果几乎总是我们想要的。我们可以用一个无单位的数值给 body 设置行高,之后就不用修改了,除非有些地方想要不一样的行高。

自定义属性(即 CSS 变量)

要定义一个自定义属性,只需要像其他 CSS 属性那样声明即可

css 复制代码
:root {
--main-font: Helvetica, Arial, sans-serif;
}

这个代码清单定义了一个名叫--main-font 的变量。将其值设置为一些常见的 sans-serif 字体。变量名前面必须有两个连字符( --),用来跟 CSS 属性区分,剩下的部分可以随意命名。

调用函数 var()就能使用该变量。利用该函数引用前面定义的变量--main-font。

css 复制代码
:root {
--main-font: Helvetica, Arial, sans-serif;
}
p {
font-family: var(--main-font);
}
动态改变自定义属性
css 复制代码
<!doctype html>
<head>
  <style>
    :root {
      font-size: calc(0.5em + 1vw);
      --main-bg: #fff;
      --main-color: #000;
    }

    body {
      font-family: Helvetica, Arial, sans-serif;
    }

    .dark {
      margin-top: 2em;
      padding: 1em;
      background-color: #999;
      --main-bg: #333;
      --main-color: #fff;
    }

    .panel {
      font-size: 1rem;
      padding: 1em;
      border: 1px solid #999;
      border-radius: 0.5em;
      background-color: var(--main-bg);
      color: var(--main-color);
    }

    .panel > h2 {
      margin-top: 0;
      font-size: 0.8em;
      font-weight: bold;
      text-transform: uppercase;
    }

    .panel.large {
      font-size: 1.2em;
    }
  </style>
</head>

<body>
  <div class="panel">
    <h2>Single-origin</h2>
    <div class="body">
      We have built partnerships with small farms
      around the world to hand-select beans at the
      peak of season. We then carefully roast in
      small batches to maximize their potential.
    </div>
  </div>

  <aside class="dark">
    <div class="panel">
      <h2>Single-origin</h2>
      <div class="body">
        We have built partnerships with small farms
        around the world to hand-select beans at the
        peak of season. We then carefully roast in
        small batches to maximize their potential.
      </div>
    </div>
  </aside>
</body>

在本例中,总共定义了自定义属性两次:第一次在根元素上( --main-color 为黑色),第二次在深色容器上( --main-color 为白色)。自定义属性就像作用域变量一样,因为它的值会被后代元素继承。在深色容器中, --main-color 为白色,在页面其他地方,则是黑色。

可以使用 JavaScript 改变自定义属性
javascript 复制代码
<script type="text/javascript">
let rootElement = document.documentElement;
let styles = getComputedStyle(rootElement);
let mainColor = styles.getPropertyValue('--main-bg');
console.log(String(mainColor).trim());

rootElement = document.documentElement;
rootElement.style.setProperty('--main-bg', '#cdf');
</script>
总结

拥抱相对单位,让网页的结构决定样式的含义。

建议用 rem 设置字号,但是有选择地用 em 实现网页组件的简单缩放。

不用媒体查询也能让整个网页响应式缩放。

使用无单位的值设置行高。

请开始熟悉 CSS 的一个新特性:自定义属性

相关推荐
木子七9 分钟前
vue3-setup中使用响应式
前端·vue
廖子默19 分钟前
提供html2canvas+jsPDF将HTML页面以A4纸方式导出为PDF后,内容分页时存在截断的解决思路
前端·pdf·html
Moment22 分钟前
毕业半年,终于拥有了两个近 500 star 的开源项目了 🤭🤭🤭
前端·后端·开源
光影少年1 小时前
react和vue图片懒加载及实现原理
前端·vue.js·react.js
AndyGoWei1 小时前
react react-router-dom history 实现原理,看这篇就够了
前端·javascript·react.js
小仓桑1 小时前
深入理解 JavaScript 中的 AbortController
前端·javascript
摸鱼也很难1 小时前
解决 node.js 执行 npm下载 报无法执行脚本的错
前端·npm·node.js
换个名字不能让人发现我在摸鱼1 小时前
裁剪保存的图片黑边问题
前端·javascript
PeterJXL1 小时前
pnpm:包管理的新星,平替 npm 和 yarn
前端·npm·node.js·pnpm