整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

一篇文章带你了解CSS单位相关知识

一篇文章带你了解CSS单位相关知识

家好,我是皮皮,今天给大家分享一些前端的知识。

一、了解 CSS 单位

测量长度的单位可以是绝对的,例如像素,点等,也可以是相对的,例如百分比(%)和 em 单位。

指定 CSS 单位对于非零值是必须的,因为没有默认单位。丢失或忽略单位将被视为错误。但是,如果该值为 0,则可以省略该单位(毕竟,零像素与零英寸是一样的)。

注意: 长度是指距离测量。长度包括数字值,后面加单位,比如 10px、2em、50% 等。数字和单位之间不能出现空白。


二、相对长度单位

相对长度单位指定相对于另一个长度属性的长度。相对单位是 描述 :em当前的字体大小 。

ex :当前字体的 x 高度 。

em 和 ex 单位取决于套用至元素的字体大小。

1. 使用 em 单位

em 的值等于使用它的元素的 font-size 属性的计算值。它可用于垂直或水平测量。

例如,如果 font-size 元素设置为 16px,并且 line-height 设置为 2.5em,则 line-height像素计算值为:2.5?x?16px?=?40px。

P {
    font-size: 16px;
    line-height: 2.5em;
}

运行效果

当在 font-size 属性本身的值中指定 em 时会发生异常,在这种情况下,它引用父元素的字体大小。

因此,当我们用 em 指定字体大小时,1em 继承自 font-size。因此, font-size: 1.2em; 使文本比父元素的文本大 1.2 倍。

<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=640, user-scalable=no">
        <title>平安保险</title>
        <link rel="stylesheet" type="text/css" href="css/fy.css" />
    </head>


    <body>
        <meta http-equiv="Content-Type" content="text/html;
 charset=utf-8" />
        <title>项目</title>
        <style>
            body {
                font-size: 62.5%;
                font-family: Arial, Helvetica, sans-serif;
            }


            p {
                font-size: 1.6em;
            }


            p:firt-letter {
                font-size: 3em;
                font-weight: bold;
            }
</style>


        <body style="text-align: center; background-color: aquamarine;">
            <div>ddad</div>
            <p> Hellow world</p>
        </body>


</html>

代码解析:浏览器中字体的默认大小为 16px。我们的第一步是通过将主体设置 font-size62.5% 来减小整个文档的大小,这会将字体大小重置为 10px(16px 的 62.5%)。

这是默认 font-size的四舍五入,方便 px 到 em的转换。

2. 使用 ex 单位

ex 单位等于当前字体的 x 高度。

所谓的 x 高度是因为它通常等于小写 x 的高度,如下所示。但是, ex 即使对于不包含 x 的字体,也会定义的。

P {
    font-size: 16ex;
    line-height: 2.5em;
}

三、绝对长度单位

绝对长度单位相对于彼此固定。它们高度依赖于输出介质,因此在输出环境已知时主要有用。绝对单位由物理单位(的 in、cm、mm、pt、pc)和 px 单位。表中j进行属性的详细介绍。

单位

描述

in

英寸 - 1 英寸等于 2.54 厘米。

cm

厘米。

mm

毫米。

pt

points - 在 CSS 中,一个点定义为 1?72 英寸(0.353mm)。

pc

picas - 1pc 等于 12pt。

px

像素单位 - 1px 等于 0.75pt。

绝对物理单位,例如 in、cm、mm 等应被用于打印介质和类似的高分辨率的设备。然而,对于桌面和低分辨率设备等屏幕显示,建议使用像素或 em 单位。

例:

   h1 {
                margin: 0.5in;
            }
            /* inches  */


            h2 {
                line-height: 3cm;
            }
            /* centimeters */


            h3 {
                word-spacing: 4mm;
            }
            /* millimeters */


            h4 {
                font-size: 12pt;
            }
            /* points */


            h5 {
                font-size: 1pc;
            }
            /* picas */


            h6 {
                font-size: 12px;
            }
            /* picas */

提示: 使用相对单位(如 em 或百分比 %)的样式表可以更轻松地从一个输出环境扩展到另一个输出环境。

四、总结

本文主要介绍了css单位的运用,通过两个方面展开,相对长度单位,绝对长度单位,在项目中需要注意的点,需要注意的事项,都进行了详细的讲解和提供了对应的解决方案。代码很简单,希望可以帮助你学习。

如果在操作过程中有任何问题,记得下面留言,我们看到会第一时间解决问题。

么是弹性布局?

用户的文字大小与弹性布局

