12个少有人知的CSS事实

一年多以前,我发布了最初的12个少有人知的CSS事实直到今天,它已经是sitepoint上最流行的文章。在那篇文章发布之后,我已经为一篇新文章收集了更多的CSS的小技巧和小篇幅的报导。因为我们都知道,每一个成功的电影都会产生一个俗气的续集,对吧!

让我们进入今年的开发者的12个CSS技巧。我确定我们当中许多人知道这些内容的一部分,但你可以在评论中让我知道这些技巧当中有多少对你来说是新的。

1.border-radius 属性可以用“slash(/)” 语法

这个是我四年多前在sitepoint上写过的内容,但我任然认为许多新手甚至是一些有经验的开发者都不知道的这个特性。

信不信由你,下面是一段有效的border-radius代码:

.box {border-radius: 35px 25px 30px 20px / 35px 25px 15px 30px ;} 

如果你从来没见过(译者:我是没见过),它可能似乎有点迷惑,所以,这里有个来自spec (译者注:spec指的是Standard Performance Evaluation Corporation,标准性能评估机构,http://www.spec.org) 的解释:

If values are given before and after the slash, then the values before the slash set the horizontal radius and the values after the slash set the vertical radius. If there is no slash, then the values set both radii equally.

译文:如果在 “/”的前后都给了值,那么在“/”前面的值设置水平radius,在“/”后面的值设置垂直radius。如果这里没有“/”,那么这些值同时设置radius。

下面是spec提供的一张图:

(译者:各位小伙伴们,看了这张图应该就明白了吧!:)

给那张图的解释是:border-radius-left-radius: 55pt 25pt 这两个值定义了角的曲度。

因此,slash的运用让你创造弯曲的角,而不是对称的。如果你想要知道更多对于这个的思考细节,可以去查看上面链接的以前的文章,或者试试这个链接https://developer.mozilla.org/en-US/docs/Web/CSS/Tools/Border-radius_generator大多数的border-radius生成器不允许你设置这些可选值,MDN生成器是我发现的唯一一个可以的。

2.font-weight属性接受相对关键字

通常,当我们看到font-weight属性被定义时,不是normal就是bold这些值。你可能也偶尔看到一个整百增加的整数值:100,200……等,增加到900.

然而,这两个值经常被忘记,bolder和lighter.

根据spec上,这些关键字具体说明了一个比继承的值更粗或者更细的字。当你在处理多种重量的字体的时候,这个显得尤为明显,bolder会比bold更粗,lighter会比一般的字细。

在基于整百的值,“bold”对应的是700,“normal”对应的是400。所以如果你有一个字是300的,但没有更低的,如果继承的值是400,一个“lighter”值可以使其减小到300,如果这里不支持更细的(IE中,400是最细的字),它会保持400,也就是“lighter”这个值无效。

让我们看看CodePen上的示例:

在这个例子中,我用了一个叫Exo 2的字体,它有18种不同的样式可用。我的例子中只用了non-italic样式的字,足够来当作基于整百的字。在这个例子中包括了12个拥有不同的font-weight 的“box”元素,包括“bolder”和“lighter”,因此你可以看到在不同的继承上下文中,这些值如何影响文本的字重。下面是来自这个例子的CSS。注意代码中的注解,每个后面的“box”都依赖前面的。

.box {font-weight: 100;}

.box-2 {font-weight: bolder; /* maps to 400 */}

.box-3 {font-weight: bolder; /* maps to 700 */}

.box-4 {font-weight: 400;}

.box-5 {font-weight: bolder; /* maps to 700 */} 

.box-6 {font-weight: bolder; /* maps to 900 */}

.box-7 {font-weight: 700;} 

.box-8 {font-weight: bolder; /* maps to 900 */} 

.box-9 {font-weight: bolder; /* maps to 900 */} 

.box-10 {font-weight: lighter; /* maps to 700 */}

.box-11 {font-weight: lighter; /* maps to 400 */}

.box-12 {font-weight: lighter; /* maps to 100 */}

在这个例子中,“bolder”和“lighter”关键字只能映射到100,400,700和900这些值。9种不同的风格,这些关键字永远不会映射到200,300,500,600和800这些值。发生的这种情况的原因是你告诉了浏览器要选择一系列字体中相邻的字体,它会把“bold”和“light”都考虑进去。因此不会去选择相邻最粗的或者相邻最细的字,而它的继承仅仅相对于bold和light。然而,如果最细的字是从300开始的(像在Open Sans的例子中https://www.google.com/fonts/specimen/Open+Sans),继承的值是四百,那么“lighter”的值回对应到300。

这可能在开始会有点迷惑,但是你可以围绕着这个例子摆弄一番,看看这些关键字是如何工作的。

3.这里有个outline-offset属性

outline属性因为它有帮助检查错误的能力而被人们熟知(可以看看这篇文章http://www.impressivewebs.com/css-things-that-dont-occupy-space/)。然而在spec上,已经增加了一个outline-offset属性,就像它名字所建议的那样——让你定义轮廓距离元素有多远。

在上面那个例子中,向左或右移动滑动条可以看到轮廓的变化。例子中的滑动的条范围在0px到30px之间,但是你可以在CSS中设置你想要的大小。

记住一点,尽管outline属性是个简写属性,但它并不包含outline-offset属性,所以你总是需要单独定义outline-offset。

outline-offset属性唯一主要的缺点就是除了IE浏览器(IE11也不例外)外其他浏览器都支持。

4.这里有个table-layout属性

你可能会认为这是旧新闻。我知道所有关于display: table的东西,bruh。垂直居中最简单的方法!但是那不是我想说的,注意我说的是table-layout属性,不是display属性。

table-layout属性解释起来不是最简单的CSS特性,所以让我们去spec,然后看一个例子。

spec上说:With this (fast) algorithm, the horizontal layout of the table does not depend on the contents of the cells; it only depends on the table’s width, the width of the columns, and borders or cell spacing.

译文:有个快速的算法,表格的水平布局不依赖单元格的内容;它仅依赖表格的宽度,列的宽度,边距或者单元格的空间。

在W3C的标准说明历史中,这可能是第一次觉得这个很难理解。但是认真地说,一个活生生的例子总是有帮助的。在下面这个例子中,CSS中表格已经有一个table-layout:fixed属性。点击按钮可以 打开或者关闭。(译者:此处的例子我以截图的形式来呈现。)

在这个例子中,你可以看到使用table-layout: fixed的优点,与默认auto相反。这不总是最好的选择,它也不总是需要的,但是记住,当你在处理有多个宽度的数据的表格时,这会是个很不错的属性。

Chris Coyier 去年在这个属性上写了个评论(https://css-tricks.com/fixing-tables-long-strings/),所以,如果你想更全面的论述,那是你最好的选择。

5.在表格中,vertical-align 属性的表现会不同于其他元素

如果你在零几年的时候写过网站,或者更早,或许你已经写了很多HTML邮件,那么在某种程度上你可能已经认为vertical-align属性是升级到旧版的HTML4的标准,现在在HTML5中是作为一个独立的,非相融的特性。

但是CSS中的vertical-align不是那样工作的。除了在表格中,我认为它很诡异,但是我认为这个属性不用在表格中会更清楚。所以,当这个属性用在常规的元素中与用在表格中相比,有什么不同吗?

当不应用在表格中时,vertical-align属性会遵循下面这些原则:

1.它只对inline或者inline-block元素有效;

2.它对一个元素的内容没什么影响,但是它会改变元素自身相对于其他inline或者inline-block元素的对齐方式;

3.它会受到text/font设置的影响,例如line-height和相邻inline或者inline-block元素的大小。

下面有个例子:

设置为baseline时所呈现的效果,

设置为top时所呈现的效果,

设置为text-top时所呈现的效果,

设置为text-bottom时所呈现的效果,

设置为super时所呈现的效果,

设置为sub时所呈现的效果,

设置为middle时所呈现的效果,

设置为bottom时所呈现的效果,

vertical-align属性在input元素中定义。通过按下其中的按钮,你能改变写在按钮中的值,你会注意到input中的每个值的位置发生了改变。总的来说,那个例子真的很基础的看到它的属性和值。为了更深的理解,可以查看这篇文章(http://christopheraue.net/2014/03/05/vertical-align/)

然而,当提到表格时,vertical-align效果很不同。这里有个例子,你可以为一个或多个表格设置属性/值,并且表格中的内容会被你选择的对齐方式所影响。

设置为baseline时,

设置为middle时,

设置为top时,

设置为bottom时,

在上面的例子中,在表格中只有四个值有效,尽管对于拥有baseline属性的兄弟元素有影响,但是主要的影响是对已经设置了vertical-align属性的单元格中的内容对齐方式上的影响。

6. ::first-letter伪元素比你认为的要聪明

::first-letter伪元素能让你设置一个元素的第一个字母的样式,能让你做出drop-cap效果(可以点击这个链接看到效果,https://en.wikipedia.org/wiki/Initial,相信很多人都见过),这个效果在印刷中很普遍。

关于这个的好消息就是,浏览器把:first-letter作为一个元素有着不错的标准。我第一次见到它是在这片文章中(https://twitter.com/andrewsmatt/status/497704502167076864),尽管他似乎在暗示那是一个不好的事情。你可以在下面的CodePen中看看他的例子。

在我看来,四大浏览器似乎在用同一种方式处理这些,所以,这很棒,因为我认为这是个正确的行为。如果一个左括号被视为一个“first-letter”,这会有点奇怪。那会更像“ first character”,我认为在它里面可以有一个全新的伪类。

7. 你可以在你的HTML class列表中使用无效的符号,例如分隔符

这个概念在2013年被Ben Everard讨论过,我认为很值得扩展它。

Ben的发表是有关使用slash(“/”)符号来分离他的HTML class到群中,让它的代码更容易阅读和浏览。他指出,虽然无法避免的slash是个无效的符号,但是浏览器不会堵住它,它们会忽略它。

所以,你可能有一段像这样的HTML例子:

<div class=”col col-4 col-8 c-list bx bx–rounded bx—transparent”>

有了slash后,它会变成这样:

<div class=”col col-4 col-8 / c-list / bx bx–rounded bx—transparent”>

你可以用任意的符号(无效的或者不)来产生同样的效果:

<div class=”col col-4 col-8 ** c-list ** bx bx–rounded bx—transparent”>

<div class=”col col-4 col-8 || c-list || bx bx–rounded bx—transparent”>

<div class=”col col-4 col-8 && c-list && bx bx–rounded bx—transparent”>

所有的这些变化似乎效果不错,你可以测试下面的例子:

当然,这些分隔符不能载你的层叠样式表中用作class。因此下面的例子是不合法的,并且不能得到具体的样式:

./{color: blue;}

如果你一定要在你的HTML class中用这些符号,来达到让他们指向你的CSS,你可以用这个工具来嵌入它们(https://mothereff.in/css-escapes)。因此,只有你的CSS看起来像这样,上面的例子才会有效。

.\/ {color: blue;}

更远一点,Unicode符号不用避免,所以你可以做这种疯狂的事:

<div class=”♥ ★”></div>

在你的 CSS中写入下面的东西:

.♥ {color: hotpink;}

.★ {color: yellow;}

要不,你也可以避免这类的符号,而不是直接插入他们。下面等同于前面的代码:

.\2665 {color: hotpink;}

 

.\2605 {color: yellow;}

8.动画反复可以是个极小的值

当在写CSS关键帧动画时,你可能知道你可以用animation-iteration-count属性来定义播放动画的次数:

.example {animation-iteration-count: 3;

例子中的整数值会告诉动画运行3次,但是你不知道你可以用极小的值:

.example {animation-iteration-count: .5;}

这种情况下,动画会运行一半的时间( 也就是它会停在中间)。让我们看一个例子,在一个页面中让两个球运动。上面的球有个一反复次数“1”,而下面有一个反复次数为“.5”。

(译者:这里需要指出的是,这个例子在Safari或者手机上不能正确的工作,这是因为填充模式下有个bug。我用safari测过,第二个球原本是停在中间的,但是运动到中间时,一下跑到跟上面的球相同的位置(如下图),请在chrome浏览器查看效果。)

关于这个还有歌有趣的地方,就是反复持续时间不是基于property/value来运动的。换句话说,如果运动距离是100px, 一半的路程不一定是在50px的位置。例如,前面的动画用了一个时间函数linear,所以可以确定的是第二个球会停在路程一半的位置。

这里有相同的两个动画,这次用了时间函数ease:

(由于是动画,所以这里无法展示了,请在原文中预览)

如果你理解了时间函数,那么你也会注意到ease-in-out这个值会把球停在跟linear同样的位置。围绕持续时间值来搬弄一番,时间函数会让你看到不同的结果。

9.动画简写会由于动画的名字而被破坏

一些开发者已经无意间发现这个,并且在spec中有个警告。让我来跟你说说下面的动画代码:

@keyframes reverse {from { left: 0;} to { left: 300px;}} 

.example {animation: reverse 2s 1s;}

注意我使用了reverse这个名字来做动画名。第一看上去这似乎还不错,但是当我们把上面的代码用在下面的在线例子是,注意到发生了什么。

动画没效,因为reverse对于animation-direction属性来说是个有效的关键字。这会发生在任何动画名与有效关键字相同并使用了简写语法的动画上,而普通写法不会发生这种情况。

动画名字会破坏掉任何包含有时间函数关键字的简写语法的动画,例如infinite,alternate,running,paused,等等。

10.你可以选择某个范围的元素

我不知道谁第一个用这个,但是我第一次看到它的时候是在这个例子中(http://bittersmann.de/samples/08-15)。

让我来跟你讲讲有一个20个元素的有序列表,你想要选择7到14这些元素。你如何做,你可以用个单一的选择器:

ol li:nth-child(n+7):nth-child(-n+14) {background: lightpink;}

(在 Safari浏览器下会有个bug, 导致它不能正常工作,这里有个解决办法,只需要简单的反转一下就可以了ol li:nth-child(-n+14):nth-child(n+7))

这个代码运用了链式结构伪类表达式。尽管表达式本身可能会有点让人困惑,你可以看看在表达式中通过数字所指向的范围。

确切的解释这段代码做了什么:在链条的第一部分,表达式说“选择第七个元素,和它之后的每一个元素”。第二部分说“选择第14个元素,和它之前的每一个元素”。但是选择器被链在了一起,每个都限制了前面的一个的作用域。所以第二部分的代码不会让第一部分的通过14,而第一部分的代码不会让第二部分返回超过7 。

想要更多这些选择器和表达式的描述细节,你可以阅读我过去发表过的文章(http://www.impressivewebs.com/css3-pseudo-class-expressions/)。

11. 伪元素可以被用在一些空元素中

如果你喜欢我,在某个时候你可能会试着应用一个伪元素到一张图片或者一个表单输入中。这不会有效,因为伪元素不会在作用在被替换的元素上。我想许多开发者都有假设空元素(指那些没有闭合标签的元素)都在那个分类下,但事实不是。

你可以应用一个伪元素到一些不能被替换的空元素上。包括hr元素,下面这个例子:

在那个例子中,颜色区域是个水平的分割线(hr元素),而且同时有::before和::after伪元素应用在上面。有趣的是,用我br元素却无法得到相同的结果,br元素也是个非替换的空元素。

你也可以添加伪元素到meta标签和link元素,如果你足够疯狂,把这些转换成display: block,就像下面的例子。

12.在选择器中一些属性值不区分大小写

最后,有一个有点费解的东西。让我来讲讲下面这些HTML:

<div class=”box”></div>

<input type=“email”>

你可以用属性选择器同时来定义它们的样式,像这样:

div[class=”box”] {color: blue;}

input[type=”email”] {border: solid 1px red;}

这样效果不错,但是这样呢?

div[class=”BOX”] {color: blue;}

input[type=”EMAIL”] {border: solid 1px red;}

注意到属性值现在都是大写的。在这种情况下,.box元素不会接收到这些样式,因为class属性是大小写敏感。email区域,换句话说,会得到这些样式,因为type属性值是大小写不敏感的。没必要在这里突破,但是它可能是你以前没意识到的。

最后总结

在这个希望不那么俗套的续集上,正式地挂上序幕了。

那种感觉像是每周我都在学一点CSS的小花絮,我希望这些信息大多数对你来说是新的。你偏好什么,费解的CSS花招还是技术?是否还有一个属性或者其他的特性让你认为不那么了解的,但是有兼容性不错的?在评论中让我们知道吧!

译者语:

这篇文章总算是翻译完了,原文的意思就是这些。这里面有很多特性是少有人知的,但是却是很有用的东西,希望各位小伙伴们能够弄懂这些。诸多翻译不是很恰当,但意思很明确,还请各位见谅,有什么问题,可以随时讨论!上面的所有例子建议大家到原文实际操作一下,看看真实的效果!

未经允许不得转载:爱前端网 » 12个少有人知的CSS事实

赞 (0) 打赏


觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