ホームページ >ウェブフロントエンド >htmlチュートリアル >REM と EM_html/css_WEB-ITnose
ウェブ タイポグラフィのベスト プラクティスの 1 つは、rem と em のような相対単位を使用することです
問題は、rem の支持者と em の支持者の間で常に議論されてきたことです。あなたがサポートしているものを使用する必要があります。
この記事では、rem と em のどちらをどのように決定したかを説明し、rem と em の正確な意味と、それらを使用してモジュール コンポーネントを構築する方法についても説明します。
EM はタイポグラフィの単位であり、現在指定されているポイント サイズに相当します。 - Wikipedia
フォント サイズの代わりにポイント サイズを使用しないため、このステートメントは Web では意味がありません。
これは、font-size 属性値が 20px のセレクターがある場合、1em=20px
h1 { font-size: 20px } /* 1em = 20px */p { font-size: 16px } /* 1em = 16px */
em 単位を使用してフォント サイズを宣言できることを意味します。実際、フォント サイズを指定するには em などの相対単位を使用するのがベスト プラクティスです。
次のコードを考えてみましょう:
h1 { font-size: 2em }
ここでの h1 セレクターの実際のサイズはどれくらいですか?
4a249f0d628e2318394fd9b75b4636b1 の親要素に基づいて font-size を計算する必要があります。その親要素は 100db36a723c770d327fc0aef2ce13b1 で、その font-size は 16px に設定されます。
このようにして、h1 の値を 32px、つまり 2 * 16px に計算できます
これも実現できますが、それを 100db36a723c770d327fc0aef2ce13b1 ピクセルに設定することは良い考えとは考えられません。 font-size の値は、ユーザーのブラウザによって設定された値に影響します。
代わりに、パーセント値を使用したり、フォント サイズを完全に無視したりできます。
注: font-size を完全に放棄すると、その値はデフォルトで 100% になります
html { font-size: 16px }h1 { font-size: 2em } /* 16px * 2 = 32px */
ほとんどのユーザー (およびブラウザ) では、ユーザーがデフォルトを変更しない限り、font-size 値は 100% のデフォルトになります。ブラウザ設定による font-size の値。しかし、そうする人はほとんどいません。
さて、話を戻しましょう。
em は、font-size 以外の他の属性値を指定するためにも使用できます。マージンとパディングのプロパティも、多くの場合、ems を使用してサイズ設定されます。
ここで、多くの人が em の価値について混乱し始めます。
以下のコードを考えてみましょう。
要素の margin-bottom の値はどうすればよいでしょうか? (100db36a723c770d327fc0aef2ce13b1 の font-size が 100% に設定されていると仮定します)
そうですかこの 2 つのケースで margin-bottom の 1em の値が異なることに驚きましたか?
これは、1em が現在のフォント サイズと同等であるために発生します。
異なるコードでは、1em の値も異なるため、人々が混乱することがよくあります。 em を初めて使用する場合は、混乱することもあります。
とにかく、これがレムです。次にレムについて知りましょう。
rem はルート em を指します。 これは、em によって引き起こされる計算問題を人々が解決できるようにするために作成されました。
タイポグラフィの単位であり、ルート フォント サイズに相当します。これは、1rem が 100db36a723c770d327fc0aef2ce13b1 の font-size に相当することを意味します。
rem で表現された同じコードを考えてみましょう。現在の margin-bottom の計算値はいくらですか?
html { font-size: 100% } /*这里的意思是默认值为16px*/
ご覧のとおり、1rem の値はどこに設定しても 16px です。
とても信頼できて分かりやすいです。
レムです。 em が何であるかを理解すれば、これは簡単に理解できますか?
さて、この記事の本題に入りましょう、レムですか、それともエムですか?
一部の開発者は、rem を使用するとコンポーネントのモジュール性が低下すると主張して、rem の使用を完全に避けます。 rem がもたらす利便性を気に入って、あらゆることに rem を使用する人もいます。
奇妙なことに、これまでのキャリアを通じて、私はさまざまな場所で rem または em を使用するという罠にはまってしまいました。モジュール式コンポーネントをサポートしてくれる点は気に入っていますが、コードが複雑になるのは嫌いです。私は rem 計算の便利さは気に入っていますが、モジュール式コンポーネントの邪魔になるのは嫌いです。
それは証明されています。 rem と em にはそれぞれ長所と短所があります。その使用は実際の状況に基づいて判断する必要があります。
ここには 2 つの簡単なルールがあります:
ちょっと単純すぎますか?単純なコンポーネント (head 要素) を記述するために rem を使用するか em を使用するかを検討してみましょう。その過程で、これら 2 つのルールがうまく機能することがわかります。
次の画像のようなタイトル要素 ( c1a436a314ed609750bd7c7d319db4da ) があります:
如果你用 rem 设置一切属性的大小,标题元素的样式应该和上图相似:
.header { font-size: 1rem; padding: 0.5rem 0.75rem; background: #7F7CFF;}
目前为止,一切都好。
既然在相同的网页上会有不同大小的元素,接下来让我们创建一个稍微大的头部元素。这里,我们尽可能继承样式。
更大元素的标记可能如下所示:
<a href="#" class="header header--large">header!</a>
css样式如下:
.header { font-size: 1rem; padding: 0.5rem 0.75rem; background: #7F7CFF;}.header--large { font-size: 2rem;}
不幸的是,这个代码并不能实现效果。你会发现在 .header--larger 下,文本和边缘的空间太小。
如果你坚持使用 rem ,唯一的办法就是使用 padding 重新声明大标题:
.header { font-size: 1rem; padding: 0.5rem 0.75rem; background: #7F7CFF;}.header--large { font-size: 2rem; padding: 1rem 1.5rem;}
有没有注意到这里的模式? .header--larger 的 font-size 是 header 的两倍大。因此, .header--large 的 padding 是 .header 的两倍大小。
如果我们有更多大小的标题,或者改变标题大小时,又会发生什么呢?你已经可以看到如果使用 rem 对整个网站进行编码所带来的重复性以及复杂性。
我们可以同时使用 rem 和 em 简化代码,这样就不需要对 .header-larger 的 padding 进行声明。
.header { font-size: 1rem; padding: 0.5em 0.75em; background: #7F7CFF;}.header--large { font-size: 2rem;}
正如你所看到的, 当有属性需要用它的字体大小( font-size )进行大小声明时,这时 em 就相当有用。 这就是第一条原则产生的地方。
接下来让我们看看,如何只使用 em 来创建相同的标题。
只使用 em 来制作标头元素和只使用 rem 制作的代码差不多,只需要将 rem 该更为 em .
.header { font-size: 1em; padding: 0.5em 0.75em; background: #7F7CFF;}.header--large { font-size: 2em;}
.header 和 .header--larger 的效果看起来和 rem 实现效果一样。
不是吗?
不是的!
你的网页只包含一个标题元素是极不可能的。我们必须考虑标题与页面其他元素的交互。
在标题之前或之后看见其他元素是十分正常的,如下图所示:
对于这个元素集的标记如下:
<div class="header header--large">A Header Element</div><p>A paragraph of text</p><p>A paragraph of text</p><div class="header">A Header Element</div><p>A paragraph of text</p>
对于样式,我们需要对 p 标签的左边和右边添加一点外边距:
p { margin-left: 0.75em; margin-right: 0.75em;}
不不不! :(
.header--larger 左边和右边的 padding 太大了!
如果你坚持只使用 em 来解决这个问题,唯一的方法就是重新声明大标头的 padding-left 和 pading-right .
.header { font-size: 1em; padding: 0.5em 0.75em; /* Other styles */}.header--large { font-size: 2em; padding-left: 0.375em; padding-right: 0.375em; margin: 0.75em 0; }
注意到这里的模式了么? .header--larger 的 font-size 是 .header 的 font-size 的两倍大小,然而 .header--larger 的 padding-left 和 padding-right 是 .header 的一半。
在上述的案例中,如果我们可以同时使用 em 和 rem 就可以简化代码。具体来说就是, em 负责 padding 的左边和右边, rem 负责 padding 的顶部和底部。
.header { padding: 0.5em 0.75rem; font-size: 1em; background: #7F7CFF;}.header--large { font-size: 2em;}
正如你所看到的,当一个元素用 font-size 声明大小时, em 单位是十分有用的。但是,当你需要根据根 font-size 来设置属性大小时,你就会陷入麻烦之中。
在一个组件之中看 rem 和 em 如何配合工作,不是更加清楚么?
现在,让我们提高一个档次,看标题和段落之间如何在网格中进行交互。
在这之前,让我们先把标题和段落组成一个组件:
<div class="component"> <div class="component__header">A header element</div> <p>Some paragraph text</p></div>
组件的基本样式为:
.component { background: white; border: 2px solid #7F7CFF;}.component__header { font-size: 2em; padding: 0.5em 1.5rem; background: #7F7CFF; margin: 0;}.component p { padding-left: 1.5rem; padding-right: 1.5rem; margin: 1.5rem 0;}
目前为止,一切都好。这都是我们在前面的章节所涵盖的。
我们可以在不同的网页中找到此组件,可能的领域包括:
当组件被放置在一个较小的位置时,如侧边栏。这时,标题元素就会使用一个较小的 font-size 来呈现。
通过修改组件的类,我们可以创建变量。标记将如下所示:
<div class="component component--small"> <!-- Contents of the component. --></div>
变量的样式如下:
.component--small .component__header { font-size: 1em;}
现在,关于组件的样式,两条规则同样适用:
通过标题元素,我们了解到,是否使用 em 进行大小声明,只需判断该属性是否与页面其他元素进行交互。这里有两种不同的方式来思考如何构建此组件:
让我们用两种方式构建组件,你就会明白我的意思。
我们通过一个例子来看这样子的组件是什么样子:
注意当组件的大小改变时,同一时间内 font-size 、 margin 和 padding 的变化。
当组件大小变化时,如果您想要这样的效果,那么就需要使用 em 进行大小声明:
.component { background: white; border: 2px solid #7F7CFF;}.component__header { font-size: 2em; padding: 0.5em 0.75em; /* Changed padding into em */ background: #7F7CFF; margin: 0;}.component p { padding-left: 1.5em; /* Changed padding into em */ padding-right: 1.5em; /* Changed padding into em */ margin: 1.5em 0; /* Changed margin into em */}// Small variant .component--small .component__header { font-size: 1em; padding-left: 1.5em; /* Added em-sized padding */ padding-right: 1.5em; /* Added em-sized padding */}
然后,要激活变化大小,你不得不更改组件的 font-size 属性。
.component { // Other styles @media (min-width: 800px) { font-size: 1.5em; }}
目前为止,一切都好。
现在,让我们开始复杂部分。
想象一下你是否有一个这样子的网格。每个网格项之间的垂直和水平空间在不同设备上需要保持一致(良好的美学需要).
网格标记为:
<div class="grid"> <div class="grid-item"> <div class="component"> <!-- component --> </div> </div> <div class="grid-item"> <div class="component component--small"> <!-- A --> </div> <div class="component component--small"> <!-- B --> </div> </div></div>
在根 font-size 大小为 16px 的情况下,我已经将每个网格项之间的间距设置为 2em 。换句话说,间距计算的宽度为 32px 。
在这个网格之中的挑战就是,小组件A和小组件B之间要保持 32px 的外边距。开始的时候我们可以将组件B的 margin-top 设置为 2em 。
.component { /* Other styles */ @media (min-width: 800px) { font-size: 1.25em; }}.component + .component { margin-top: 2em;}
不幸的是,这效果并不是很好。小组件A和小组件B之间的 margin 的大小在视觉上远远大于视窗宽度 800px 时的列间距。
这种情况的发生是因为当视窗大于 800px 时,组件的 font-size 大小为 1.5em ( 24px )。因为 font-size 为 24px ,所以 2em 就是 48px ,这不同于我们所期待的 32px .
幸运的是,当我们知道是根据 font-size 来设置列间距大小时,我们就可以用 rem 轻易地解决这个问题。
.component + .component { margin-top: 2rem;}
这里有一个Codepen,你可以尝试一下。
注意:你需要用Flexbox来创建此网格。这里我将不再过多的解释,因为不仅仅是代码问题。如果你想了解更多关于Flebox的知识,你可以参考这里的文章。
顺便说一下,我没有赶上这一技术。Chris Coyier(他是一个天才)在一年之前就写了 它 。
不管怎样,我们就到目前为止好吗?如果好的话,让我们转向案例2。如果不好的话,有时间就留下评论,我会想办法作进一步解释。
案例1很容易理解。缺点是 很难保持模块化缩放,主要是垂直方向间距(vertical rhythms)并且在同一组件内保持大小一致 (特别是建设响应式网站)。
有时候你只需要调整组件的一部分,而不是一次性调整所有部分。例如,您可能仅仅想要更改一个较大视区标题的 font-size 。
在这种情况下,让我们先看看如何书写基本样式:
.component { background: white; border: 2px solid #7F7CFF;}.component__header { font-size: 2em; padding: 0.5em 1.5rem; background: #7F7CFF; margin: 0;}.component p { padding-left: 1.5rem; padding-right: 1.5rem; margin: 1.5rem 0;}.component--small .component__header { font-size: 1em;}
既然我们只是更改标题的 font-size 为 1200px ,我们可以使用 rem 控制一切属性的大小(不包括标题的 padding-top 和 padding-bottom 属性)
.component { background: white; border: 2px solid #7F7CFF;}.component__header { font-size: 2rem; /* Sized in rem instead */ padding: 0.5em 1.5rem; /* Sized in rem instead */ background: #7F7CFF;}.component p { padding-left: 1.5rem; /* Sized in rem instead */ padding-right: 1.5rem; /* Sized in rem instead */ margin: 1.5rem 0; /* Sized in rem instead */}.component--small .component__header { font-size: 1rem; /* Sized in rem instead */}
然后你就可以通过在不同视区下增加一个媒体特性,来更改标题的 font-size .
.component__header { font-size: 2rem; @media (min-width: 1200px) { font-size: 3rem }}.component--small .component__header { font-size: 1rem; @media (min-width: 1200px) { font-size: 1.5rem }}
注意,当我们改变浏览器大小时,标题 font-size 是如何改变的。这就是我们创建的案例2:)
还有一件事。
因为最好只使用少量的字体大小,我经常从组件上发现抽象的 font-size 属性。这种方式可以轻松的实现在所有组件上保持字体大小。
h2 { font-size: 2rem; @media (min-width: 1200px) { font-size: 3rem } }h3 { font-size: 1rem; @media (min-width: 1200px) { font-size: 1.5rem }}.component__header { @extend h2; }.component--small .component__header { @extend h3; }
这就是案例2!这里有一个Codepen供你去尝试:
这里你可能会问一个问题,“你应该使用哪种方法呢?”所以我还是先回答吧。
我会回答,这取决于您的设计。
就我个人而言,自从喜欢上自由文字排版模式,我使用案例2的时候相对多一点。
所以,你应该使用 rem 或者 em 吗?我想这并不是一个很好的问题。 rem 和 em 都各有优缺点,应该综合使用它们以帮助您更简单的建立模块化组件。
本文根据 @Zell 的《 REM vs EM – The Great Debate 》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处: http://zellwk.com/blog/rem-vs-em/ 。
在校学生,本科计算机专业。一个积极进取、爱笑的女生,热爱前端,喜欢与人交流分享。想要通过自己的努力做到心中的那个自己。微博:@静-如秋叶