用户的浏览器默认渲染的文字大小是“16px”,换句话说,Web页面中“body”的文字大小在用户浏览器下默认渲染是“16px”。当然,如果用户愿意他可以改变这种字体大小的设置,用户可以通过UI控件来改变浏览器默认的字体大小。

弹性设计有一个关键地方Web页面中所有元素都使用“em”单位值。“em”是一个相对的大小,我们可以这样来设置1em,0.5em,1.5em等,而且“em”还可以指定到小数点后三位,比如“1.365em”。而其中“相对”的意思是:

1.相对的计算必然会一个参考物,那么这里相对所指的是相对于元素父元素的font-size。比如说:如果在一个<div>设置字体大小为“16px”,此时这个<div>的后代元素教程了是将继承他的字体大小,除非重新在其后代元素中进行过显示的设置。此时,如果你将其子元素的字体大小设置为“0.75em”,那么其字体大小计算出来后就相当于“0.75 X 16px=12px”;

2.如果用户通过浏览器的UI控件改变了文字的大小,那么我们整个页面也会进行放大(或缩小),不至于用户改变了浏览器的字体后会致使整个页面崩溃(我想这种现像大家都有碰到过,不信你就试试你自己制作过的项目,你会觉得很恐怖)。

大家可以查看这个弹性布局样例。此时你使用浏览器的UI控件改变了文字的大小或者直接“ctrl + ”和“ctrl - ”,你会发现这个弹性布局实例,在浏览器改变字体大小浏览会做出相应的放大和缩小,并不会影响整个页面的布局。注:这个实例的所有HTML和CSS在本教程中教程了都会使用到。

至于其他的弹性布局的实例,大家可以浏览Dan Cederholm的Simplebites,并改变文字的大小去浏览。

体验后,是不是觉得弹性布局的页面很灵活呀,而且也像“px”一样的精确。因此,只要我们掌握了“font-size”、“px”和“em”之间的基本关系,我们就可以民以食快速使用CSS创建精确的布局。

CSS的Elastigirl引进EM

Elastigirl的“em”是极其强大和灵活的,他不管字体大小是什么,是12px,16或60,他都可以计算出其值。

em其实就是一种排版的测试单位,而且他的由来还有一段小故事,关于这段小故事我就不和大家说了,因为大家都不是来听我讲故事的,我想大还是喜欢知道他在CSS中的那些事。

在CSS中,“em”实际上是一个垂直测量。一个em等于任何字体中的字母所需要的垂直空间,而和它所占据的水平空间没有任何的关系,因此:

如果字体大小是16px,那么1em=16px。

入门

在我们开始来了解CSS中的这个“em”之前,我们需要知道在浏览器下,他的默认字体大小。正好我们前面也这样做了,在所有现代浏览器中,其默认的字体大小就是“16px”。因此在浏览器下默认的设置将是:

1em=16px

因此,在一个CSS选择器被写入时,浏览器就有了一个“16px”大小的默认字体。此时我们Web页面中的<body>就继承了这个“font-size:16px;”,除非你在CSS样式中显式的设置<body>的“font-size”值,来改变其继承的值。这样一来,“1em=16px”、“0.5em=8px”、“10em=160px”等等,那么我们也可以使用“em”来指定任何元素的大小。

设置Body的font-size

很多前辈在多年的实践中得出一个经验,他们建议我们在<body>中设置一个正文文本所需的字体大小,或者设置为“10px”,相当于(“0.625em或62.5%”),这样为了方便其子元素计算。这两种都是可取的。但是我们都知道,<body>的默认字体是“16px”,同时我们也很清楚了,我们改变了他的默认值,要让弹性布局不被打破,就需要重新进行计算,重新进行调整。所以完美的设置是: body {font-size:1em;}

可是在那个没人爱的IE底下,“em”会有一个问题存在。调整字体大小的时候,同样会打破我们的弹性布局,不过还好,有一个方法可以解决:

html {font-size: 100%;}

公式转换——PXtoEM

如果你是第一创建弹性布局的,最好在身边准备一个计算器,因为我们一开始少不了很多的计算,有了他放心。

像素对于我们来说太密切了,因此我们也将从这开始。首先需要计算出1px和em之间的比例,然后是知道我们需要的px值。通过前面的介绍,大家都知道1em总是等于父元素的字体大小,因此我们完全可以通过下面的工式来计算:

1 ÷ 父元素的font-size × 需要转换的像素值=em值

大家可以参考一下面这张转换表(body字体为16px时的值)

