呜啦!日常碎碎念,偶尔掉落优质前端博文推荐、学习资源等
网页:https://tg.cosine.ren
本频道的搜索Bot 来辣 👉 @cosSearchBot
私聊直接发消息就可以搜索啦~
🔖tags
#优质博文 #资源推荐 #博客更新 #碎碎念 #项目更新 #手工 #书摘 #阮一峰的科技周刊 #新动态

图频:Cosine 🎨 Gallery @CosineGallery
猫片: @cosine_cat
联系频道主:@cosine_yu
#碎碎念 #tailwind #资源推荐 #css
@tailwindcss/typography 太牛了吧,还是今天搭博客的时候发现的,官方的 Tailwind CSS Typography 插件提供了一组 prose 类,可以使用它们向您无法控制的任何普通 HTML 添加漂亮的版式默认值,例如从 Markdown 渲染的 HTML 或从 CMS 提取的 HTML。好评! GitHub - tailwindlabs/tailwindcss-typography: Beautiful typographic defaults for HTML you don't control.
#资源推荐 #前端 #react #markdown
今天在搭建自己的博客,关于markdown渲染和解析元数据找了这两个库:
1. markdown-to-jsx 最轻量级、可定制的 React markdown 组件。
2. gray-matter 从字符串或文件中解析 front-matter。快速、可靠且易于使用。默认情况下解析 YAML front-matter,但也支持 YAML、JSON、TOML 或 Coffee Front-Matter GitHub - probablyup/markdown-to-jsx: 🏭 The most lightweight, customizable React markdown component.
#资源推荐 #css #tailwind
无意中发现的 Tailwind CSS
Color Generator
—— 输入十六进制代码或更改 HSL 值,创建Tailwind自定义色阶
#书摘 #css #前端
《CSS 选择器世界》 任意匹配伪类: is()
:is()
伪类可以把括号中的选择器依次分配出去,这对于复杂的有很多逗号分隔的选择器或者浏览器可能不支持的选择器非常有用。

