呜啦!日常碎碎念,偶尔掉落优质前端博文推荐、学习资源等
网页:https://tg.cosine.ren
本频道的搜索Bot 来辣 👉 @cosSearchBot
私聊直接发消息就可以搜索啦~
🔖tags
#优质博文 #资源推荐 #博客更新 #碎碎念 #项目更新 #手工 #书摘 #阮一峰的科技周刊 #新动态
图频:Cosine 🎨 Gallery @CosineGallery
猫片: @cosine_cat
联系频道主:@cosine_yu
网页:https://tg.cosine.ren
本频道的搜索Bot 来辣 👉 @cosSearchBot
私聊直接发消息就可以搜索啦~
🔖tags
#优质博文 #资源推荐 #博客更新 #碎碎念 #项目更新 #手工 #书摘 #阮一峰的科技周刊 #新动态
图频:Cosine 🎨 Gallery @CosineGallery
猫片: @cosine_cat
联系频道主:@cosine_yu
#优质博文 #前端 #碎碎念
使用 Next.js + Hexo 重构我的博客
想这么干很久了,不能再咕了呜呜呜呜再咕博客要坏掉了
打算用 Next.js + tailwind + ts 重构我这小博客了,顺便把坏掉的掘金外链图也修一修,预计排期:不知道。
使用 Next.js + Hexo 重构我的博客
想这么干很久了,不能再咕了呜呜呜呜再咕博客要坏掉了
打算用 Next.js + tailwind + ts 重构我这小博客了,顺便把坏掉的掘金外链图也修一修,预计排期:不知道。
Emoji Kitchen” 就可以直接使用网页版,生成结果还是比较有趣的和细致的,这个结果并不是生硬的进行拼凑,而是考虑到了很多场景(例如高楼大厦的黑夜+钻石,得到的是大厦中升起一颗钻石,而大厦的黑夜+蝎子,得到的就是一个哥斯拉级别的蝎子在拆楼,而不是楼中升起一只蝎子)#书摘 #css #前端
《CSS 选择器世界》使用 :active 伪类实现点击反馈
:active 伪类可以用于设置元素激活状态的样式,可以通过点击鼠标主键或者用手指或者触控笔点击触摸屏触发激活状态。具体表现如下,按下触发:active伪类样式,抬起取消:active伪类样式的应用。:active伪类支持任意HTML元素,例如
然而,落地实现时:active伪类并没有理论上那么完美,表现为以下3点。
1. IE浏览器下:active样式的应用是无法冒泡的
此时,点击
2. IE浏览器下,`<html>`、`<body>` 元素应用:active伪类设置背景色后,背景色是无法还原的。
具体来说,鼠标键按下时确实应用了:active设置的背景色,但是抬起后背景色没有还原,而且此时无论怎么点击鼠标,背景色都无法还原。这是一个很奇怪的bug,普通元素不会有此问题,这个问题甚至比在IE7浏览器下链接元素必须失焦才能取消:active样式还要糟糕。
3. 键盘访问无法触发:active伪类。例如,`<a>` 元素在focus状态下按下Enter键的事件行为与点击一致,但是,不会触发:active伪类。
4. 最后,:active伪类的主要作用是反馈点击交互,让用户知道他的点击行为已经成功触发,这对于按钮和链接元素是必不可少的,否则会有体验问题。由于:active伪类作用在按下的那一段时间,因此不适合用来实现复杂交互。
https://memo.cosine.ren/m/330
《CSS 选择器世界》使用 :active 伪类实现点击反馈
:active 伪类可以用于设置元素激活状态的样式,可以通过点击鼠标主键或者用手指或者触控笔点击触摸屏触发激活状态。具体表现如下,按下触发:active伪类样式,抬起取消:active伪类样式的应用。:active伪类支持任意HTML元素,例如
<div>`、`<span> 等非控件元素,甚至是自定义元素。然而,落地实现时:active伪类并没有理论上那么完美,表现为以下3点。
1. IE浏览器下:active样式的应用是无法冒泡的
img:active {
outline: 30px solid #ccc;
}
p:active {
background-color: teal;
}
<p><img src="1.jpg"></p>
此时,点击
<img> 元素的时候,在IE浏览器下,`<p>` 元素是不会触发:active伪类样式的,实际上祖先元素的:active样式也应当被应用;在Chrome和Firefox等浏览器下,其表现符合预期。2. IE浏览器下,`<html>`、`<body>` 元素应用:active伪类设置背景色后,背景色是无法还原的。
具体来说,鼠标键按下时确实应用了:active设置的背景色,但是抬起后背景色没有还原,而且此时无论怎么点击鼠标,背景色都无法还原。这是一个很奇怪的bug,普通元素不会有此问题,这个问题甚至比在IE7浏览器下链接元素必须失焦才能取消:active样式还要糟糕。
3. 键盘访问无法触发:active伪类。例如,`<a>` 元素在focus状态下按下Enter键的事件行为与点击一致,但是,不会触发:active伪类。
4. 最后,:active伪类的主要作用是反馈点击交互,让用户知道他的点击行为已经成功触发,这对于按钮和链接元素是必不可少的,否则会有体验问题。由于:active伪类作用在按下的那一段时间,因此不适合用来实现复杂交互。
https://memo.cosine.ren/m/330
#书摘 #css #前端
《CSS 选择器世界》:hover伪类与悬停交互开发
:hover 是各大浏览器最早支持的伪类之一,最早只能用在`<a>`元素上,其设计的初衷是改变链接元素的颜色:
由于 :hover 实现浮层元素的显示与隐藏效果非常方便,于是当时出现了很怪异的现象:`<a>`元素满天飞,甚至`<a>`元素里面嵌套`<div>`元素以实现悬停交互效果,完全不符合HTML元素原本语义。例如:
CSS所有新特性的出现都源自用户需求和开发需求。同样,当意识到仅`<a>`元素支持:hover伪类非常影响开发效率之后,浏览器迅速跟进升级。目前,所有主流浏览器中,:hover伪类已经可以在任意HTML元素中使用了,其中包括自定义元素:
需要注意的有如下几点,
- 如果是移动端开发,强烈建议不要使用:hover伪类实现交互效果,因为对于手机和iPad这类移动设备,常见的交互操作都通过触屏,而不是鼠标。虽然在这些设备上,:hover也能触发,但消失并不敏捷,体验反而不佳。
- 对于带有交互的行为,一定不能只使用:hover伪类,而需要额外的处理,可以通过增加:focus伪类来优化体验
- 但对于本身就带有链接或按钮的浮层元素,使用:focus伪类是不可行的,因为虽然可以触发浮层的显示,但是浮层内部的链接和按钮无法被点击,这是由于通过键盘切换焦点元素时浮层会因失焦而迅速隐藏。不过这是有其他解决方法的,那就是使用整体焦点伪类
《CSS 选择器世界》:hover伪类与悬停交互开发
:hover 是各大浏览器最早支持的伪类之一,最早只能用在`<a>`元素上,其设计的初衷是改变链接元素的颜色:
a { color: blue; }
a:hover { color: darkblue; }
由于 :hover 实现浮层元素的显示与隐藏效果非常方便,于是当时出现了很怪异的现象:`<a>`元素满天飞,甚至`<a>`元素里面嵌套`<div>`元素以实现悬停交互效果,完全不符合HTML元素原本语义。例如:
<a href="javascript:void(0)">
菜单
<div class="list">列表</div>
<a>
list {
display: none;
position:absolute;
}
a:hover .list {
display: block;
}
CSS所有新特性的出现都源自用户需求和开发需求。同样,当意识到仅`<a>`元素支持:hover伪类非常影响开发效率之后,浏览器迅速跟进升级。目前,所有主流浏览器中,:hover伪类已经可以在任意HTML元素中使用了,其中包括自定义元素:
x-element:hover {}
需要注意的有如下几点,
- 如果是移动端开发,强烈建议不要使用:hover伪类实现交互效果,因为对于手机和iPad这类移动设备,常见的交互操作都通过触屏,而不是鼠标。虽然在这些设备上,:hover也能触发,但消失并不敏捷,体验反而不佳。
- 对于带有交互的行为,一定不能只使用:hover伪类,而需要额外的处理,可以通过增加:focus伪类来优化体验
- 但对于本身就带有链接或按钮的浮层元素,使用:focus伪类是不可行的,因为虽然可以触发浮层的显示,但是浮层内部的链接和按钮无法被点击,这是由于通过键盘切换焦点元素时浮层会因失焦而迅速隐藏。不过这是有其他解决方法的,那就是使用整体焦点伪类
:focus-within
https://memo.cosine.ren/m/329#书摘 #css #前端
《CSS 选择器世界》 忽略属性值大小写的正则匹配运算符
正则匹配运算符是属性选择器中新增的运算符,它可以忽略属性值的大小写,使用字符i或者I作为运算符值,但约定俗成都以小写字母i作为运算符。语法如下:
作为对比示意,假设有选择器`[attr*="val"]`,则:
如果选择器是 `[attr*="val" i]`,则:
可以看到,属性值的大小写被忽略了。
https://memo.cosine.ren/m/328
《CSS 选择器世界》 忽略属性值大小写的正则匹配运算符
正则匹配运算符是属性选择器中新增的运算符,它可以忽略属性值的大小写,使用字符i或者I作为运算符值,但约定俗成都以小写字母i作为运算符。语法如下:
[attr~="val" i] {}
[attr*="val" i] {}
作为对比示意,假设有选择器`[attr*="val"]`,则:
<!-- 不匹配 -->
<div attr="VAL"></div>
<!-- 匹配 -->
<div attr="Text val"></div>
<!-- 不匹配 -->
<div attr="Value"></div>
<!-- 不匹配 -->
<div attr="Val-ue"></div>
如果选择器是 `[attr*="val" i]`,则:
<!-- 匹配 -->
<div attr="VAL"></div>
<!-- 匹配 -->
<div attr="Text val"></div>
<!-- 匹配 -->
<div attr="Value"></div>
<!-- 匹配 -->
<div attr="Val-ue"></div>
可以看到,属性值的大小写被忽略了。
https://memo.cosine.ren/m/328
《CSS 选择器世界》CSS属性选择器搜索过滤技术
我们可以借助属性选择器来辅助实现搜索过滤效果,如搜索通讯录、城市列表,这样做性能高,代码少。
HTML结构如下:
<input type="search" placeholder="输入城市名称或拼音" />
<ul>
<li data-search="重庆市chongqing">重庆市</li>
<li data-search="哈尔滨市haerbin">哈尔滨市</li>
<li data-search="长春市changchun">长春市</li>
...
</ul>
此时,当我们在输入框中输入内容的时候,只要根据输入内容动态创建如下CSS代码就可以实现搜索匹配效果了,无须自己写代码进行匹配验证。
var eleStyle = document.createElement('style');
document.head.appendChild(eleStyle);
// 文本框输入
input.addEventListener("input", function() {
var value = this.value.trim();
eleStyle.innerHTML = value ? '[data-search]:not([data-search*="'+ value +'"])
{ display: none; }' : '';
});
https://memo.cosine.ren/m/327#书摘 #css #前端
《CSS 选择器世界》6.3 属性值正则匹配选择器
属性值正则匹配选择器包括下面3种:
这3种属性选择器就完全是字符匹配了,而非单词匹配。其中,尖角符号`^`、美元符号`$`以及星号`*`都是正则表达式中的特殊标识符,分别表示**前匹配、后匹配和任意匹配**。
1.
- 这种选择器可以匹配中文,如果匹配的中文不包含特殊字符(如空格等),则引用中文的引号是可以省略的,例如:
- 理论上可以匹配空格,但由于IE浏览器会自动移除属性值首尾的空格,因此会有兼容性问题
例如,下面的样式可以对HTML格式进行验证:
实际开发中,开头正则匹配属性选择器用得比较多的地方是**判断`<a>`元素的链接地址类型**,也可以用来显示对应的小图标,例如:
2.
该选择器的使用细节和
**在实际开发中,结尾正则匹配属性选择器用得比较多的地方是判断`<a>`元素的链接的文件类型**,也可以用来显示对应的小图标。例如:
3.
它也可以用来匹配链接元素是否是外网地址,例如:
《CSS 选择器世界》6.3 属性值正则匹配选择器
属性值正则匹配选择器包括下面3种:
[attr^="val"]
[attr$="val"]
[attr*="val"]
这3种属性选择器就完全是字符匹配了,而非单词匹配。其中,尖角符号`^`、美元符号`$`以及星号`*`都是正则表达式中的特殊标识符,分别表示**前匹配、后匹配和任意匹配**。
1.
[attr^="val"]
[attr^="val"] 表示**匹配attr属性值以字符val开头的元素**。例如:
<!-- 匹配 -->
<div attr="val"></div>
<!-- 不匹配 -->
<div attr="text val"></div>
<!-- 匹配 -->
<div attr="value"></div>
<!-- 匹配 -->
<div attr="val-ue"></div>
- 这种选择器可以匹配中文,如果匹配的中文不包含特殊字符(如空格等),则引用中文的引号是可以省略的,例如:
[title^=我] {}
- 理论上可以匹配空格,但由于IE浏览器会自动移除属性值首尾的空格,因此会有兼容性问题
例如,下面的样式可以对HTML格式进行验证:
/*高亮类属性值包含多余空格的元素*/
[class^=" "] {
outline: 1px solid red;
}
实际开发中,开头正则匹配属性选择器用得比较多的地方是**判断`<a>`元素的链接地址类型**,也可以用来显示对应的小图标,例如:
/* 链接地址 */
[href^="http"],
[href^="ftp"],
[href^="//"] {
background: url(./icon-link.svg) no-repeat left;
}
/* 网页内锚链 */
[href^="#"] {
background: url(./icon-anchor.svg) no-repeat left;
}
/* 手机和邮箱 */
[href^="tel:"] {
background: url(./icon-tel.svg) no-repeat left;
}
[href^="mailto:"] {
background: url(./icon-email.svg) no-repeat left;
}
2.
[attr$="val"]
[attr$="val"] 表示**匹配attr属性值以字符val结尾的元素**。例如:
<!-- 匹配 -->
<div attr="val"></div>
<!-- 匹配 -->
<div attr="text val"></div>
<!-- 不匹配 -->
<div attr="value"></div>
<!-- 不匹配 -->
<div attr="val-ue"></div>
该选择器的使用细节和
[attr^="val"] 的一致,这里不再赘述。**在实际开发中,结尾正则匹配属性选择器用得比较多的地方是判断`<a>`元素的链接的文件类型**,也可以用来显示对应的小图标。例如:
/* 指向PDF文件 */
[href$=".pdf"] {
background: url(./icon-pdf.svg) no-repeat left;
}
/* 下载zip压缩文件 */
[href$=".zip"] {
background: url(./icon-zip.svg) no-repeat left;
}
/* 图片链接 */
[href$=".png"],
[href$=".gif"],
[href$=".jpg"],
[href$=".jpeg"],
[href$=".webp"] {
background: url(./icon-image.svg) no-repeat left;
}
3.
[attr*="val"]
[attr*="val"] 表示**匹配attr属性值包含字符val的元素**。例如:
<!-- 匹配 -->
<div attr="val"></div>
<!-- 匹配 -->
<div attr="text val"></div>
<!-- 匹配 -->
<div attr="value"></div>
<!-- 匹配 -->
<div attr="val-ue"></div>
它也可以用来匹配链接元素是否是外网地址,例如:
a[href*="//""]:not([href*="example.com"]) {}
https://memo.cosine.ren/m/326#书摘 #css #前端
《CSS 选择器世界》属性值直接匹配选择器
属性值直接匹配选择器包括下面4种:
这4种选择器的兼容性不错,IE8及以上版本的浏览器完全支持,IE7浏览器也支持,不过不完全,在极个别场景中有瑕疵。
1.
此时,如果想用属性选择器判断输入框是否禁用,可以直接使用下面的选择器,无须关心具体的属性值究竟是什么:
2.
(1) 不区分单引号和双引号,单引号和双引号都是合法的引号:
(2) 引号是可以省略的。例如:
如果属性值包含空格,则需要转义
3.
- 有些属性值(如class属性、rel属性或者一些自定义属性)包含多个关键词,这时可以使用空格分隔这些关键词,例如:
此时就可以借助该选择器实现匹配,例如:
匹配的属性值不能是空字符串。
- 如果匹配的属性值只是部分字符串,那么也是无效的。例如,有选择器 `[attr~="val"]`,则下面两段HTML都不匹配:
但是,如果字符串前后有一个或者连续多个空格分隔,则可以匹配:
4.
可以看到,这个选择器严格遵循属性值起始片段匹配的规则。
https://memo.cosine.ren/m/325
《CSS 选择器世界》属性值直接匹配选择器
属性值直接匹配选择器包括下面4种:
[attr]
[attr="val"]
[attr~="val"]
[attr|="val"]
这4种选择器的兼容性不错,IE8及以上版本的浏览器完全支持,IE7浏览器也支持,不过不完全,在极个别场景中有瑕疵。
1.
[attr]
[attr] 表示只要包含指定的属性就匹配,尤其适用于一些HTML布尔属性,这些布尔属性只要有属性值,无论值的内容是什么,就认为这些属性值为 true。例如,下面所有的输入框的写法都是禁用的:
<input disabled>
<input disabled="">
<input disabled="disabled">
<input disabled="true">
<input disabled="false">
此时,如果想用属性选择器判断输入框是否禁用,可以直接使用下面的选择器,无须关心具体的属性值究竟是什么:
[disabled] {}
2.
[attr="val"]
[attr="val"] 是属性值完全匹配选择器,例如:
[type="radio"] {}
[type="checkbox"] {}
(1) 不区分单引号和双引号,单引号和双引号都是合法的引号:
[type="radio"] {}
(2) 引号是可以省略的。例如:
[type=radio] {}
[type=checkbox] {}
如果属性值包含空格,则需要转义
3.
[attr~="val"]
[attr~="val"] 是属性值单词完全匹配选择器,专门用来匹配属性中的单词,其中,`~=` 用来连接属性和属性值。- 有些属性值(如class属性、rel属性或者一些自定义属性)包含多个关键词,这时可以使用空格分隔这些关键词,例如:
<a href rel="nofollow noopener">链接</a>
此时就可以借助该选择器实现匹配,例如:
[rel~="noopener"] {}
[rel~="nofollow"] {}
匹配的属性值不能是空字符串。
- 如果匹配的属性值只是部分字符串,那么也是无效的。例如,有选择器 `[attr~="val"]`,则下面两段HTML都不匹配:
<!-- 不匹配 -->
<div attr="value"></div>
<!-- 不匹配 -->
<div attr="val-ue"></div>
但是,如果字符串前后有一个或者连续多个空格分隔,则可以匹配:
<!-- 匹配 -->
<div attr=" val "></div>
<!-- 匹配 -->
<div attr="val ue"></div>
4.
[attr|="val"]
[attr|="val"] 是属性值起始片段完全匹配选择器,表示对于具有attr属性的元素,**其值要么正好是val,要么以val加短横线-(U+002D)开头**,|=用于连接需要匹配的属性和属性内容。
<!-- 匹配 -->
<div attr="val"></div>
<!-- 匹配 -->
<div attr="val-ue"></div>
<!-- 匹配 -->
<div attr="val-ue bar"></div>
<!-- 不匹配 -->
<div attr="value"></div>
<!-- 不匹配 -->
<div attr="val bar"></div>
<!-- 不匹配 -->
<div attr="bar val-ue"></div>
可以看到,这个选择器严格遵循属性值起始片段匹配的规则。
https://memo.cosine.ren/m/325
#优质博文 #前端 #组件库 #tailwind
2023 年前端 UI 组件库概述,百花齐放!
感觉不少 tailwind 组件库冒出来了mark 一下这个组件库
1. ShadCN/UI,跟我思想很接近。它提供了一种不同于其他库的开发方法。不需要通过npm安装组件或整个库,而是将代码直接复制粘贴到自己的代码库中。这样做的目的是让开发者完全拥有组件,并将设计和实现分离。它使用 Tailwind 进行构建,并提供了一个CLI工具,可以生成组件代码并调整tailwind.config.js文件。
2. NextUI:不要与 React 元框架 Next.js 混淆,这个库是使用 Tailwind CSS 构建的。它声称学习曲线很小。主题由tailwind.config.js文件处理,具备良好的可访问性,并且所有组件都支持暗黑主题。只需使用不同的 Tailwind 类名即可覆盖样式。
2023 年前端 UI 组件库概述,百花齐放!
感觉不少 tailwind 组件库冒出来了mark 一下这个组件库
1. ShadCN/UI,跟我思想很接近。它提供了一种不同于其他库的开发方法。不需要通过npm安装组件或整个库,而是将代码直接复制粘贴到自己的代码库中。这样做的目的是让开发者完全拥有组件,并将设计和实现分离。它使用 Tailwind 进行构建,并提供了一个CLI工具,可以生成组件代码并调整tailwind.config.js文件。
2. NextUI:不要与 React 元框架 Next.js 混淆,这个库是使用 Tailwind CSS 构建的。它声称学习曲线很小。主题由tailwind.config.js文件处理,具备良好的可访问性,并且所有组件都支持暗黑主题。只需使用不同的 Tailwind 类名即可覆盖样式。
#书摘 #css #前端
《CSS 选择器世界》第6章 被低估的属性选择器
前几章讲述了几个常用的、必须掌握的选择器,以及可以将选择器威力放大数倍的选择符,对新手而言,只要掌握前面这几章的内容,就能实现完全静态的网页布局效果,足以在生产环境中进行开发,再掌握一些基础且常用的CSS属性,就可以算是前端入门了。
但CSS这门语言入门简单,精深却不容易。以本书为例,从本章开始的所有内容都可以看作CSS选择器功能的增强,占据的篇幅达到60%~70%之大,但是覆盖的只是实际开发场景中的30%。
所有设计出的CSS选择器都是有针对性和应对场景的,其中可能有些场景不太常见,但是随着开发的不断深入,早晚会在实践中遇到,此时,如果能够使用对应的CSS选择器,则开发效率和实现效果都会很惊人。
举个例子,我们进行Web Components组件化开发的时候,要想知道组件是否已经被定义,如果你没有学习后面的内容,就要在JavaScript代码中埋一些标记量给CSS使用,其实,是有专门的名为:defined的伪类匹配这种场景的。
从本章开始,对内容的掌握程度决定了读者是普通的还是资深的CSS开发人员。
先介绍一个被大家低估的选择器——属性值匹配选择器。我们平常提到的属性选择器指的是[type="radio"]这类选择器,实际上,属性选择器是简称,其全称为“属性值匹配选择器”。 在正式文档中,类选择器和ID选择器都属于属性选择器,因为本质上类选择器是HTML元素中class的属性值,ID选择器是HTML元素中id的属性值。
(睡觉!下次再读)
《CSS 选择器世界》第6章 被低估的属性选择器
前几章讲述了几个常用的、必须掌握的选择器,以及可以将选择器威力放大数倍的选择符,对新手而言,只要掌握前面这几章的内容,就能实现完全静态的网页布局效果,足以在生产环境中进行开发,再掌握一些基础且常用的CSS属性,就可以算是前端入门了。
但CSS这门语言入门简单,精深却不容易。以本书为例,从本章开始的所有内容都可以看作CSS选择器功能的增强,占据的篇幅达到60%~70%之大,但是覆盖的只是实际开发场景中的30%。
所有设计出的CSS选择器都是有针对性和应对场景的,其中可能有些场景不太常见,但是随着开发的不断深入,早晚会在实践中遇到,此时,如果能够使用对应的CSS选择器,则开发效率和实现效果都会很惊人。
举个例子,我们进行Web Components组件化开发的时候,要想知道组件是否已经被定义,如果你没有学习后面的内容,就要在JavaScript代码中埋一些标记量给CSS使用,其实,是有专门的名为:defined的伪类匹配这种场景的。
从本章开始,对内容的掌握程度决定了读者是普通的还是资深的CSS开发人员。
先介绍一个被大家低估的选择器——属性值匹配选择器。我们平常提到的属性选择器指的是[type="radio"]这类选择器,实际上,属性选择器是简称,其全称为“属性值匹配选择器”。 在正式文档中,类选择器和ID选择器都属于属性选择器,因为本质上类选择器是HTML元素中class的属性值,ID选择器是HTML元素中id的属性值。
(睡觉!下次再读)
#书摘 #css #前端
《CSS 选择器世界》第5章 精通CSS选择符
2. 子选择符——箭头(>)
子选择符也是非常常用、重要的一个选择符,IE7浏览器开始支持,它和后代选择符有类似于“远房亲戚”的关系。子选择符只匹配第一代子元素,而后代选择符会匹配所有子元素。
子选择符是一把双刃剑,它通过限定关系使结构更加稳固,但同时失去了弹性和变化,需要审慎使用。
3. 相邻兄弟选择符——加号(+)
相邻兄弟选择符也是非常实用的选择符,它被IE7及以上版本的浏览器支持。它
可以用于选择相邻的兄弟元素,但只能选择后面一个兄弟元素。相邻兄弟选择符会忽略文本节点和注释节点,只认元素节点。
相邻兄弟选择符最有价值的应用还是配合诸多伪类以低成本实现很多实用的交互效果,它是众多高级选择器技术的核心。
- 场景1:用来实现类似:first-child伪类的效果。例如,我们希望除第一个列表以外的其他列表都有margin-top属性值,首先可以想到的就是:first-child,下面介绍另一种方法,那就是借助相邻兄弟选择符,如下:
由于相邻兄弟选择符只能匹配后一个元素,因此第一个元素不会被匹配,于是自然而然实现了非首列表元素的匹配。
实际上,此方法的适用范围比:first-child更广一些,例如,当容器的第一个子元素并非.cs-li的时候,相邻兄弟选择符这个方法依然有效,而:first-child此时却无效了,因为没有任何.cs-li元素是第一个子元素了,也就无法匹配:first-child。
- 场景2:当我们聚焦输入框的时候,如果希望显示后面的提示文字,可以借助相邻兄弟选择符轻松实现 —— 把提示文字预先埋在输入框的后面,当触发focus行为时,提示文字即可显示。HTML和CSS代码分别如下:
4. 随后兄弟选择符——波浪线(~)
随后兄弟选择符和相邻兄弟选择符的兼容性一致,都是从IE7浏览器开始支持的,可以放心使用。两者的实用性和重要程度也是类似的,它们的关系较近。
相邻兄弟选择符只会匹配它后面的第一个兄弟元素,而随后兄弟选择符会匹配它后面的所有兄弟元素。至于其他细节,两者是类似的,例如,随后兄弟选择符也会忽略文本节点和注释节点。
在CSS选择器世界中,并不存在前面兄弟选择符,但是我们在实际开发的时候,确实存在很多场景需要控制前面的兄弟元素,此时又该怎么办呢?
此时标题元素就是深天蓝色,虽然伪类的参数是相邻兄弟选择符,但是匹配的是前面的元素,详见9.4节。
《CSS 选择器世界》第5章 精通CSS选择符
2. 子选择符——箭头(>)
子选择符也是非常常用、重要的一个选择符,IE7浏览器开始支持,它和后代选择符有类似于“远房亲戚”的关系。子选择符只匹配第一代子元素,而后代选择符会匹配所有子元素。
子选择符是一把双刃剑,它通过限定关系使结构更加稳固,但同时失去了弹性和变化,需要审慎使用。
3. 相邻兄弟选择符——加号(+)
相邻兄弟选择符也是非常实用的选择符,它被IE7及以上版本的浏览器支持。它
可以用于选择相邻的兄弟元素,但只能选择后面一个兄弟元素。相邻兄弟选择符会忽略文本节点和注释节点,只认元素节点。
相邻兄弟选择符最有价值的应用还是配合诸多伪类以低成本实现很多实用的交互效果,它是众多高级选择器技术的核心。
- 场景1:用来实现类似:first-child伪类的效果。例如,我们希望除第一个列表以外的其他列表都有margin-top属性值,首先可以想到的就是:first-child,下面介绍另一种方法,那就是借助相邻兄弟选择符,如下:
.cs-li + .cs-li { margin-top: 1em; }
由于相邻兄弟选择符只能匹配后一个元素,因此第一个元素不会被匹配,于是自然而然实现了非首列表元素的匹配。
实际上,此方法的适用范围比:first-child更广一些,例如,当容器的第一个子元素并非.cs-li的时候,相邻兄弟选择符这个方法依然有效,而:first-child此时却无效了,因为没有任何.cs-li元素是第一个子元素了,也就无法匹配:first-child。
- 场景2:当我们聚焦输入框的时候,如果希望显示后面的提示文字,可以借助相邻兄弟选择符轻松实现 —— 把提示文字预先埋在输入框的后面,当触发focus行为时,提示文字即可显示。HTML和CSS代码分别如下:
用户名:<input><span class="cs-tips">不超过10个字符</span>

.cs-tips {
color: gray;
margin-left: 15px;
position: absolute;
visibility: hidden;
}
:focus + .cs-tips {
visibility: visible;
}
4. 随后兄弟选择符——波浪线(~)
随后兄弟选择符和相邻兄弟选择符的兼容性一致,都是从IE7浏览器开始支持的,可以放心使用。两者的实用性和重要程度也是类似的,它们的关系较近。
相邻兄弟选择符只会匹配它后面的第一个兄弟元素,而随后兄弟选择符会匹配它后面的所有兄弟元素。至于其他细节,两者是类似的,例如,随后兄弟选择符也会忽略文本节点和注释节点。
在CSS选择器世界中,并不存在前面兄弟选择符,但是我们在实际开发的时候,确实存在很多场景需要控制前面的兄弟元素,此时又该怎么办呢?
<h4 class="cs-h">标题</h4>
<p class="cs-li">列表内容</p>
.cs-h:has( + .cs-li) {
color: deepskyblue;
}
此时标题元素就是深天蓝色,虽然伪类的参数是相邻兄弟选择符,但是匹配的是前面的元素,详见9.4节。
#书摘 #css #前端
《CSS 选择器世界》第5章 精通CSS选择符
CSS选择符可以让选择器有更丰富的层级关系,使我们从容应对各种相对复杂的样式布局。
CSS选择符目前有下面这几个:后代选择符——空格( )、子选择符——箭头(>)、相邻兄弟选择符——加号(+)、随后兄弟选择符——波浪线(~)和列选择符——双管道(||)。其中对于前4个选择符,浏览器开始支持的时间较早,非常实用,是本章的重点。最后的列选择符算是“新贵”,与Table等布局密切相关,但目前浏览器的兼容性还不足以使它被实际应用,因此只简单介绍。
1. 后代选择符——空格( )
后代选择符是非常常用的选择符,随手抓取一个线上的CSS文件就可以看到这个选择符,它从IE6时代就开始被支持了。
后代选择符以空格作为分隔符,从前往后的选择器,只要匹配DOM由外而内的层级关系,就会匹配最后一个选择器对应的元素。
> 早些年我拿这道题做测试,结果全军覆没,无人答对,大家都认为1和2的颜色分别为深蓝色和浅蓝色。实际上正确答案是,1和2全部都是深蓝色
当包含后代选择符的时候,整个选择器的优先级与祖先元素的DOM层级没有任何关系,这时要看落地元素的优先级。在本例中,落地元素就是最后的<p>元素。两个<p>元素彼此分离,非嵌套,因此DOM层级平行,没有先后之分。再看选择器的优先级,.lightblue p和.darkblue p出现了一个类选择器(数值10)和一个标签选择器(数值1),选择器优先级数值一样。此时就要看它们在CSS文件中的位置,遵循“后来居上”的规则,由于.darkblue p位置靠后,因此<p>都是按照color:darkblue进行颜色渲染的,于是,最终1和2的文字颜色都是深蓝色。
《CSS 选择器世界》第5章 精通CSS选择符
CSS选择符可以让选择器有更丰富的层级关系,使我们从容应对各种相对复杂的样式布局。
CSS选择符目前有下面这几个:后代选择符——空格( )、子选择符——箭头(>)、相邻兄弟选择符——加号(+)、随后兄弟选择符——波浪线(~)和列选择符——双管道(||)。其中对于前4个选择符,浏览器开始支持的时间较早,非常实用,是本章的重点。最后的列选择符算是“新贵”,与Table等布局密切相关,但目前浏览器的兼容性还不足以使它被实际应用,因此只简单介绍。
1. 后代选择符——空格( )
后代选择符是非常常用的选择符,随手抓取一个线上的CSS文件就可以看到这个选择符,它从IE6时代就开始被支持了。
后代选择符以空格作为分隔符,从前往后的选择器,只要匹配DOM由外而内的层级关系,就会匹配最后一个选择器对应的元素。
> 早些年我拿这道题做测试,结果全军覆没,无人答对,大家都认为1和2的颜色分别为深蓝色和浅蓝色。实际上正确答案是,1和2全部都是深蓝色
<div class="lightblue">
<div class="darkblue">
<p>1. 颜色是?</p>
</div>
</div>
<div class="darkblue">
<div class="lightblue">
<p>2. 颜色是?</p>
</div>
</div>
.lightblue p {
color: lightblue;
}
.darkblue p {
color: darkblue;
}
当包含后代选择符的时候,整个选择器的优先级与祖先元素的DOM层级没有任何关系,这时要看落地元素的优先级。在本例中,落地元素就是最后的<p>元素。两个<p>元素彼此分离,非嵌套,因此DOM层级平行,没有先后之分。再看选择器的优先级,.lightblue p和.darkblue p出现了一个类选择器(数值10)和一个标签选择器(数值1),选择器优先级数值一样。此时就要看它们在CSS文件中的位置,遵循“后来居上”的规则,由于.darkblue p位置靠后,因此<p>都是按照color:darkblue进行颜色渲染的,于是,最终1和2的文字颜色都是深蓝色。
《CSS 选择器世界》规范与更多字符的合法性
顺着上面这个“不能以数字开头”的案例,我们讲解更多关于选择器命名合法性的内容。
首先,关于命名,看看规范中是如何描述的,如图3-4所示。
- 首字符支持的字符类型是
a~z`、`A~Z`、下划线(`_`)以及非 `ASCII 字符(中文、全角字符等)- 后面的字符支持的字符类型是
a~z`、`A~Z`、`0~9`、下划线(`_`)、短横线(`-`)以及非 `ASCII 字符,后面的字符支持的字符类型中多了数字和短横线。很多人对选择器的合法性认识就停留在上面所述内容的层面,而忽略了图3-4下面的“`escape`”方块。实际上,对于其他没有出现的字符,只要对它们 执行转义来重新编码 就能使其成为所支持的字符类型。也就是说,选择器不仅可以以数字开头,也支持以其他字符开头。这些字符可以是下面的这些。
1. 不合法的ASCII字符,如``!、"、#、$、%、&、'、(、)、*、+、,、-、.、/、:、;、<、=、>、?、@、[、\、]、^、`、{、|、}以及~``
严格来讲,上述字符也应该完全转义。例如,加号(+)的Unicode值是2b,因此选择器需要写成`\2b`加上空格,或者`\00002b`。
但是,对于上述字符,还有一种更优雅的表示方式,那就是直接使用斜杠转义,如
\+
包括IE在内的浏览器都支持上面的斜杠转义写法,因此可以放心使用。唯一需要多提一句的就是冒号(:),在IE7浏览器下,直接使用\:是不被支持的,如果你的项目需要兼容这种浏览器,可以使用\3a加上空格代替。(其实一般也不会用)2. 中文字符。下面的CSS也是有效的:
.我是foo { color: red; }
3. 中文标点符号,例如:
.。foo { color: red; }
4. emoji字符:
.☺ { color: red; }
「由于emoji字符在手机设备或者macOS系统上自动显示为emoji表情,因此有人会在实验性质的项目中使用emoji字符作为类名,这样,展示源代码的时候,会有一个个表情出现,挺有意思的。
至于其他转义字符,没有在实际项目中使用它们的任何理由。但我个人觉得对于中文命名可以一试。」
(我感觉其实也不用)