接下来我们一起看一个很简单的实例“使用CSS的EM制作一个960px宽度的弹性布局”

HTML Markup

<body> <div id="container">…</div> </body>

将960px转换为em

1 ÷ 16px × 960px=60em

这个计算值的前提条件是<body>的“font-size:16px”。

CSS Code

html { font-size: 100%; } body { font-size: 1em; } #container { width: 60em; }

通过上面的实例,我想大家更能形像化的理解了,因为有例可询,其实我们可以把上面的计算公式转换一下,将更方便你的计算:

需要转换的像素值 ÷ 父元素的font-size=em值

那么我们上面的实例“960px”就可以这样来转换成“em”值

960px ÷ 16px=60em

上面我们一起见证了“px”转换成“em”的计算方式,接下来我们一起来动看制作上面展示过的弹性布局样例。下面我们主要一起来一步一步的实现他。

构建一个弹性的容器

要创建弹性布局样例那样的居中效果,我们首先需要创建一个HTML结构,我在此给创建一个<div>并且取名叫“wrap”

<body> <div id="wrap"> content here</div> </body>

我们希望这个容器是一个“740px”宽,适合一个“800px × 600px”显屏的实例。那么“740px”会等于多少“em”呢?这就是我们需要关心的问题,大家一起来看吧:

1、将“740px”转换成“em”设置到我们的容器“div#wrap”:我们都知道“div#wrap”的父元素<body>设置了字体为“16px”,那么此时在没有进行另外显示的设置时,他的子元素<div id="wrap">将继承“font-size”值,这样我们就可以轻意得到:“1px和1em之间的关系”

1em=16px 也就是 1px=1 ÷ 16=0.0625em

这样一来,我们的“740px”就很容易的能转换成“em” 0.0625em × 740=46.25em

当然大家也可以按照我们前面所列出的计算公式来进行转换,这样你心中更具有一个概念性,也不容易弄错:

1 ÷ 16 × 740=46.25em (1 ÷ 父元素的font-size × 需要转换的像素值=em值)

这样一来,您可以使用上面的公式计算出您需要的任何宽度或高度的“em”值,你只需要知道“1px等于多少em”,另外就是你要转换的“px”值是多少,具备这几个参数你就能得到你想要的“em”值了。

2、创建CSS样式:现在我们可以给“div#wrap”写样式了,弹性布局样例很明显的告诉我们,给“div#wrap”设置了一个宽度为“740px”居中,带有上下“margin”为“24px”,而且带有“1px”的边框效果,那么我们首先根据上面的公式计算出相应的“em值”,然后在写到CSS样式中:

html {font-size: 100%;} body {font-size: 1em;} #wrap { width: 46.25em;/*740px ÷ 16=46.25em */ margin: 1.5em auto;/*24px ÷ 16=1.5em*/ border: 0.0625em solid #ccc;/*1px ÷ 16=0.0625em*/ }

现在我们就轻松的创建了一个包含内容的弹性容器:弹性布局样例。

文本样式与em

首先我们在前面那个创建的<div id="wrap"></div>中插入一个<h1>和一个<p>:

<div id="wrap"> <h1>...</h1> <p>...</p> </div>

在弹性布局样例实例中,我们标题使用了“18px”,而段落设置的是“12px”字体,同时其行高是“18px”。18px将是我们实现弹性布局的一个重要值,可以使用他们都按正比变化。(有关于标题和段落的排版介绍,大家感兴趣可以点击Richard Rutter的basic leading和vertical rhythm以及chapter on vertical motion的相关介绍)。

根据CSS继承一说,我们在“div#wrap”的内容容器中没有显式的设置字体大小,这样整个“div#wrap”将继承了其父元素“body”的字体——“16px”。

1、给段落设置样式:——“12px”的字体,“18px”的行高以及margin值

从CSS继承中,我们可以得知我们所有段落继承了其父元素“div#wrap”的“font-size:16px”。同时我们通过前面的介绍得知1px=1 ÷ 16=0.0625em,这样一来我们就很轻松的知道“12px”等于多少个“em”

0.0625em × 12=0.750em

这样我们就可以给段落p设置样式:

p {font-size: 0.75em;/*0.0625em × 12=0.750em */}

要计算出段落所需的行高和“margin”为“18px”,来满足Richard Rutter说的basic leading,那我们就需要像下面的方法和来计算:

18 ÷ 12=1.5em

使用所需的行高值“18px”直接除以“字体大小12px”,这样就得到了段落“p”的“line-height”值。在本例中行高就等于字体的“1.5”倍,接着我们把“line-height”和“margin”样式加到段落“p”中

