我们之前讨论过 “为什么用 Ems?”。
对于那些不熟悉 em 值的人,Mozilla 开发者网络 对 em 做了很好的解释。
…一个 em 等于应用于当前元素父元素的字体大小。如果您在页面上没有设置任何字体大小,那么它将是浏览器的默认值,这可能是 16px。因此,默认情况下 1em = 16px,2em = 32px。
如果您仍然喜欢用 px 思考,但喜欢 em 的优点,不需要使用计算器,您可以让 Sass 为您完成这项工作。有很多方法可以使用 Sass 计算 em。
内联数学
h1 {
font-size: (32 / 16) * 1em;
}
p {
font-size: (14 / 16) + 0em;
}
注意:我们需要那里的“* 1em”以便 Sass 正确附加单位值。您也可以使用“+ 0em”来达到同样的目的。
结果
h1 {
font-size: 2em;
}
p {
font-size: 0.875em;
}
这可以工作,但我们可以让它更容易。
em() Sass 函数
有很多不同的方法来编写这个函数,这个来自 Web Design Weekly 的一篇文章
$browser-context: 16; // Default
@function em($pixels, $context: $browser-context) {
@return #{$pixels/$context}em;
}
非常聪明!这个函数使用 Sass 的字符串插值来将 em 附加到值。请注意,$context 参数具有 $browser-context 的默认值(因此,您将此变量设置为的任何值)。这意味着当在 Sass 中调用该函数时,您只需要定义 $pixels 值,并且数学计算将相对于 $browser-context(在本例中为 16px)进行。
示例用法
h1 {
font-size: em(32);
}
p {
font-size: em(14);
}
结果
h1 {
font-size: 2em;
}
p {
font-size: 0.875em;
}
一个使用数学而不是字符串插值的类似函数,来自 The Sass Way 可以很容易地修改为接受变量,就像我们的字符串插值函数一样
//un-modified
@function calc-em($target-px, $context) {
@return ($target-px / $context) * 1em;
}
// and modified to accept a base context variable
$browser-context: 16;
@function em($pixels, $context: $browser-context) {
@return ($pixels / $context) * 1em;
}
另一个使用 Sass 的 unitless() 方法
$browser-context: 16;
@function em($pixels, $context: $browser-context) {
@if (unitless($pixels)) {
$pixels: $pixels * 1px;
}
@if (unitless($context)) {
$context: $context * 1px;
}
@return $pixels / $context * 1em;
}
这使我们可以在函数调用中包含或不包含 px 单位。
h1 {
font-size: em(32);
}
// is the same as:
h1 {
font-size: em(32px);
}
在或某些根元素上设置 10px 的基本字体大小,难道不会简单得多吗?然后 1em 将始终为 10px?而且您只需要使用 em。所以计算 px 会非常容易。(32px = 3.2em)。
这里没有明确提到,但 em 会向上遍历 DOM 树以查找第一个字体大小。
为什么你整个字体结构要基于这么小的字体大小呢?10px 将需要你更改页面上几乎每个元素的字体大小,这样你才能省去一点数学运算?
你说的在每个元素上更改字体大小是什么意思?
如果你想要“弹性”或响应式字体大小,无论如何你都需要为每个组件声明它,就像这篇文章展示的那样。
只需花 5 分钟比较这两种方法。这不是要避免数学运算,而是要让你的团队开发更容易。
sass 真棒!!
特别是当你了解一些编程概念,比如函数、变量、if 条件……等等。
我还没有深入研究,但看起来它像是救星。
关于 Jesse 的评论
Jesse 说得对,设置 10 的基本字体需要调整比自然字体大小 > 10 时更多的元素的字体大小。说你需要为响应式网站设置每个元素的字体大小是不正确的。
考虑以下代码片段
… 现在将字体大小设置为 13px(或你的基本大小)。
如果你将基本字体大小设置为 10(这很小!),如果你想要它们是 10 以外的基本大小,那么最终你将为 red 和 blue 类指定字体大小。这与使用函数调整字体大小相比,工作量太大。
嗨,Chris,
我喜欢这个 mixin,但我想知道如何让它接受简写形式。
我希望能够将其用于任何属性测量 - 比如 padding: em(10 20 15 0);
我相信 bourbon 和 compass 内置了这个功能,但我更希望在可能的情况下不使用它们。
我还想知道将像素转换为 REM 而不是 EM 是否有任何价值。
感谢你所做的一切!
嗨,Travis,
我为 Chris 写了这篇文章。抱歉,我直到现在才看到这个,因为我一直在阅读评论。这些是 Sass 函数,它们比 mixin 的灵活性略差。
你目前可以使用它来进行简写,比如这样:
padding: em(10) em(20);
这不是你所要求的,但它是上面列出的函数中唯一可行的方法。我会看看是否可以使用这些函数开发一个 mixin,然后在这里告诉你结果。谢谢!
我还错过了回答你的一个问题。
对于一个很棒的 REM mixin,请查看 Hugo Giraudel 的 这篇很棒的文章
感谢这个帮助,它在很大程度上简化了流程,省去了来回使用计算器的麻烦!
嗨,Sean/Chris
真的很喜欢使用 Sass 的 unitless 函数的解决方案,但发现如果上下文是 em 值,它仍然返回 px 值,而不是 em 值。
我通过首先检查上下文的 em 单位,然后在进行计算之前剥离单位,最后将最终结果转换为 em 来修复了这个问题。
这里有一个 pen 来说明差异
http://codepen.io/aljaydavids/pen/YwWNGb
嘿,Jero,我读了你的评论,想确保我会避免你描述的问题,但不知道如何重现它。
尝试按照你的示例操作,但仍然感到困惑。
你能帮我理解为什么在某些情况下会返回 px 吗?
当我尝试将其应用到 Bootstrap 模板时,我遇到了这个问题:错误:未定义的操作:“1rem 乘以 1.25”。
以下代码触发了该问题
$font-size-context: 15;
$font-size-base: rem($font-size-context);
作为解决方案,我找到了这个修改后的函数版本,它修复了这个问题
@function rem( $pixels, $context: $font-size-context ) {
@return ($pixels/$context)*1rem;
}
对于遇到此问题的任何人来说,这是一个提醒,因为我在弄清楚发生了什么事的时候,撞了一下头。感谢 em() 的想法!
这是用于 rem 的函数
嗨!我有一个很大的疑问
当在不同的视窗大小下缩放字体时,它是否有效???
因为我们设置了默认值始终为 16px
谢谢 :)
我只是配置了 :root 并在那里设置了大小属性。
嗨,有没有办法乘以 em() 值?
示例
$padding: em(10);
如果我需要 em(20) 所以我想要乘以那个变量。
$padding*2 但不起作用
也许是我误解了什么,但这难道不违背使用 em 单位的目的吗?
如果我们设置一个静态的 $context 值,那么我们的目标就没有像“em”单位那样从其祖先继承字体大小。
我也是。
我想我们这里谈论的是
rem
,而不是em
?