作者:前端大骆 https://juejin.cn/post/7357194991339143168
前端开发的核心构建在三大基石技术上:HTML、CSS和JavaScript。回想起多年前,前端开发者常被戏称为“切图仔”,但就是这样的角色,通过精湛的CSS技巧,能够实现各种复杂的交互和特效,展现出前所未有的网页魔法。这是那些专注于服务端开发的工程师所难以企及的领域。
因此,前端工程师这一职业逐渐崭露头角,早期的培训班甚至设立了专门的课程来传授这些技能。然而,随着时间的推移,UI组件库和框架变得越来越普及,HTML和JavaScript的重要性依旧被人们所认可,但CSS技能却逐渐被边缘化,甚至有所忽视。
在一次代码走查中,发现一个拥有三四年前端开发经验的同事,连CSS最基本的类型选择器都掌握不熟练。这一现象令人感到忧虑。
在一次对 useState
的使用场景进行治理的过程中。发现了一段感觉很无语的代码。代码我简化一下如下所示:
import React, { useState } from 'react';
import { Input } from 'antd';
import type { FC } from 'react';
import styles from './index.less';
const Test: FC = () => {
const [isFocus, setIsFocus] = useState(false);
return (
<Input
className={isFocus ? styles['input-focus'] : styles.input}
onFocus={() => {
setIsFocus(true);
}}
onBlur={() => {
setIsFocus(false);
}}
/>
);
};
export default Test;
.input-focus{
background: #f2f3f;
}
这段代码的目的是根据输入框的焦点状态(聚焦或失去焦点)来改变其样式,逻辑上没有问题。
我找到编写这段代码的同事询问:“为什么需要定义一个isFocus
状态呢?”
他看了代码良久,有些疑惑地解释说:“这是为了追踪输入框的聚焦状态,从而在聚焦时改变背景色。”
“这个状态还有其他用途吗?”我追问。
“没有,就这个作用。有问题吗?”他回答。
我继续探询:“不使用isFocus
状态,我们还能达到同样的效果吗?”
他思考了一会儿:“如果不添加类名来标识输入框的聚焦状态,我们怎么区分呢?”
我提出了另一种方案:“我们能不能仅用CSS来实现这个效果?”
他迟疑了一下:“但是CSS怎么能识别输入框是否聚焦呢?”
我提醒他:“你有没有试过使用伪类选择器?”
“伪类?我通常只用类选择器。”他回答。
我解释道:“我们可以使用:focus
伪类来实现这个效果。你可以先回去继续你的工作。”
我继续审查了这位同事的其他代码,发现他对CSS的理解似乎并不深入。例如,为了实现列表的斑马纹效果,理应直接使用:nth-child(odd)
和:nth-child(even)
选择器,但他却通过在遍历过程中判断索引是奇数还是偶数来分别添加不同的类选择器实现这一效果。此外,他同时使用了float: left
和position: absolute
,这在布局中是矛盾的组合。他还通过JavaScript动态添加类选择器来改变输入框提示文字的字体颜色,还一直重复定义color
和font-size
而不懂这些可以继承。
我不确定这是否反映了他的态度问题或是能力问题,在现在只出不进,内部消化的环境下,我默默地记录下这些,以便将来作为评估的参考。
也许会有人觉得我要求的太苛刻,也许这位同事只是忘记了有这几个CSS选择器。的确,CSS选择器的种类众多,达到60多种,可能会让人难以记住每一个。然而,重点并不在于能否一一背诵每个选择器,而在于理解它们各自的功能和使用场景。这样,当面对特定的样式需求时,我们可以轻松地查找并应用最合适的选择器来实现目标效果。
最基本的元素选择器、类选择器、和ID选择器因其简洁直观而被频繁使用。但是,深入探索那些不那么显眼的选择器——如通配符选择器、组合选择器、属性选择器、伪类选择器、和伪元素选择器——同样至关重要。这些选择器赋予了我们更精细的控制权,使得我们能够创造出更加复杂和细腻的视觉效果。
总之,我们不必强迫自己记住所有CSS选择器。更为重要的是认识到CSS选择器的多样性和强大之处。这种认识使我们能够在遇到具体的样式挑战时,知道如何寻找解决方案,从而更高效地运用CSS优化我们的代码。
为了真正理解这些选择器,我们需要思考它们被设计出来的原因——它们是如何帮助我们更好地控制样式,应对各种布局和视觉挑战的。这种深入的理解方式,远比简单的记忆更为重要和有效。
伪类选择器在CSS中的存在有着重要的意义和作用。它们提供了一种方式来选择HTML文档中无法通过简单选择器(如元素选择器、类选择器或ID选择器)直接选择的元素。伪类选择器的设计初衷和主要用途包括以下几点:
伪类选择器允许开发者根据用户与页面的交互来改变元素的样式,而不需要改变HTML代码。例如,:hover
伪类可以用来改变鼠标悬停在链接或按钮上时的样式,:focus
伪类用于当元素获得焦点时(比如输入框被点击时),而:active
伪类则用于元素被激活(通常是被点击)的瞬间。这些都是基于用户行为的动态变化,通过CSS直接实现,无需JavaScript介入,提高了网页的交互性和用户体验。
伪类选择器还可以用来选择处于特定位置的元素,例如第一个子元素、最后一个子元素或者是父元素的唯一子元素。这对于设计复杂的布局和样式非常有用,尤其是在处理列表、表格和导航菜单时。例如,:first-child
、:last-child
、:nth-child()
等伪类选择器,它们提供了一种灵活的方式来选择和样式化这些特定位置的元素。
虽然属性选择器(如[attribute=value]
)可以用来基于元素的属性选择元素,但某些伪类选择器(如:checked
)提供了更为简便的方式来选择具有特定属性的元素。例如,:checked
伪类选择器可以选择所有选中的复选框和单选按钮,这对于创建自定义表单控件的样式非常有用。
伪类选择器还可以增强网页的可访问性。例如,:focus
伪类可以用来为获得焦点的元素定义明显的样式,这对于键盘导航用户来说非常重要。通过提供视觉反馈,用户可以更容易地识别当前交互的元素,从而提高网站的可访问性。
使用伪类选择器,开发者可以在不增加额外HTML标记的情况下,实现复杂的样式和布局。这有助于保持HTML代码的简洁和语义化,同时还可以减少页面的大小和提高加载速度。
总之,伪类选择器为CSS提供了强大的功能,使得开发者能够以更细致和动态的方式控制网页的样式。它们是现代网页设计中不可或缺的工具,使得网页能够响应用户的交互,同时保持代码的整洁和高效。
伪元素选择器在CSS中的引入,为网页设计和内容表现提供了更加丰富和灵活的手段。伪元素选择器允许开发者访问并样式化一个元素的特定部分,或者在文档树中虚拟地创建新的元素,而这些通常不能通过HTML直接实现。伪元素选择器的存在有几个重要的原因和用途:
伪元素选择器使得开发者能够访问并样式化元素的特定部分,比如第一行文本、第一个字母、或者元素之前和之后的内容。例如,::first-line
和 ::first-letter
伪元素分别允许开发者为元素的第一行文本和第一个字母设置特定的样式。这在打造具有吸引力的排版和阅读体验时非常有用。
通过使用 ::before
和 ::after
伪元素,开发者可以在元素的内容之前或之后插入新的内容或装饰,而不需要修改HTML代码。这种方法非常适合添加图标、装饰性元素或者是为元素添加特殊的前缀或后缀,同时保持HTML的清晰和语义化。
伪元素选择器也常被用于创建特殊的视觉效果,比如自定义的清除浮动方法(使用 ::after
清除浮动),或者是设计复杂的背景装饰和形状。这些都可以通过伪元素以及结合CSS的其他特性(如background
、border
、box-shadow
等)来实现。
使用伪元素可以在不增加额外HTML元素的情况下实现复杂的设计,这有助于减少DOM的大小,从而提高网页的性能。通过减少页面加载时需要解析的HTML标签数量,可以加快页面的渲染速度。
通过使用伪元素来添加装饰性内容或样式,开发者可以避免在HTML中添加非语义化的标记。这有助于保持HTML文档的清晰和语义化,使得文档的结构更加明确,也更容易被搜索引擎优化(SEO)和屏幕阅读器理解。
总之,伪元素选择器为CSS提供了强大的功能,使得开发者能够以更细致和动态的方式控制网页的样式和内容。它们是现代网页设计中不可或缺的工具,允许开发者在不牺牲HTML语义化的前提下,实现复杂和创新的设计。
属性选择器在CSS中的引入提供了一种强大的方式来根据元素的属性及其值来选择元素,从而应用特定的样式。这种选择器的存在和使用有几个关键的原因和优势:
在复杂的网页设计中,开发者可能需要对具有特定属性或属性值的元素应用样式,而不是仅基于元素类型、类或ID。属性选择器使得这种精确选择成为可能。例如,可以选择所有设置了target="_blank"
属性的<a>
标签,并为它们应用特定的样式,以提示用户这些链接将在新窗口中打开。
属性选择器增加了CSS规则的灵活性,允许开发者基于元素的属性和属性值来创建复杂的选择条件。这意味着开发者可以在不修改HTML结构的情况下,通过CSS实现更多的设计需求和响应式布局。
使用属性选择器,开发者可以避免在HTML中过度使用类或ID,从而简化HTML结构并提高样式的可维护性。当需要基于相同属性的元素应用统一的样式时,只需在CSS中定义一次相应的属性选择器规则,而不是在HTML中为每个元素重复添加类或ID。
属性选择器可以用来增强文档的语义化和可访问性。例如,通过选择具有特定role
属性的元素并为它们应用样式,开发者可以帮助提高网页对于屏幕阅读器等辅助技术的可访问性。
在某些情况下,开发者可能希望仅在元素具有特定属性或属性值时才应用样式。属性选择器使得这种条件样式化成为可能,无需额外的类或ID,也无需使用JavaScript。这种方式非常适合实现基于特定数据属性(data-*
属性)的样式变化。
示例
假设我们想为所有含有特定属性data-tooltip
的元素添加一个工具提示样式,我们可以使用如下CSS规则:
[data-tooltip] {
position: relative;
cursor: pointer;
}
[data-tooltip]:before {
content: attr(data-tooltip);
/* 更多的样式规则来定义工具提示的外观 */
}
这个示例展示了如何仅通过CSS和HTML属性来实现一个简单的工具提示功能,无需修改HTML结构或使用JavaScript。
总之,属性选择器为CSS提供了更多的选择和样式化能力,增加了样式表的灵活性和可维护性,同时促进了更好的文档结构和语义化。
组合选择器在CSS中扮演着至关重要的角色,它们提供了一种强大的机制来选择具有特定关系的元素,从而允许开发者以更精细、更具体的方式应用样式。组合选择器的存在和使用主要基于以下几个原因:
在复杂的网页布局中,仅使用简单选择器(如元素选择器、类选择器或ID选择器)往往难以精确地定位到特定的元素。组合选择器通过定义元素之间的关系(如父子关系、相邻关系等),使得开发者可以更精确地选择到目标元素。这种精确性对于实现特定的布局和样式效果至关重要。
使用组合选择器,可以避免在HTML中过度使用类或ID来达到样式目的,从而使得CSS的结构更加清晰和简洁。这种方法有助于提高代码的可维护性和可读性,同时减少了因重复定义样式而导致的冗余。
组合选择器提供了一种方式来实现基于特定元素关系的复杂样式设计。例如,开发者可以使用子选择器(>
)来仅为特定父元素的直接子元素应用样式,或使用相邻兄弟选择器(+
)来为紧跟在特定元素后的兄弟元素应用样式。这种灵活性使得开发者能够创造出更加动态和富有层次感的页面布局和视觉效果。
通过使用组合选择器,开发者可以为特定的元素关系定义样式,而不是针对特定的类或ID。这种做法增加了样式的可复用性,因为相同的组合选择器样式可以在不同的HTML结构中被复用,只要这些结构符合选择器定义的元素关系。
组合选择器的使用有助于保持HTML代码的语义化,因为它们允许开发者基于元素之间的自然关系来应用样式,而不是强迫添加额外的类或ID。这样不仅使得HTML结构更加清晰,也有助于搜索引擎优化(SEO)和提高网站的可访问性。
示例
假设我们想为一个列表中的第一个项目添加特殊样式,我们可以使用子选择器和伪类选择器的组合来实现这一点:
ul > li:first-child {
color: red;
}
这个示例展示了如何使用组合选择器来精确选择并样式化特定的元素,而无需为该元素添加额外的类或ID。
总之,组合选择器是CSS中不可或缺的一部分,它们通过定义元素之间的关系增强了选择器的功能,使得开发者能够以更灵活、更高效的方式设计和实现网页样式。
- END -