p{ font-size: 0.75em;/*0.625em × 12=0.750em */ line-height: 1.5em;/*18px(line-height) ÷ 12(font-size)=1.5em */ margin: 1.5em;/*18px(margin) ÷ 12(font-size)=1.5em */ }

2、给标题设置一个18px的字号

标题“h1”和段落“p”一样的原理,他也是继承他父元素“div#wrap”的“16px”的“font-size”,所以我们也是按同样的方法可以计处出他的“em”

0.0625em × 18=1.125em

我们可以把得出的值写到CSS样式表中

h1 { font-size: 1.125em;/*0.625em × 18=1.125em*/ }

同样为了保留Richard Rutter所说的vertical rhythm,我们同样将标题“h1”的“line-height”和“margin”都设置为“18px”,使用方法前面介绍的方法。很容易得到他们的“em”值为“1em”:

h1 { font-size: 1.125em; /*0.625em × 18=1.125em*/ line-height: 1em; /*18px(line-height) ÷ 18px(font-size)=1em */ margin: 1em; /*18px(margin) ÷ 18px(font-size)=1em */ }

设置图片大小——使用em

要做出弹性布局样例这样的果,我们也需要在html中插入一张图片:

<body> <div id="wrap"> <h1>....</h1> <p><img src="90.png" alt="" /> Lorem...</p> </div> </body>

我们这张图片具有“90px”的宽和高,同时具有一个右边距和底边距为“18px”设置,而且还进行左浮动。下面我们就一起来看其如何实现图片这几个样式效果:

从HTML结构中,我们很清楚的知道,图片是段落“p”的子元素,通过前面的介绍,你们知道这个段落“p”的“font-size”值被得定义为“12px”,因此我们计算图片的属性值时,不能在按“1px=0.0625em”或者“1em=16px”来计算,我们需要使用最老的公式计算:

1 ÷ 父元素的font-size × 需要转换的像素值=em值

这样一来,按上面所示的公式,我们就可以计算出图片的大小:

1 ÷ 12 × 90=7.5em

现在你就可以将计算出来的值写到样式中去:

p img { width: 7.5em; /*1 ÷12( 父元素的font-size) × 90px(图片的宽度)=7.5em */ height: 7.5em; /*1 ÷12( 父元素的font-size) × 90px(图片的高度)=7.5em */ }

我们在段落中知道了“18px”刚好是“1em”,现在我们也把他使用到图片的样式中:

p img { width: 7.5em; /*1 ÷12( 父元素的font-size) × 90px(图片的宽度)=7.5em */ height: 7.5em; /*1 ÷12( 父元素的font-size) × 90px(图片的高度)=7.5em */ margin: 0 1.5em 1.5em 0; float: left; }

这样我们就制作出一个和弹性布局样例一样的效果。希望通过这样的一个实例能帮助大家了解如何使用“em”来创建一个弹性布局的方法。当然大家可能还在担心使用“em”来制作一个弹性布局,不能像“px”一样的的精确,如果你真正理解了这篇教程后,我想你不会在有这样的想法。

弹性布局的公式总结

最后我想大家肯定和我会有同一种想法,就是相关参数是的“px”值如何成功而且正确的转换成“em”值,经过上面的学习,我最后将公式总结一下:

元素自身没有设置字号大小时,元素的width、height、line-height、margin、padding、border等值转换都按下面公式转换:

1 ÷ 父元素的font-size × 需要转换的像素值=em值

我们来看一个实例:

<body> <div id="wrapper">test</div> </body>

我们在body默认字体大小为“16px”,此时需要“div#wrapper”的相关参数值为:

#wrapper { width: 200px; height: 100px; border: 5px solid red; margin: 15px; padding: 10px; line-height: 18px; }

那么我们按照上面的公式,将所在参数进行转换:

#wrapper { width: 12.5em;/*1 ÷ 16 × 200=12.5em值*/ height: 6.25em;/*1 ÷ 16 × 100=6.25em值*/ border: 0.3125em solid red;/*1 ÷ 16 × 5=0.3125em值*/ margin: 0.9375em;/*1 ÷ 16 × 15=0.9375em值*/ padding: 0.625em;/*1 ÷ 16 × 10=0.625em值*/ line-height: 1.125em;/*1 ÷ 16 × 18=1.125em值*/ }

我们一起来看计算出来的值:

