:target和:target-within都是 Selectors Level 4 模块中的两个伪元素。可能很多同学对:target更熟悉一些,甚至用:target伪元素的特性制作了 Tab 、Accordion 和 Modal 等UI交互效果。
比如下面这个手风琴的效果就是用:target伪元素制作的:
这里简单的来看看:target和:target-within的作用。
在某些文档语言中,文档的URL可以通过URL的片段进一步指向文档中的特定元素。以这种方式指向的元素是文档的目标元素。其中片段标识符是URL中紧跟#的部分,例如#top或#fontnote1。你可能已经使用它们创建页面内导航,比如大家常见的“跳转链接”。有了:target伪类,我们可以突出显示与该片段对应的文档部分,而且无需JavaScript也可以做到这一点。
比如下面这个简单的示例:
Table of Contents
- Jump to the first paragraph!
- Jump to the second paragraph!
- This link goes nowhere, because the target doesn't exist.
My Fun Article
You can target this paragraph using a URL fragment. Click on the link above to try out!
This is another paragraph, also accessible from the links above. Isn't that delightful?
/* CSS */
p:target {
background-color: gold;
}
/* 在目标元素中增加一个伪元素*/
p:target::before {
font: 70% sans-serif;
content: “►”;
color: limegreen;
margin-right: .25em;
}
/在目标元素中使用italic样式/
p:target i {
color: red;
}
你可以看到像下图的效果:
而:target-within伪类应用于:target伪类所应用的元素,以及在平面树(Flat Tree)的后代(包括非元素节点,比如文本节点)与匹配:target-within的条件相匹配的元素。
article:target-within {
background-color: hsl(var(–surfaceHSL) / 10%);
}
其实在选择器Level 4模块中还新增了很多其他的伪类选择器,如果你对这方面新增的选择器感兴趣的话,可以听一听@Adam Argyle和@Ana Tudor一起办的CSS Podcast,其中第十四期[15]就是专门聊CSS的伪类选择器的。
▐ CSS逻辑属性
如果你接触过CSS书写模式特性,你会发现以前我们熟悉的物理属性在不同的语言环境之下很难满足布局的需求,比如英语和阿拉伯语,日语和蒙语等,我们设置的margin-left有可能不是margin-left,width也有可能不是width。
这个时候,CSS逻辑属性就显得尤其重要。换句话说,逻辑属性的出现,我们以往熟悉的盒模型也将带来很大的变化:
下图是我们熟悉的物理属性和逻辑属性的对应关应:
对于块轴(block axis)和内联轴(inline axis)区别,同样用一张图来描述这两者吧:
块轴和内联轴和CSS的书写模式writing-mode以及direction和HTML的dir有关系。换句话说:
-
块轴:主要定义网站文档(元素块)流,CSS的书写模式writing-mode会影响块轴的方向。
-
内联轴:主要定义网站的文本流方向,也就是文本的阅读方式,CSS的direction或HTML的dir会影响内联轴的方向。
▐ min()、max()和clamp()
min()、max()和clamp()三个函数称为“比较函数”。早在《聊聊min(),max()和clamp()函数》一文中对其做过详细的介绍。这里不做详细介绍,仅和三张图来分别展示他们的功能。
我们可以使用 min()设置最大值:
max()和min()相反,返回的是最大值。使用max()设置一个最小值:
clamp()函数和min()以及max()不同,它返回的是一个区间值。clamp()函数接受三个参数,即 clamp(MIN, VAL, MAX),其中MIN表示最小值,VAL表示首选值,MAX表示最大值。它们之间:
-
如果VAL在MIN和MAX之间,则使用VAL作为函数的返回值;
-
如果VAL大于MAX,则使用MAX作为函数的返回值;
-
如果VAL小于MIN,则使用MIN作为函数的返回值。
这里有一个关于clamp() 的示例,尝试着拖动浏览器视窗的大小,你可以看到类似下图这样的效果:
我们再来看几个和文本相关的特性:
▐ leading-trim 和 text-edge
一直以来,在Web的排版中行高(line-height)总是令Web开发者感到困惑和头痛,主要是因为line-height在CSS中是一个非常复杂的体系。他的计算总是会涉及到很多因素:
@iamvdo的《Deep dive CSS: font metrics, line-height and vertical-align》一文对这方面做过深入的阐述!
在还原UI时,文本的行高总是让我们计算元素块之间的间距带来一定的麻烦:
为了解决这方面的烦恼, CSS Inline Layout Module Level 3新增了一个leading-trim和text-edge属性。可以让我们删除每一种字体中的额外间距,以便我们可以更好的计算相邻块元素之间的间距。
h1 {
leading-trim: both;
text-edge: cap alphabetic;
}
上面的示例首先使用text-edge来告诉浏览器想要的文本边缘是cap高度和字母基线(alphabetic baseline)。然后用leading-trim对文本两边进行修剪。
注意,leading-trim只影响文本框,它不会切断其中的文字。
示例中的两行简单的CSS创建了一个包含文本的干净的文本框(不受line-height相关的特性影响)。这有助于实现更精确的间距,并创建更好的视觉层次结构。
CSS的text-edge和leading-trim分别可接受的值:
text-edge: leading | [ text | cap | ex | ideographic | ideographic-ink ] [ text | alphabetic | ideographic | ideographic-ink ]?
leading-trim: normal | start | end | both
如果你对leading-trim特性感兴趣的话,除了阅读规范之外,还可以阅读下面几篇文章:
-
The Thing With Leading in CSS
-
Leading-Trim: The Future of Digital Typesetting
-
Rethinking line-sizing and leading-trim
▐ ::grammar-error 和 ::spelling-error
::grammar-error和::spelling-error是两个非常有意思的伪元素选择器。从字面说我们可以知道, Grammar error 指的是语法错误, Spelling error指的是拼写错误。其实这两种现象在我们平时书写文本的时候经常可见,可能会由于手误, 将某个单词或标点符号用错,甚至语法上的错误。针对于这种现象,我们总是希望有一定的提示信息来提示我们,比如颜色上的差异,添加一些下划线等等:
在 CSS Pseudo-Elements Module Level 4 的高亮伪元素中我们可以看到这两个伪元素的身影:
-
::grammar-error:浏览器为语法错误的文本段添加样式。
-
::spelling-error:浏览器为拼写错误的文本段添加样式。
在CSS中并不是所有属性都能运用于这两个伪元素,到目前为止,只有color、background-color、cursor、text-emphasis-color、text-shadow、outline、text-decoration、fill-color、stroke-color 和stroke-width可以用于这两个伪元素。
:root::spelling-error {
text-decoration: spelling-error;
}
:root::grammar-error {
text-decoration: grammar-error;
}
[spellcheck]::spelling-error {
text-decoration: wavy underline var(–neon-red);
}
[grammarcheck]::grammar-error {
text-decoration: wavy underline var(–neon-blue);
}
▐ 新增相对单位:cap、lh、rlh、vi和vb
CSS中单位和值中,单位有:
但在相对单位中并没有提到cap、lh、rlh、vi和vb这几个相对单位。
从上表的描述来看,其中cap、lh、rlh的计算都和元素的字体以及行高等有关系。我用下图来描述一个字体的Cap Height,Line Height等:
-