:is()
伪类本身的优先级为0,整个选择器的优先级是由:is()伪类里参数优先级最高的那个选择器决定的。例如: :is(#article, .section) p {}​​ 优先级等同于 #article p 。这是由参数中优先级最高的选择器决定的。
1. :is() 伪类的语法和两大作用
先讲解 :is()`伪类的语法。和 :not()` 伪类不同,`:is()` 伪类的参数从一开始就支持复杂选择器或复杂选择器列表。例如,下面的写法都是合法的:


/* 简单选择器 */
:is(article) p {}
/* 简单选择器列表 */
:is(article, section) p {}
/* 复杂选择器 */
:is(.article[class], section) p {}
/* 带逻辑伪类的复杂选择器 */
.some-class:is(article:not([id]), section) p {}​​



:is()伪类的一大作用是简化选择器。例如,平时开发中经常会遇到类似下面的CSS代码:


.cs-avatar-a > img,
.cs-avatar-b > img,
.cs-avatar-c > img,
.cs-avatar-d > img {
display: block;
width: 100%; height: 100%;
border-radius: 50%;
}​​



此时就可以使用:is()伪类进行简化:


:is(.cs-avatar-a, .cs-avatar-b, .cs-avatar-c, .cs-avatar-d) > img {
display: block;
width: 100%; height: 100%;
border-radius: 50%;
}​​



这种简化只是一维的,:is()伪类的优势并不明显,但如果选择器是交叉组合的,:is()伪类就大放异彩了。例如,有序列表和无序列表可以相互嵌套,假设有两层嵌套,则最里面的 <li> 元素存在下面4种可能的情况:


ol ol li,
ol ul li,
ul ul li,
ul ol li {
margin-left: 2em;
}​​



如果使用:is()伪类进行简化,则只有下面这几行代码:

css
:is(ol, ul) :is(ol, ul) li {
margin-left: 2em;
}​​



2. :is() 伪类在Vue等框架中的妙用
按道理讲,下面两行CSS语句中的选择器所匹配的元素是没有任何区别的,因为此时:is()伪类仅仅是一个无关紧要的语法糖,既不影响选择器的优先级,也不影响匹配的规则:


.box .some-class {}
.box :is(.some-class) {}​​



如果是在常规的开发场景中,确实如此,但要是在Vue或者React等成熟的框架中,则情况就会不同,可以利用这种特性让我们的开发变得更顺畅。

以Vue框架为例,在Vue框架中,无论是构建模块还是组件,都会使用设置了scoped属性的样式,目的是让CSS私有,避免和外部CSS发生冲突。例如:


<style scoped>
.logo {
height: 6em;
padding: 1.5em;
}
</style>​​



此时框架会给类名.logo创建随机的属性选择器,这样可以确保.logo匹配的元素在当前Vue模块中是唯一的。

但是当我们需要匹配的元素是动态生成的时候(业务逻辑插入或者第三方组件),这种给类名添加随机属性选择器的特性可能会导致元素无法匹配。例如运行下面这段JavaScript代码:


const html = ’<img src=”/vite.svg“ class=”logo“ />‘
const app = document.getElementById(’app‘)
app.insertAdjacentHTML(’afterbegin‘, html)​​



此时插入的 <img> 元素是不会被框架添加随机属性值的(如图9-3所示),而 <style> 元素中类名却自动添加了属性选择器,导致样式无法匹配。

如果此时希望可以匹配这个 <img> 元素,同时CSS代码又要写在设置了scoped属性的 <style> 元素中,该怎么办?除Vue框架内置的:deep()语法外,我们还可以使用:is()伪类。不知是出于什么考虑,所有:is()伪类中的选择器在Vue框架中都是不会添加随机属性选择器的(:where()伪类也有此特性),因此,我们可以利用这个特性,让设置了scoped属性的 <style> 元素中的CSS无属性匹配。例如,CSS代码可以这样书写:

<style scoped>
* > :is(.logo) {
height: 6em;
padding: 1.5em;
}
</style>​​


此时,CSS代码中的.logo选择器就是干干净净的类选择器,如图9-4所示,此时,哪怕页面中的HTML元素没有被组件添加随机属性值,也能被匹配了。

虽然:is()伪类因这一特性在意想不到的地方发挥着作用,但其还是有令人遗憾的地方,尤其是不支持伪元素这一点::is()伪类并不支持伪元素,例如:is(::before, ::after)是不合法的,这是个巨大的遗憾

目前现代浏览器已经全面支持:is()伪类,大家可以在一些内部项目中大胆使用。

https://memo.cosine.ren/m/362
Hover Card Effect

❗️ Source Code

Save and Share 🚀

👉 @frontend_trend
#前端 #优质博文 #小程序
分享 11 个 yyds微信小程序开源项目
mark一下,万一哪天用了呢

1. UrShop -多店铺SAAS+三级分销微信小程序
2. ChatGPT-MP -基于 ChatGPT 实现的微信小程序,适配 H5 和 Web 端
3. 前端铺子 -基于 Vue,使用 colorUi 与 uView,完美支持微信小程序
5. 叮点跑腿 -小程序采用 uniapp 实现的一套跑腿下单接单系统
6. wanyue_dangjian -一套智慧党建小程序管理系统
7. GarbageSort -一套垃圾识别精灵基于 uni-app 开发的微信小程序
8. QuestionWechatApp -智慧考题宝小程序适用于考核,评测等场景
9. BookChatApp -通用书籍阅读APP,使用 uni-app 实现,支持多端分发
10. Mall4j商城 -一个基于Vue、element ui 的轻量级、前后端分离、拥有完整 sku和下单流程的开源商城的小程序端
11. WeTravel -一个为游客朋友提供多元化服务的一站式数字文旅平台
12. bee -餐饮点餐微信小程序商城,是针对餐饮行业推出的一套完整的餐饮解决方案
#书摘 #css #前端
《CSS 选择器世界》 不容小觑的逻辑组合伪类

标签选择器、属性选择器直接匹配元素,树结构伪类通过DOM结构进行匹配,而本章要介绍的伪类则通过逻辑进行匹配,这进一步增强了CSS选择器对HTML元素匹配的能力。

目前CSS中的逻辑组合伪类主要有4个,分别是 :not() 、`:is()` 、`:where()` 和 :has() 。这4个伪类自身的优先级都是0,当伪类选择器自身和括号里的参数作为一个整体时,整个选择器的优先级各有差异,有的由参数选择器决定,如:not(),有的参数选择器的优先级也是0,如:where()。

:not()伪类从IE9浏览器就开始支持,非常实用,务必掌握。其他3个伪类适用于无须兼容IE浏览器的项目,其中的:has()伪类是一个功能强大的伪类,可以实现类似于父选择器的效果,日后定是个“大杀器”,大家一定要重点关注。现在先从:not()伪类说起

1. :not() 是否定伪类,如果当前元素与括号里的选择器不匹配,则该伪类会进行匹配。:not()伪类其他相关细节如下。
- :not( 伪类的优先级是0,即最终选择器的优先级是由括号里的表达式决定的。例如 :not(p) {}​​ 的优先级就是p选择器的优先级。
- :not( 伪类可以不断级联。例如:

input:not(:disabled):not(:read-only) {}​​



表示匹配所有不处于禁用状态也不处于只读状态 <input> 元素。
- 从2021年开始,所有现代浏览器均已支持在:not()伪类中使用多个表达式,例如下面这种写法是合法的:

/* 现代浏览器均支持 */
.cs-li:not(li, dd) {}​​



但是在过去,浏览器是无法解析上述用法的,需要使用下面这种冗长的写法代替:


.cs-li:not(li):not(dd) {}​​



在过去,下面几种写法也不支持,但是现在没有这个限制了,只要项目无须兼容IE浏览器,就可以放心使用。


/* 过去不支持,现在均支持 */
input:not(:disabled:read-only) {}
input:not(p:read-only) {}
input:not([id][title]) {}​​



此外,`:not()` 伪类的参数值不仅可以是选择器,还支持选择符。例如下面的语句也是可以被现代浏览器解析的:


/* 现代浏览器均支持 */
input:not(.a > .b) { border: red solid; }​​



2. 告别重置,全部交给:not()伪类
:not()伪类的最大用处就是可以优化过去我们重置CSS样式的策略。由于重置样式在Web开发中非常常见,因此:not()伪类的适用场景非常广泛。例如:


.cs-panel {
display: none;
}
.cs-panel.active {
display: block;
}​​



实际上,这种效果有更好的实现方式,那就是使用:not()伪类,推荐使用下面的CSS代码:


.cs-panel:not(.active) {
display: none;
}​​



使用:not()伪类有如下优点。
(1)使代码更简洁。
(2)更易于理解。
(3)最重要的是**保护了原类名的优先级,扩展性更强**,更利于维护。

对于某类重置场景,如果:not()伪类使用不当,可能会有预料之外的情况出现。例如,对于一些阅读类的网站,希望 <article> 元素内的 <ol>`、 `<ul> 元素依然保留默认的样式,不希望被重置。传统的实现一般是外部CSS重置,在 <article> 元素里再还原,CSS示意代码如下:


ol, ul {
padding: 0;
margin: 0;
list-style-type: none;
}
article ol,
article ul {
all: revert;
}​​



有些读者学了本节的内容后会想到使用:not()伪类来实现,然后使用了如下的CSS代码:

:not(article) ol,
:not(article) ul {
padding: 0;
margin: 0;
list-style-type: none;
}​​



实际上这是有问题的。例如,有如下HTML代码:


<article>
<div>
<ol>
<li>内容1</li>
<li>内容2</li>
<li>内容3</li>
</ol>
</div>
</article>​​



这里的 <ol> 元素的margin和padding等CSS属性样式理论上不应该被重置,但实际上这些样式都被重置了,因为 <ol> 元素外面的 <div> 元素也匹配 :not(article) ol 选择器。

所以,对于这种场景,:not()伪类的使用并没有想象的那么简单,不过也不是不能实现,而是需要使用:not()伪类在CSS选择器Level4规范中的新语法,也就是使用选择符:


ol:not(article ol),
ul:not(article ul) {
padding: 0;
margin: 0;
list-style-type: none;
}​​



上面的例子有演示页面,读者可以通过链接https://demo.cssworld.cn/selector2/9/1-1.php 访问。

https://memo.cosine.ren/m/357
#书摘 #css #前端
《CSS 选择器世界》匹配类型的子索引伪类 —— :nth-of-type() 伪类和 :nth-last-of-type() 伪类
1. :nth-of-type() 伪类匹配指定索引的当前标签类型元素,:nth-of-type()伪类从前面开始匹配,而:nth-last-of-type()伪类从后面开始匹配。
- :nth-of-type() 伪类和 :nth-child() 伪类的相同之处是它们的语法一
- :nth-of-type() 伪类和 :nth-child() 伪类的不同之处是::nth-of-type() 伪类的匹配范围是所有相同标签的相邻元素, 而:nth-child() 伪类会匹配所有相邻元素,忽略标签类型。
-

2. :nth-of-type() 伪类适用于特定标签组合且这些组合会不断重复的场景。在整个HTML中,这样的组合元素并不多见,较为典型的是“dt+dd”组合:


<dl>
<dt>标题1</dt>
<dd>内容1</dd>
<dt>标题2</dt>
<dd>内容2</dd>
</dl>​​


以及“details > summary”组合:


<details open>
<summary>订单中心</summary>
<a href>我的订单</a>
<a href>我的活动</a>
<a href>评价晒单</a>
<a href>购物助手</a>
</details>​​


这段代码中的 <a> 元素就可以使用 :nth-of-type() 伪类进行匹配。

https://memo.cosine.ren/m/355
#书摘 #css #前端
《CSS 选择器世界》匹配类型的子索引伪类 —— :first-of-type 伪类和 :last-of-type 伪类和 :only-of-type 伪类
匹配类型的子索引伪类类似于子索引伪类,区别在于,匹配类型的子索引伪类是在同级列表中相同标签元素之间进行索引与解析的

写HTML的时候要注意使用语义化标签,甚至可以使用自定义标签,因为要想使本节中的这些伪类在项目中大放异彩,离不开标签的区分,如果全部都是类是在同级列表中相元素,就无法使用这些伪类。

1. :first-of-type 表示当前第一个标签类型的元素。例如:


dl > :first-of-type {
color: deepskyblue;
font-style: italic;
}
<dl>
<dt>标题</dt>
<dd>内容</dd>
</dl>​​


结果:first-of-type伪类匹配了 <dt> <dd> 元素,文字表现为深天蓝色倾斜体

如果有如下HTML代码,其中有多个 <dt> <dd> 元素,则对于后面的 <dt> <dd> 元素,`:first-of-type` 伪类不会匹配,文字表现为默认的黑色且非倾斜体,代码如下:


<dl>
<dt>标题1</dt>
<dd>内容1</dd>
<dt>标题2</dt>
<dd>内容2</dd>
</dl>​​


标题2和内容2不会被匹配

2. :last-of-type 伪类的语法和匹配规则与 :first-of-type 的类似,区别在于,`:last-of-type` 伪类匹配最后一个同类型的标签元素。在上面的代码中就是匹配标题1和内容1。

3. :only-of-type 伪类
:only-of-type 表示匹配唯一的标签类型的元素。例如:
使用:only-of-type伪类也可以匹配例1中的 <dt> <dd> 元素,因为这两种类型的标签均只有一个。

> :only-child伪类匹配的元素,:only-of-type伪类一定匹配。但是:only-of-type伪类匹配的元素,:only-child伪类不一定匹配。

:only-of-type伪类缺少典型的应用场景,大家需要根据实际情况适时使用。

https://memo.cosine.ren/m/354
#书摘 #css #前端
《CSS 选择器世界》nth-child()的参数索引特性
对于nth-child()、nth-last-child() 以及8.4.3节要介绍的 nth-of-type()、nth-last-of-type(),还有一种大家可能没见过的语法,就是使用 of 关键字配合特性的CSS选择器,对已经匹配的树结构元素进行进一步的匹配。例如,有如下HTML结构和CSS代码:


<dl>
<dt>标题</dt>
<dd>列表1</dd>
<dd>列表2</dd>
<dd>列表3</dd>
<dt>标题</dt>
<dd>列表1</dd>
<dd>列表2</dd>
<dd>列表3</dd>
<dt>标题</dt>
<dd>列表1</dd>
<dd>列表2</dd>
<dd>列表3</dd>
</dl>
dl > :nth-child(even of dd) {
color: red;
font-weight: bold;
}​​


表示匹配所有子元素集合中的偶数项的 <dd> 元素。

顺便提一下,选择器:nth-child(even of dd)和选择器dd:nth-child(even)是不一样的,even关键字是相对整个子元素而言的,而不是仅相对于 <dd> 元素。

另外,of后面的选择器除了标签选择器,类名选择器、属性选择器都是支持的,可以让子元素的匹配更加精准可控。可惜这个特性目前仅被Safari浏览器支持,Chrome等浏览器暂时没有支持的迹象,因此,大家先了解即可。

https://memo.cosine.ren/m/353
#博客更新
NestJS 学习之优秀项目分析与最佳实践
这篇写的超用心!一不小心一天就过去了。

AI 生成的摘要:这篇文章是关于NestJS学习的优秀项目分析与最佳实践。文章介绍了NestJS的基本概念和模块,并通过分析优秀项目和代码示例来帮助读者更好地理解和应用NestJS。文章还解释了常见的后端术语和目录结构,以及模块、服务、控制器等的作用和用途。通过阅读这篇文章,读者可以更全面地了解NestJS的架构和设计理念,提高后端开发的效率和自信。

Hexo博客链接🔗 https://ysx.cosine.ren/nest-learn-project-1
xLog链接🔗 https://x.cosine.ren/nest-learn-project-1
RSS订阅 📢 https://x.cosine.ren/feed/xml
#书摘 #css #前端
《CSS 选择器世界》:nth-child()伪类和:nth-last-child()伪类
:nth-last-child()伪类和:nth-child()伪类的区别在于:
:nth-last-child()伪类是从后面开始按指定序号匹配,而:nth-child()伪类是从前面开始匹配。

除此之外,无论是在兼容性还是语法方面,两者都没有区别。因此,本节会以:nth-child()为代表对这两个伪类进行详细且深入的介绍。

1. 从:nth-child()开始说起
在介绍语法之前,有必要提一句,:nth-child()伪类虽然功能很强大,但只适用于内容动态、无法确定的匹配场景。如果数据是纯静态的,哪怕是列表,都要使用类名或者属性选择器进行匹配。没有必要使用 :nth-child(),因为这样会增加选择器的优先级,且由于DOM结构严格匹配,无法随意调整,不利于维护。

:nth-child()伪类可以匹配指定索引序号的元素,支持一个参数,且必须有参数,参数可以是关键字值或者函数符号这两种类型。
(1)关键字值的形式如下。
odd :匹配第奇数个元素,如第1个元素、第3个元素、第5个元素……
even :匹配第偶数个元素,如第2个元素、第4个元素、第6个元素……
可以这样记忆:如果字母个数是奇数(odd有3个字母),就匹配奇数个数的元素;如果字母个数是偶数(even有4个字母),就匹配偶数个数的元素。
奇偶匹配关键字多用在列表或者表格中,可以用来实现提升阅读体验的斑马线效果。
(2)函数符号的形式如下。
● An+B:其中A和B都是固定的数值,且必须是整数;n可以理解为从0开始的自然数序列(0, 1, 2, 3, …),n前面可以有负号。第一个子元素的匹配序号是1,小于1的计算序号会被忽略。
下面来看一些示例,快速了解一下各种类型的参数的含义。
tr:nth-child(odd) :匹配表格的第1, 3, 5行,等同于tr:nth-child(2n+1)。
tr:nth-child(even) :匹配表格的第2, 4, 6行,等同于tr:nth-child(2n)。
:nth-child(3) :匹配第3个元素。
:nth-child(5n) :匹配第5, 10, 15, …个元素。其中5=5×1,10=5×2,15=5×3……
:nth-child(3n+4) :匹配**第4, 7, 10, …个元素**。其中4=(3´0)+4,7=(3´1)+4,10=(3´2)+4……
:nth-child(-n+3) :匹配**前3个元素**,因为−0+3=3,−1+3=2,−2+3=1。
li:nth-child(n) :匹配所有的 <li> 元素,就匹配的元素而言和li标签选择器一模一样,区别是优先级更高了。实际开发中总是避免过高的优先级,因此没有理由这样使用。
li:nth-child(1) :匹配第一个 <li> 元素,和li:first-child匹配的作用一样,区别是后者的兼容性更好,因此,**也没有这样使用的理由**,可以使用li:first-child代替。
li:nth-child(n+4):nth-child(-n+10) :匹配第4~10个 <li> 元素,这个就属于比较高级的用法了。例如,考试成绩前3名的有徽章,第4名~第10名的高亮显示,此时,这种**正负值组合**的伪类非常好用。

2. 动态列表项数量匹配技术
聊天软件中的群头像或者一些书籍的分组往往采用复合头像作为一个大的头像,可以看到如果头像数量不同,布局就会不同。(如微信群组)

借助子索引伪类自动判断列表项的个数,从而实现我们想要的布局。在这个方法中,不需要在父元素上设置当前列表项的个数,因此,HTML看起来平淡无奇:

<ul class="box">
<li></li>
<li></li>
<li></li>
...
</ul>​​


关键在于CSS,我们可以借助伪类判断当前列表项的个数,示意代码如下:

/* 1个 */
li:only-child {}
/* 2个 */
li:first-child:nth-last-child(2) {}
/* 3个 */
li:first-child:nth-last-child(3) {}
...​​


> 其中,:first-child:nth-last-child(2) 表示当前 <li> 元素既匹配第一个子元素,又匹配从后往前的第二个子元素,因此,我们就能判断当前总共有两个 <li> 子元素,从而精准实现我们想要的布局了,只需要配合使用相邻兄弟选择符加号(+)以及兄弟选择符(~)。例如:


/* li列表项的数量大于或等于5时所有元素宽度为33.333% */
li:first-child:nth-last-child(n+5),
li:first-child:nth-last-child(n+5) ~ li {
width: calc(100% / 3);
}​​


以上是不是一个非常巧妙的实现呢?
总之,基于上面的数量匹配原理就能自动实现不同列表项数量下的不同布局效果,而无须设置专门表示列表项数量的类名或者属性。
读者可以手动输入 https://demo.cssworld.cn/selector2/8/3-3.php 体验与学习。

https://memo.cosine.ren/m/351
#书摘 #css #前端
《CSS 选择器世界》比较实用的子索引伪类
本节要介绍的伪类都是用来匹配子元素的,子元素必须是独立标签的元素,文本节点、注释节点是无法匹配的。
如果想要匹配文字,只有::first-line和::first-letter两个伪元素可以实现,且只有部分CSS属性可以应用,这里不展开介绍。

1. :first-child 伪类和 :last-child 伪类
:first-child 伪类可以匹配第一个子元素,:last-child 伪类可以匹配最后一个子元素。
2. 给力的 :only-child 伪类
:only-child 也是一个很给力的伪类,尤其在处理动态数据的时候,可以省去很多JavaScript逻辑代码。
我们先来看一下这个伪类的基本含义,:only-child,顾名思义,就是匹配没有任何兄弟元素的元素
例如,:only-child伪类可以匹配下面的 <p> 元素,因为其前后没有其他兄弟元素:

<div class="cs-confirm">
<!-- 可以匹配:only-child伪类 -->
<p class="cs-confirm-p">确定删除该内容?</p>
</div>​​


另外,:only-child 伪类在匹配元素的时候会忽略其前后的文字内容。例如:

<button class="cs-button">
<!-- 可以匹配:only-child伪类 -->
<i class="icon icon-delete"></i>删除
</button>​​


虽然.icon元素后面有“删除”文字,但由于没有标签嵌套,是匿名文本,因此不影响:only-child伪类匹配.icon元素。

尤其需要指出的是,使用:only-child的场景是动态场景,也就是对于某个固定的小模块,根据场景的不同,里面可能是一个子元素,也可能是多个子元素,元素个数不同,布局方式就会不同,此时就是:only-child伪类大放异彩的时候。例如,某个正在加载(loading)的模块里面可能只有一张加载图片,也可能仅有一段加载文字,也可能是加载图片和加载文字兼有,此时:only-child伪类非常好用。

https://memo.cosine.ren/m/350
#书摘 #css #前端
《CSS 选择器世界》empty伪类应用场景
:empty伪类与::before/::after伪元素
::before 和::after 伪元素可以给标签插入内容、图形,但这样会不会影响:empty伪类的匹配呢?答案是:不会。这一特性非常实用。
无论是大项目还是小项目,都会用到:empty伪类。主要有下面几种场景。
1. 隐藏空元素
例如,某个模块里面的内容是动态的,其可能是列表,也可能是按钮,这些模块容器常包含影响布局效果的CSS属性,如margin、padding属性等。当然,这些模块里面有内容的时候,布局显示效果是非常好的。然而,一旦这些模块里面的内容为空,页面上就会有很大一块明显的空白,布局效果就不好,这种情况下使用:empty伪类予以控制就再好不过了:


.cs-module:empty {
display: none;
}​​


无须额外的JavaScript逻辑判断,直接使用CSS就可以实现动态样式效果。唯一需要注意的是,当列表内容缺失的时候,一定要把空格也去掉,否则 :empty 伪类不会匹配。

2. 字段缺失智能提示
例如,下面的HTML代码:

<dl>
<dt>姓名:</dt>
<dd>张三</dd>
<dt>性别:</dt>
<dd></dd>
<dt>手机:</dt>
<dd></dd>
<dt>邮箱:</dt>

<dd></dd>

</dl>​​


用户某些字段的信息是缺失的,此时开发人员应该使用其他占位符示意这里没有内容,例如用短横线(-)或者直接使用文字提示。但多年的开发经验表明,开发人员非常容易忘记这里需要的特殊处理,最终导致布局混乱,信息难辨。
但如今,我们不用再担心这样的问题了,直接使用CSS就可以处理这种情况,代码很简单:


dd:empty::before {
content: '暂无';
color: gray;
}​​


这样的布局效果良好,信息明确。存储的是什么数据内容,直接输出的就是什么内容,就算数据库中存储的是空字符也无须担心。
实际开发中,类似的场景还有很多。例如,表格中的备注信息通常都是空的,此时可以这样处理:

td:empty::before {
content: '-';
color: gray;
}​​


除此之外,还有一类典型场景需要用到:empty伪类,那就是Ajax动态加载数据为空的情况。当一个新用户开始使用一个产品的时候,很多模块内容是没有的。要是在过去,我们需要在JavaScript代码中做if判断,如果没有值,我们要输出“没有结果”或者“没有数据”的信息。但是现在有了:empty伪类,直接把这个工作交给CSS就可以了。例如:


.cs-search-module:empty::before {
content: '没有搜索结果';
display: block;
line-height: 300px;

text-align: center;
color: gray;
}​​


总之,这种方法非常好用,可以节约大量的开发时间,同时用户体验更好,维护更方便,因为可以使用一个通用类名使整站提示信息保持统一:


.cs-empty:empty::before {
content: '暂无数据';
display: block;
line-height: 300px;
text-align: center;
color: gray;

}​​



ps: 个人感觉有用,但不多,但有用
https://memo.cosine.ren/m/349
#书摘 #css #前端
《CSS 选择器世界》empty伪类
先来了解一下 :empty 伪类的基本匹配特性。
1. :empty 伪类用来匹配空标签元素。例如:

<div class="cs-empty"></div>

.cs-empty:empty {

width: 120px;

padding: 20px;

border: 10px dashed;
}​​


此时,:empty伪类会匹配 <div> 元素,呈现为虚线框。

2. :empty伪类还可以匹配前后闭合的替换元素,如 <button> 元素和 <textarea> 元素。例如:


<textarea></textarea>
textarea:empty {

border: 6px double deepskyblue;

}​​


在所有浏览器下都呈现为双实线

3. :empty伪类还可以匹配非闭合元素,如 <input> 元素、`<img>` 元素和 <hr> 元素等。但实际开发中很少有需要使用:empty伪类匹配非闭合元素的场景。

4. :empty伪类可以匹配什么样的元素?如果没有深入研究,你大概会认为:empty伪类可以匹配没有任何子元素、不显示任何内容的元素。但如果深入细节,就会发现这其中存在误解。
- :empty伪类与空格
如果元素内有注释,:empty伪类是否可以匹配?多数人会觉得不匹配,这是完全正确的。例如:

<!-- 无法匹配:empty伪类 -->

<div class="cs-empty"><!-- 注释 --></div>​​


但如果元素内有一个空格或者标签内有换行符呢?实际上,:empty伪类依然无法匹配。例如,有以下两种情况。
- 不能有空格:


<!-- 无法匹配:empty伪类 -->
<div class="cs-empty"> </div>​​


- 不能有换行符:


<!-- 无法匹配:empty伪类 -->
<div class="cs-empty">
</div>​​


因此,实际开发的时候,如果遇到:empty伪类匹配无效的场景,要仔细查看HTML代码,看看标签内是否有空格或者换行符。尤其是使用一些渲染模板的时候,明明没有任何列表内容,但:empty伪类就是无法匹配,这可能是换行符或者空格导致的。不过根据具体实践,一些流行的开发框架(如Vue等)会自动去除空格,这有利于在实际项目中灵活使用:empty伪类。
:empty伪类忽略空格的特性不符合我们的直观认知,W3C官方也收集到了很多这样的意见,所以**在CSS选择器Level 4规范中已经开始明确:empty伪类可以匹配只有空格文本节点的元素**,但是直到撰写本章的时候还没有任何浏览器支持。因此,为安全起见,实际开发中大家还是按照无空格标准来进行。

https://memo.cosine.ren/m/348
#书摘 #css #前端
《CSS 选择器世界》 :root伪类
:root伪类用来匹配文档的根元素,下面进行详细分析。
由于没有特别需要使用:root伪类的理由,反正匹配的是 <html> 元素,因此为何不直接使用html标签选择器呢?这样兼容性更好,优先级更低,是这样吗?
实际上,下面两个开发场景中更推荐使用:root伪类。
1. 利用:root伪类的高优先级
假设引入了某些UI组件库,如果这些组件对html标签进行了一些设置,而这些设置是开发人员不需要的,我们就可以使用:root伪类进行重置,因为:root伪类的优先级更高,不用担心不能重置。例如设置了如下的CSS:

html {
overflow-y: scroll;
}​​


我们就可以用如下代码重置,以确保页面内容在加载过程中不会出现晃动。


:root {

overflow-y: auto;
scrollbar-gutter: stable;
}​​


另外,借助 :root 伪类提高任意选择器的优先级也是一种常见的技巧,例如类名 .recover 不能重置某些样式,可以在其前面加上 :root,变成 :root .recover,说不定就可以重置了,毕竟任何页面都一定有根元素(除了根元素 svg 等特殊场景),这种写法要比 .recover.recover 的性能提高不少。

2. CSS变量
现代浏览器都已经支持CSS自定义属性(也就是CSS变量),其中有一些变量是全局的,如整站的颜色、主体布局的尺寸等。对于这些变量,业界约定俗成,都将它们写在:root伪类中。
大家千万不要以为将CSS变量写在:root伪类中有什么特别的作用,这只是一种写法而已,其效果和写在html标签选择器中是一样的,因为全局CSS变量一定都是用以继承的,只要是级别足够高的祖先选择器都可以。
之所以CSS变量都写在:root伪类中,可能是因为这样可以使代码的可读性更好。同样是根元素,html标签选择器负责样式,:root伪类负责变量,互相分离,各司其职。

https://memo.cosine.ren/m/347
#前端 #阮一峰的科技周刊
科技爱好者周刊(第 272 期):Unity 的安装费,游戏业的缩影


#优质博文 #资源推荐 #tools
1. 1024以后的端口(英文) 📓 Linux 系统保留了小于1024的端口(0-1023),供系统使用,其他端口由用户自己分配。本文总结了被各种常见应用占用的大于1024的端口。

2. 视口碎片化(英文) 📓 浏览器窗口大小(又称视口)到底有多少种?一家设计公司尝试进行统计,结果有2300种之多。

3. AWS SES 如何申请进入生产模式(中文)📓 SES 是亚马逊的邮件发送服务,但是开通这个服务,需要写申请邮件,说清楚用途。作者分享了自己的申请经验。

4. Linkwarden 🧰 一个开源的桌面程序,用来管理网络书签。

5. v0 🧰 #AI Vercel 推出的一个实验性产品,使用 AI 网页生成网页。(好东西,快去申请)
你用文字描述想要什么页面,它会给出三个 UI 设计,让你选一个,然后生成该页面的 React + Tailwind CSS 实现,并允许不断微调。官网有很多作品展示,其中有几个相当可以。它应该是目前最强的 AI 网页生成器。现在还处于 Alpha 阶段,使用资格需要排队等待开通。

6. 讯飞星火认知大模型 🧰 讯飞公司的 AI 大模型,可以根据提示生成 PPT 和简历,以及文档问答。

7. Subdomain Center 🧰 #站长工具 该网站可以查询一个域名有多少个子域名,点击查询框后,通过可以直接改地址栏的 URL 来查询。它的代码开源。
ps:评论有人提供了更强的 OneForAll

8. Sqids 🧰 一个生成短字母 ID 的库,有各种主要语言的版本。

9. Webrecorder 🧰 一个工具包,用来保存交互式网页,做到离线时也能尽可能准确地重现它。

10. 下面两个网站,可以查询某个 IP 地址的地域归属。
- ipinfo.io 🧰
- ipapi.is 🧰
这两个网站还都提供免费的数据库下载 De Facto Ports
Back to Top