接下来我需要大家在来看一个效果,这一点很关键哟,仔细看好,在同样的参数基础上稍加一条元素本身设置字体大小为:14px;,大家可以会说很简单的呀,按前面的公式计算出来加上就是了,那么我现在就按大家说的计算加上:

#wrapper { font-size: 0.875em;/*1 ÷ 16 × 14=0.875em值*/ width: 12.5em;/*1 ÷ 16 × 200=12.5em值*/ height: 6.25em;/*1 ÷ 16 × 100=6.25em值*/ border: 0.3125em solid red;/*1 ÷ 16 × 5=0.3125em值*/ margin: 0.9375em;/*1 ÷ 16 × 15=0.9375em值*/ padding: 0.625em;/*1 ÷ 16 × 10=0.625em值*/ line-height: 1.125em;/*1 ÷ 16 × 18=1.125em值*/ }

此进我们在firebug下看计算出来的layout值

为了更好的说明问题,我把元素自身没有设置字体大小和元素自身设置了字体大小,两者在firebug计算出来值:

我截这个图的主要意图是,说明一个问题就是元素自身要是设置了字体大小后,其计算公式就不在是前面所说的,我们需要做一下修改:

1、字体计算公式依旧

1 ÷ 父元素的font-size × 需要转换的像素值=em值

2、其它属性的计算公式需要换成

1 ÷ 元素的font-size × 需要转换的像素值=em值

那么我们现在来计算一回:

#wrapper { font-size: 0.875em;/*1 ÷ 16 × 14=0.875em值*/ width: 14.2857em;/*1 ÷ 14 × 200=14.2857em值*/ height: 7.1429em;/*1 ÷ 14 × 100=7.1429em值*/ border: 0.357em solid red;/*1 ÷ 14 × 5=0.357em值*/ margin: 1.071em;/*1 ÷ 14 × 15=1.071em值*/ padding: 0.714em;/*1 ÷ 14 × 10=0.714em值*/ line-height: 1.2857em;/*1 ÷ 14 × 18=1.2857em值*/ }

我们在来看一次计算出来的值:

总结

长篇介绍了一大堆,唯一想告诉大家的是以下几点

1、浏览器的默认字体大小是16px

2、如果元素自身没有设置字体大小,那么元素自身上的所有属性值如“boder、width、height、padding、margin、line-height”等值,我们都可以按下面的公式来计算

1 ÷ 父元素的font-size × 需要转换的像素值=em值

3、这一种千万要慢慢理解,不然很容易与第二点混了。如果元素设置了字体大小,那么字体大小的转换依旧按第二条公式计算,也就是下面的:

1 ÷ 父元素的font-size × 需要转换的像素值=em值

那么元素设置了字体大小,此元素的其他属性,如“border、width、height、padding、margin、line-height”计算就需要按照下面的公式来计算:

1 ÷ 元素自身的font-size × 需要转换的像素值=em值

这样说,不知道大家理解了整明白了没有,如果没有整明白,可以回过头来看上面的一个实例。

多入门学前端的同学,或是准备面试的同学都会去死记硬背一些前端知识点,笔者也是这么经历过来的,但却不推荐这种囫囵吞枣、不求甚解的学习方式,因为这样会走很多弯路,属于“应试”学习,我们更应该的是从基础到复杂,从表象到原理的角度却思考学习,才能熟练掌握技能。

整理了一些在CSS(层叠样式表)中的知识点,或许你曾看过一些什么“万字总结”、“面试必看”,但还是希望更多同学能够沉下心来学习,不仅仅满足于停留在“API工程师”的层面,多从CSS约定的规则去解释现象。

一、width(宽)& height(高)

浏览器中,明确了widthheight就可以绘制出一块矩形区域,也决定(量化)了当前HTML标签渲染后在屏幕上占据的有效矩形面积。

1.1 width与height的值

值说明100px像素(绝对)单位,矩形宽度为100px50%百分比(相对)单位,矩形宽度为包含块定义width的50%50vw(相对)单位,矩形宽度为视口宽度的50%,CSS3规范50vh(相对)单位,矩形宽度为视口高度的50%,CSS3规范auto默认值,为内容(与子元素)撑开的宽度,块级元素宽度默认为100%inherit继承父元素对应值initial初始值,在MDN文档中可查,不同的CSS属性的初始值不同unset继承父级相应属性值,父级没有对应属性则取默认初始值

height属性规则与width相同。另外max-heightmin-height优先级大于height,同理max-widthmin-width优先级大于width

1.2 height:100%无效

我们有时会在CSS里写height: 100%,发现并无效果,如下:

<div class="block"></div>
* {
  padding: 0;
  margin: 0;
  border: 0;
}
body {
  background-color: green;
/*   height: 100%; */
  border: 5px solid greenyellow;
}
.block {
  width: 100%;
  height: 100%;
  background-color: red;
}

block类 div的高度并未按照我们预想那样撑满全屏高度

高度100%并未铺满屏幕

代码&效果:https://codepen.io/DYBOY/embed/RwoJKRP

block类的父级(包含块)是bodybody在未设置值的时,height值为autobody的实际计算高度为内容撑开的高度,即为0(可以将上述代码的border样式取消注释,可看到body的高度)

那么子元素block类的高度即等同于0

body {
    background-color: azure;
    height: auto;
}
.block {
    width: 100%;
    height: 0 * 100%; // 0
    background-color: red;
}

所以此时block类所在的div盒子的高度无效,height为0,即在浏览器上无渲染高度 浏览器的渲染规则可理解记忆为:深度优先遍历计算

子元素的相对单位的计算值都是基于父/祖先元素对应的属性值,auto是基于内容区域撑开计算所得。

浏览器渲染HTML文档流,背景色默认为白色,如果文档中的htmlbody标签设置了背景色,这两个标签的背景色实际设置的是浏览器视口的背景色。

二、padding(内边距)& border(边框)& magin(外边距)

盒模型可以看作四个“同心矩形”组合而成,如下图

对于这三个属性的表现其实并无特别可说明,见上图可知意。

元素分为行级元素块级元素,行级元素的marginpadding的上下值无效。

2.1 百分比单位计算

自己之前一直有个误区,认为paddingmargin的百分比单位的计算基数是当前元素矩形区域宽高来算,但是根据包含块的规则,他们的计算基数应该是包含块的width值。

之前团队里大佬洪岩问:“如何实现一个高度是自适应宽度3倍的图片?”

实现方法1: 利用Chrome浏览器最新支持的aspect-ratio属性,其问题就是C端浏览器兼容性不好

.box {
    aspect-ratio: 1/3; // width/height 宽高比
}

aspect-ratio效果

实现方法2: 巧用包含块规则(paddingwidth属性百分比值的计算基数是包含块的宽度)+背景图实现

利用包含块规则实现

代码和演示:https://codepen.io/DYBOY/pen/JjbZgeE

2.2 border-radius百分比和像素

border-radius属性用于描述边框圆角半径,根据资料如果是百分比单位,则根据所在**盒子模型的矩形宽和高(包含border和padding)**作为计算基数,border-radius的值描述的是边框角度所在椭圆的半长轴和半短长轴长度。

border-*-radius属性的两个长度或百分比值定义了四分之一椭圆的半径,该半径定义了外边界边角的形状(参见下图)。第一个值为水平半径第二个为垂直半径。如果省略第二个值,则从第一个复制。如果任一长度为零,则角为正方形,而不是圆角。

水平半径的百分比是指边框的宽度,而垂直半径的百分比是指边框的高度。

来看下面这个示例:

<div class="box">1</div>
<div class="box style1">2</div>
<div class="box style2">3</div>
<div class="box style3">4</div>
* {
    padding: 0;
    margin: 0;
}
body {
    background-color: #fff;
}
.box {
    position: relative;
    width: 200px;
    height: 200px;
    margin: 10px auto;
    background-color: #00abef;
    border-radius: 100px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 32px;
    color: #fff;
}
.style1 {
    padding: 20px;
}
.style2 {
    padding: 20px;
    border-radius: 50%;
}
.style3 {
    padding: 20px;
    border-width: 10px;
    box-sizing: border-box;
}

效果

代码&演示:https://codepen.io/DYBOY/pen/BaQPaaj

发现第二个形状是一个椭圆,其原因是百分比的计算是把所在元素矩形区域的宽和高作为计算基数,而所在矩形的框高的计算值需要加上paddingborder的宽度,所以变成了一个椭圆。那么,是不是把盒模型设置为IE盒模型就可以避免这个问题了?答案是的,如上代码的第四个圆形。

  • 参考详细资料:https://www.w3.org/TR/2010/WD-css3-background-20100612/#the-border-radius

利用边框的椭圆,可以制造平滑的不规则形状,例如模仿一个水滴:

运动的水珠

**知识点:**如果没有设置border-color,默认边框颜色为所在元素的文本颜色。

2.3 BFC与margin折叠

BFC是盒模型中在屏幕上渲染展示的矩形区域,决定了浮动、盒模型渲染交互的区域。

margin区域折叠是一个BFC(块级格式化上下文)的问题,两个div属于同一个BFC。父子元素margin-top塌陷,兄弟元素margin重合取较大值。

若想要避免,则需要让两个相邻设置了margin的元素都变成一个BFC

创建BFC的常见CSS属性值?

  1. 浮动元素,float:left/right/auto
  2. 定位,position:absolute/fixed
  3. 展示,display:inline-block/table相关/flow-root/flex/grid
  4. flex/grid 的直接子元素为BFC
  5. table 相关的比如 tabletable-celltable-caption
  6. flow-root最好,无副作用
  7. 溢出,显示指明overflow:hidden/auto
  8. overflow的css计算值不为visiable,也就是指明溢出盒模型交互区域的处理方式
  9. html根元素是一个BFC

关于BFC更详细的解读可以参阅:

  • 《可能是最好的BFC解析了...》- https://juejin.cn/post/6960866014384881671

2.3.1 实例&解决方案

2.3.1.1 父子高度塌

父级margin,子级的margin-top无效

高度塌陷

代码&演示:https://codepen.io/DYBOY/pen/poNxjOP

解决方案:

原因是父子组件的margin-top取最大值,上面例子中父子组件的包含块都是body,属于同一个BFC(html标签)内的子元素,因此需要将父/子元素变成BFC(根据如上的创建BFC的CSS值设置),那么子元素的margin就会依赖父元素的左上角作为基准点margin偏移。

2.3.1.2 兄弟元素margin取较大值

<style>
.box {
    margin: 20px auto;
    background-color: red;
    width: 200px;
    height: 200px;
}
</style>

<div class="box"></div>
<div class="box"></div>
<div class="box"></div>

上下相邻元素的外边距为20px重合了

解决方案:

想要每两个盒子的上下边距为20px*2,则就需要如下处理:

<style>
.box-parent {
    overflow: hidden;
    /* display: flow-root; */
}
.box {
    margin: 20px auto;
    background-color: red;
    width: 200px;
    height: 200px;
}
</style>

<div class="box-parent">
    <div class="box"></div>
</div>
<div class="box-parent">
    <div class="box"></div>
</div>
<div class="box-parent">
    <div class="box"></div>
</div>

推荐解决方案:

由于改变了DOM结构,所以不是最好的解决方法,更好的方法就是利用塌陷规则,增加margin-bottom/margin-top的值,直接计算得到两块元素之间的margin,并设置对应值。

三、Containing Block(包含块)

包含块内容可参阅文章《字节前端都知道的CSS包含块规则》

四、box-sizing(盒模型)

盒子模型包含四部分:外边距(margin area)、边框(border area)、内边距(padding area)、内容区(content area),其分布组合如下图所示。

盒子模型

盒模型有两种,IE盒模型border-box)和标准盒模型content-box),其常用语法如下

// 默认为标准盒模型
box-sizing:border-box | content-box

不同的盒模型影响HTML标签在浏览器上实际渲染的屏幕像素面积,该属性规定了borderpadding属性值是否占用widthheight规定的内容区。

例如宽度width属性的值计算规则如下:

  • content-boxwidth=content width
  • border-boxwidth=content width + padding width + margin width

一言以蔽之,content-box的宽高是规定内容区宽高,border-box的宽高规定了content+border+padding三者和的宽高

CSS盒模型

五、position(定位)

关于定位,必要明确的就是定位的基准点是哪儿?

值说明static默认值,文档流正常位置,top、left、right、bottom、z-index无效relative相对定位,相对文档流原正常位置左上角偏移,不影响其他元素absolute绝对定位,脱离正常文档流,相对position!=static的父元素(包含块)左上角偏移fixed固定定位,脱离正常文档流,相对视口左上角偏移sticky粘性定位,相对文档流的包含块、滚动祖先元素左上角偏移,不影响其他元素

六、font-size(字号)& line-height(行高)

line-height带有单位时,计算行高的结果为line-height高度,line-height规定的是行高最小的的高度

line-height是相对单位时,line-height具有继承性,其子元素如果没有设置line-height,那么子元素的行高为父元素计算所得的行高值。

line-height值为纯数字时,当前行高会根据当前文本的 font-size*line-height 计算所得。

七、CSS选择器

7.1 通用选择器

.a.b:(无空格)当a和b在同一标签类名中同时出现才选择
.a .b:(有空格)选择a的所有后代b
.a>.b:(>)选择a的子代b
.a, .b:(,)a与b样式相同
.a+.b:(+)选择a紧邻的兄弟b
.a~.b:(~)有共同父元素,选择a后的所有b,ab不必紧邻

7.2 属性选择器:

  • [attr]:表示带有以attr命名的属性的元素。
  • [attr=value]:表示带有以attr命名的属性,且属性值为value的元素。
  • [attr~=value]:表示带有以attr命名的属性的元素,并且该属性是一个以空格作为分隔符的值列表,其中至少有一个值为value。
  • [attr|=value]:表示带有以attr命名的属性的元素,属性值为“value”或是以“value-”为前缀("-"为连字符,Unicode 编码为 U+002D)开头。典型的应用场景是用来匹配语言简写代码(如 zh-CN,zh-TW 可以用 zh 作为 value)。
  • [attr^=value]:表示带有以attr命名的属性,且属性值是以value开头的元素。
  • [attr$=value]:表示带有以attr命名的属性,且属性值是以value结尾的元素。
  • [attr*=value]:表示带有以attr命名的属性,且属性值至少包含一个 value 值的元素。

7.3 伪类选择器

:root :文档根元素

八、文本处理

font-stretch: normal;
font-kerning: normal;
text-rendering: optimizeLegibility;

文本是最基础最重要的功能之一,深入了解文本的渲染布局非常有必要。

关于文本处理相关的CSS,知识点较多且深,因此将在后续文章将详细解读,因为文字处理属于一个需要深入理解的领域,也是一个基础领域,在大部分的场景我们是不需要关心,但是如果涉及到精细化展示、兼容性的问题,就不得不涉及到文本渲染原理相关内容。

九、flex布局

.box {
    display: flex;  /* 还可以设置行内元素的 inline-flex */
    flex-direction: row; /* 主轴水平!:row:列(左至右);row-reverse:列(右至左)   主轴竖直!cloumn:行(上至下);column-reverse:行(下至上) */
    flex-wrap: nowrap; /* 一行放不下的时候:nowrap不换行,wrap换行,wrap-reverse换行第一行在下方  */
    /* flex-flow: row nowrap;  是上面两者的简写形式 */
    justify-content: flex-start;  /* 定义项目在主轴上的对齐方式  flex-start左侧,flex-end右侧,center居中,space-between两端对齐项目间隔相等,space-around项目左右两侧间距相同 */
    align-items: flex-start; /* 定义项目在纵轴上的对齐方式  flex-start上,flex-end下,center居中,baseline项目中第一行文字对齐,stretch默认值高度未设置时候将撑满容器高度 */
}
.item {
    order: 0;   /* 定义项目的排列顺序,数值越小越靠前,默认0 */
    flex-grow: 0;   /* 定义剩于空间的放大比例,默认0不放大,如果多个item均为1,则将等分剩于的空间,不同值按照比例分配剩于空间 */
    flex-shrink: 1; /* 定义项目缩小比例,默认为1,空间不足,均等比例缩小,为0则不缩小 */
    flex-basis: auto; /* 定义项目在分配剩于主轴空间之前的主轴占据的长度,浏览器会根据这个属性去计算是否有剩于的空间 */
    /* flex: auto; 是flex-grow、flex-shrink和flex-basis的简写默认值:0 1 auto */
    align-self: flex-start; /* 设置单个项目与其他项目不一样的对齐方式,可覆盖父容器设置的align-items,默认auto继承父元素的align-items值  auto | flex-start | flex-end | center | baseline | stretch */
}

上述是笔者对flex使用经验的一些精简总结,另外推荐大家阅读《Flexbox布局中不为人知的细节 - Alibaba F2E》,从原理层解读,研读完非常受用。

十、自定义CSS属性

example:

html {
    --theme-color: red;
    --theme-font-size: 16px;
}

.example {
    color: var(--theme-color);
    font-size: var(--theme-font-size);
}

因为是新的属性规则,在低版本设备上可能遇上不兼容情况,因此可以使用查询特性的@supports()

@supports(color: var(--theme-color)) {
    // 支持上面的的处理方式则下面的css将生效
    .class-box {
        color: var(--theme-color);
    }
}

// 对于selector的支持不好
@supports not (color: var(--theme-color)) {
    // 不支持上面的的处理方式则下面的css将生效
    .class-box {
        color: red;
    }
}

兼容性:https://caniuse.com/?search=%40supports

@support文档:https://developer.mozilla.org/zh-CN/docs/Web/CSS/@supports

总结

上述讲到了十个大的CSS知识点,也是工作开发过程中经常会遇到的细节问题,把这些知识点/CSS规则熟记于心,有利于高效率编写前端样式!