이 글에서는 CSS의 선택자를 이해하고 단순 선택자, 복합 선택자, 복잡한 선택자 및 선택자 우선순위의 구문을 소개합니다.
먼저 선택기의 구문을 이해하고 그 뒤에 있는 관련 기능을 자세히 살펴보겠습니다.
간단한 선택기
*
div svg|a
tagName
(태그 이름) 속성을 선택한다는 의미입니다. tagName
(标签名) 属性HTML
、SVG
、MathML
|
,CSS选择器里面单竖线是一个命名空间的分隔符,而HTML 里面命名空间分隔符是 冒号 :
。然后前面说到的命名空间是需要 @namespace 来声明的,他们是配合使用的,但是这个命名空间的使用不是很频繁,它的存在只是为了一个完备性考虑,HTML 和 SVG当中唯一一个重叠的元素名就只有一个 a
.class-name
.
开头的选择器就是 class 选择器,也是最经典之一.class
只要匹配中其中一个就可以了#id
하지만 HTML에도 이름이 있습니다. 공간적으로 세 가지 주요 유형이 있습니다: HTML
, SVG
, MathML
|
를 사용해야 합니다. CSS 선택기의 단일 수직 막대는 네임스페이스 구분 기호이고 HTML의 네임스페이스 구분 기호는 콜론 :
입니다. 그러면 앞서 언급한 네임스페이스를 @namespace로 선언해야 하는데, 이 네임스페이스는 자주 사용되지는 않으며 HTML과 SVG 사이에 유일하게 겹치는 요소입니다. code>a#
开头加上 ID 名选中一个 ID[attr=value]
attr=value
,等于前面是属性名,后面是属性值~
就表示像 class 一样,可以支持拿空格分隔的值的序列:attr~=value
attr|=value
:hover
.class -name
:
开头的,它主要是一些属性的特殊状态::before
.
로 시작하는 선택기는 가장 고전적인 클래스 선택기 중 하나입니다. ::
공백을 구분 기호로 사용하여 여러 클래스를 지정할 수도 있습니다. 이 .class
는 둘 중 하나만 일치하세요#id
#
로 시작하고 ID 이름을 추가하여 ID를 선택하세요속성 선택기|속성 선택기 —— [attr=값]
attr=value
입니다. 즉, 앞에 속성 이름이 있고 그 뒤에 속성 값이 옵니다~
를 추가할 수 있습니다. 즉, 클래스와 마찬가지로 공백으로 구분된 일련의 값을 지원할 수 있습니다. attr~=value
attr|=value
우선순위에 대한 특별한 요구사항이 없다면 이론적으로 속성 선택기를 사용하여 다음을 수행할 수 있습니다. 장치의 클래스 선택기 및 ID 선택
pseudo-class 교체 —— :hover
:
로 시작하는 것은 주로 일부 속성의 특별한 상태입니다이것은 우리가 작성하는 HTML과는 아무 관련이 없으며 주로 상호 작용 및 효과에서 발생합니다.
🎜일부 의사 클래스 선택자에는 의사 함수가 있습니다. -클래스 선택기, 의사 클래스를 사용하여 이러한 문제를 해결할 수 있습니다🎜🎜🎜🎜🎜의사 요소 선택기🎜 ——::before
🎜🎜 일반적으로 🎜 이중 콜론으로 시작합니다. 🎜🎜 실제로 단일 콜론 사용을 지원하지만 의사 요소 선택자임을 한눈에 알 수 있기 때문에 이중 콜론 🎜🎜을 사용하는 방식을 옹호합니다. Kailai와 구별됩니다🎜🎜의사 요소는 원래 존재하지 않는 일부 요소를 선택하는 데 사용됩니다🎜🎜선택하지 않으면 이 요소는 여기에 존재하지 않습니다. 선택 후에는 요소가 하나 더 생깁니다. 🎜🎜🎜🎜🎜복합 선택기🎜 🎜🎜🎜🎜🎜🎜* 아니면 div를 맨 앞에 써야 합니다🎜🎜🎜🎜우선 복합 선택기 다중 단순 선택을 기반으로 합니다. 선택자로 구성되며, 단순 선택자를 나란히 작성하여 복합 선택자로 전환합니다. 그 의미는 우리가 선택한 요소가 동시에 여러 개의 단순 선택기와 일치하여 "AND" 관계를 형성해야 한다는 것입니다. 🎜🎜🎜🎜🎜복합 선택기🎜🎜🎜🎜🎜복합 선택기는 중간에 커넥터를 사용하여 복합 선택기로 바뀔 수 있습니다. 복합 선택기는 요소의 구조를 기반으로 선택합니다. 🎜
케이스부터 시작합니다. 선택자 우선순위는 선택자에 포함된 모든 단순 선택자를 계산하는 것입니다. 따라서 선택자 목록은 완전한 선택자(즉, 쉼표로 구분된 선택자)로 간주되지 않습니다. 선택자 목록의 중간 부분이 간단한 선택자 계산을 위해 쉼표로 구분된 복합 선택자이기 때문입니다. 예: #id div.a#id
여기에는 두 개의 ID 선택기, 유형 선택기와 클래스 선택기가 포함되어 있습니다.
#id div.a#id
specificity
数组的计数 [inline-style个数
,ID 选择器个数
,class 选择器个数
,tagName 选择器个数
]specificity = [0, 2, 1, 1]
특수성
배열에 따라 count [인라인 스타일 항목 수
, ID 선택기 수
, 클래스 선택기 수
, tagName 선택기 수
]특이성 = [0, 2, 1, 1]
을 얻습니다.N=1000000
,那么 S=2000001000001
,这个就是这个例子中选择器的 specificity
을 사용합니다
N=1000000
,
S=2000001000001
, 이것이 선택기의 특이성입니다. example
우선 순위는
IE IE6의 이전 버전과 마찬가지로 메모리를 절약하기 위해 N의 값이 충분히 크지 않기 때문에 255의 값을 N으로 취하므로 매우 흥미로운 일이 발생합니다 , 예를 들어 256개의 클래스는 ID와 동일합니다. 나중에 대부분의 브라우저는 65536을 선택했으며 기본적으로 더 이상 할당량을 초과하지 않았습니다. 표준에서는 상대적으로 큰 값만 사용하라고 하는데 임시 메모리 사용량 문제를 고려해야 하므로 16진수로 상대적인 정수를 취하는데, 이는 일반적으로 256의 정수(왜냐하면 256은 정확히 1바이트이기 때문)입니다. ).
🎜🎜CSS 의사 클래스 🎜🎜🎜🎜의사 클래스는 실제로 많은 콘텐츠에 대한 간단한 선택기입니다. 🎜🎜🎜🎜링크/액션🎜🎜🎜:any-link
- 모든 하이퍼링크와 일치 가능:any-link
—— 可以匹配任何的超链接:link
—— 还没有访问过的超链接:link :visited
—— 匹配所有被访问过的超链接:hover
—— 用户鼠标放在元素上之后的状态,之前是只能对超链接生效,但是现在是可以在很多元素中使用了:active
—— 之前也是只对超链接生效的,点击之后当前的链接就会生效:focus
—— 就是焦点在这个元素中的状态,一般用于 input 标签,其实任何可以获得焦点的元素都可以使用:target
—— 链接到当前的目标,这个不是给超链接用的,是给锚点的 a
标签使用的,就是当前的 HASH指向了当前的 a
标签的话就会激活 target
伪类一旦使用了
:link
或者:visited
之后,我们就再也无法对这个元素的文字颜色之外的属性进行更改。为什么要这样设计呢?因为一旦我们使用了 layout 相关的属性,比如说我们给:visited
的尺寸加大一点,它就会影响排班。这样我们就可以通过 JavaScript 的 API 去获取这个链接是否被访问过了。但是如果我们能获得链接是否被访问过了,那么我们就可以知道用户访问过那些网站了,这个对于浏览器的安全性来说是一个致命打击。所以这里也提醒一下大家,不要以为做一些表现性的东西于安全没有任何关系,其实安全性是一个综合的考量。CSS 它也能造成安全漏洞的。
树结构
:empty
—— 这个元素是否有子元素:nth-child()
—— 是父元素的第几个儿子(child):nth-last-child()
—— 于 nth-child
一样,只不过从后往前数:first-child :last-child :only-child
:nth-child
是一个非常复杂的伪类,里面支持一种语法,比如说可以在括号里面写奇偶event
或者odd
,也可以写4N+1
、3N-1
,这个就会分别匹配到整数的形态。因为这个是一个比较复杂的选择器,我们就不要在里面写过于复杂的表达式了,只用它来处理一下奇偶,逢3个多1个,逢4个多1个等等这种表达式。
其实
empty
、nth-last-child
、last-child
、only-child
这两个选择器,是破坏了我们之前在 《实现中学习浏览器原理》中的说到的 CSS 计算的时机问题。我们可以想象一下,当我们在开始标签计算的时候,肯定不知道它有没有子标签。empty
影响不是特别大,但是last-child
的这个关系其实还是影响蛮大的。所以浏览在实现这些的时候是做了特别处理的,要么就是浏览器实现的不是特别好,要么就是浏览器要耗费更大的性能来得以实现。所以建议大家尽量避免大量使用这些。
逻辑型
这里还是像温馨建议一下大家,不建议大家把选择器写的过于复杂,我们很多时候都可以多加一点 class 去解决的。如果我们的选择器写的过于复杂,某种程度上意味着 HTML 结构写的不合理。我们不光是为了给浏览器工程省麻烦,也不光是为了性能,而是为了我们自身的代码结构考虑,所以我们不应该出现过于复杂的选择器。
一共分为 4 种
::before
和 ::after
是在元素的内容的前和后,插入一个伪元素。一旦应用了 before 和 after 的属性,declaration(声明)里面就可以写一个叫做 content
的属性(一般元素是没有办法写 content 的属性的)。content
的属性就像一个真正的 DOM 元素一样,可以去生成盒,可以参与后续的排版和渲染了。所以我们可以给他声明 border
、background
:link
- 아직 방문하지 않은 하이퍼링크
🎜🎜트리 구조🎜🎜🎜🎜:hover
- 사용자가 요소에 마우스를 놓은 후의 상태입니다. 이전에는 하이퍼링크에만 적용됩니다. 하지만 이제는 다양한 요소에서 사용할 수 있습니다.🎜
:active
- 예전에는 하이퍼링크에만 적용되었습니다. 클릭하면 현재 링크가 적용됩니다. li>:focus - 이 요소의 포커스 상태입니다. 일반적으로 입력 태그에 사용됩니다. 실제로 포커스를 얻을 수 있는 모든 요소를 사용할 수 있습니다.:target —— 현재 대상에 대한 링크입니다. 하이퍼링크에는 사용되지 않지만 앵커 포인트의 <code>a
태그에는 현재 HASH가 현재a code>를 가리킵니다. 태그는 <code>target
의사 클래스를 활성화합니다:link
또는:visited
가 사용되면 다음을 수행할 수 있습니다. 더 이상 이 요소의 텍스트 색상 이외의 속성을 변경하지 않습니다. 왜 이렇게 설계되었나요? 예를 들어 레이아웃 관련 속성을 사용한 후:visited
의 크기를 늘리면 일정에 영향을 미치기 때문입니다. 이러한 방식으로 JavaScript API를 사용하여 링크 방문 여부를 확인할 수 있습니다. 그러나 링크 방문 여부를 알 수 있다면 사용자가 어떤 웹사이트를 방문했는지 알 수 있으며 이는 브라우저 보안에 치명적인 타격을 줍니다. 그래서 여기서 저는 여러분에게 어떤 표현적인 것을 만드는 것이 안전과 아무 관련이 없다고 생각하지 않는다는 점을 상기시키고 싶습니다. 사실 안전은 포괄적인 고려 사항입니다. CSS는 보안 허점을 유발할 수도 있습니다. 🎜
:empty
—— 이 요소에 하위 요소가 있는지 여부🎜:nth-child()
—— 어느 하위 요소가 상위 요소인지🎜:nth-last-child()
—— 와 동일 n번째-자식
, 뒤에서 앞으로 계산하는 것은 제외🎜:first-child :last-child :only-child
ul>🎜🎜 :nth-child
는 구문을 지원하는 매우 복잡한 의사 클래스입니다. 예를 들어 홀수 및 짝수 event
또는 odd를 괄호 안에 쓸 수 있습니다. code>에 <code>4N+1
, 3N-1
을 쓸 수도 있으며 이는 각각 정수 형식과 일치합니다. 이것은 상대적으로 복잡한 선택기이기 때문에 우리는 지나치게 복잡한 표현식을 작성하고 싶지 않습니다. 예를 들어 3마다 1 더, 4보다 1 더 많은 등의 홀수 및 짝수 표현식을 처리하는 데만 사용합니다. 🎜🎜🎜사실 비어있음
, n번째 마지막 자식
, 마지막 자식
, only-child 이 두 선택기는 "구현 시 브라우저 원리 학습"에서 언급한 CSS 계산의 타이밍 문제를 파괴합니다. 레이블 계산을 시작할 때 하위 레이블이 있는지 확실히 알 수 없다고 상상할 수 있습니다. <code>empty
의 영향은 특별히 크지 않지만 last-child
간의 관계는 실제로 상당한 영향을 미칩니다. 따라서 브라우징에서는 이를 구현할 때 특별한 처리를 수행했습니다. 브라우저가 이를 특별히 잘 구현하지 않거나 이를 구현하려면 브라우저에 더 많은 성능이 필요합니다. 따라서 이러한 제품은 대량으로 사용하지 않는 것이 좋습니다. 🎜🎜🎜논리 유형🎜🎜🎜🎜: 의사 클래스 아님 - 주류 브라우저는 단순 선택기(복합 선택기)의 시퀀스만 지원합니다. 복잡한 선택기 구문을 작성할 방법이 없습니다.🎜:where :has - 이 두 개의 매우 강력한 논리적 의사 클래스가 CSS 레벨 4에 추가되었습니다.🎜 🎜여기 모두에게 따뜻한 제안이 있습니다. , 🎜선택기를 너무 복잡하게 작성하는 것은 권장하지 않습니다🎜, 🎜문제를 해결하기 위해 클래스를 더 추가하는 경우가 많습니다🎜. 선택기가 너무 복잡하게 작성되면 HTML 구조가 어느 정도 불합리하다는 의미입니다. 우리는 브라우저 프로젝트나 성능에 대한 문제를 줄일 뿐만 아니라 우리 자신의 코드 구조를 위해서도 이렇게 하므로 지나치게 복잡한 선택기를 사용해서는 안 됩니다. 🎜::before
및 : :after
는 요소의 내용 앞과 뒤에 의사 요소를 삽입합니다. before 및 after 속성이 적용되면 content
라는 속성을 선언에 쓸 수 있습니다(일반 요소는 content 속성을 쓸 수 없습니다). content
의 속성은 실제 DOM 요소와 유사하며 상자를 생성하고 후속 조판 및 렌더링에 참여할 수 있습니다. 따라서 테두리
, 배경
등과 같은 속성을 선언할 수 있습니다. 🎜🎜🎜 다음과 같이 이해될 수 있습니다. 🎜 의사 요소는 존재하지 않는 요소를 인터페이스에 추가합니다. 🎜🎜::first-line
과 ::first-letter
에는 서로 다른 메커니즘이 있습니다. 이 두 가지는 실제로 콘텐츠에 존재합니다. 이름에서 알 수 있듯이 "첫 번째 행"을 선택하고 "첫 번째 문자"를 선택합니다. 이는 존재하지 않는 요소가 아니며 텍스트의 일부를 포함하여 일부 처리를 수행할 수 있습니다. ::first-line
和 ::first-letter
的机制就不一样了。这两个其实原本就存在 content 之中。他们顾名思义就是 选中“第一行” 和选中 “第一个字母”。它们 不是一个不存在的元素,是把一部分的文本括了起来让我们可以对它进行一些处理。
before 和 after
在我们概念里,我们可以认为带有 before 伪元素的选择器,会给他实际选中的元素的内容前面增加了一个元素,我们只需要通过他的 content 属性为它添加文本内容即可。(这里我们也可以给伪元素赋予 content: ''
为空的)所以我们可以任何的给 before 和 after 指定 display 属性,和不同元素一样比较自由的。
我们在实现一些组建的时候,也会常常使用这种不污染 DOM 树,但是能实际创造视觉效果的方式来给页面添加一些修饰性的内容。
<div> <::before/> content content content content content content content content content content content content content content content content <::after/> </div>
first-letter 和 first-line
first-letter
相当于我们有一个元素把内容里面的第一个字母给括了起来。这个 first-letter
我们是可以任意声明各种不同的属性的,但是我们是无法改变它的 content 的。我们应该都看到过报纸上的第一个字母会比较大,然后会游离出来的效果,这个在 CSS 里面我们就可以用 ::first-letter
的伪元素选择器了。使用这个来实现相比用 JavaScript 来实现就会更加稳定和代码更加优雅一些。
<div> <::first-letter>c</::first-letter>ontent content content content content content content content content content content content content content content content </div>
first-line
是针对排版之后的 line
,其实跟我们源码里面的 first line
没有任何的关系的。假如说我们的浏览器提供的渲染的宽度不同,first-line
전후우리 개념에서는 이전 의사 요소가 있는 선택기가 실제 선택된 요소의 내용을 제공한다고 생각할 수 있습니다. 요소를 추가한 후에는 content 속성을 통해 텍스트 콘텐츠만 추가하면 됩니다. (여기서
content: ''
를 의사 요소에 빈 것으로 할당할 수도 있습니다.) 따라서 다른 요소처럼 어떤 방식으로든 전후에 대한 표시 속성을 지정할 수 있습니다.
일부 구성요소를 구현할 때 DOM 트리를 오염시키지 않으면서 실제로 시각적 효과를 생성할 수 있는 방식으로 페이지에 장식적인 콘텐츠를 추가하기 위해 이 방법을 자주 사용합니다. <div>
<::first-line>content content content content content</::first-line>
content content content content
content content content content
content content content content
</div>
첫 글자와 첫 줄
첫 글자
는 첫 번째 요소를 넣는 요소가 있는 것과 같습니다. 내용에서 문자는 괄호 안에 표시됩니다. 이 첫 글자
의 다양한 속성을 마음대로 선언할 수 있지만 내용을 변경할 수는 없습니다. 우리 모두는 신문의 첫 글자가 더 커지고 분리되는 효과를 보았을 것입니다. CSS에서는 ::first-letter
의사 요소 선택기를 사용할 수 있습니다. 이를 사용하여 구현하는 것이 JavaScript를 사용하는 것보다 더 안정적이고 코드가 더 우아해집니다. <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Match Example —— by 三钻</title> </head> <body> <div> <b> <div class="class classA" id="id">content</div> </b> </div> </body> <script language="javascript"> /** * 匹配选择器 */ function matchSelectors(selector, element) { // 先匹配当前元素是否匹配 let tagSelector = selector.match(/^[\w]+/gm); let idSelectors = selector.match(/(?<=#)([\w\d\-\_]+)/gm); let classSelectors = selector.match(/(?<=\.)([\w\d\-\_]+)/gm); /** * 实现复合选择器,实现支持空格的 Class 选择器 * -------------------------------- */ // 检查 tag name 是否匹配 if (tagSelector !== null) { if (element.tagName.toLowerCase() !== tagSelector[0]) return false; } // 检测 id 是否匹配 if (idSelectors !== null) { let attr = element.attributes['id'].value; if (attr) { for (let selector of idSelectors) { if (attr.split(' ').indexOf(selector) === -1) return false; } } } // 检测 class 是否匹配 if (classSelectors !== null) { let attr = element.attributes['class'].value; if (attr) { for (let selector of classSelectors) { if (attr.split(' ').indexOf(selector) === -1) return false; } } } return true; } /** * 匹配元素 */ function match(selector, element) { if (!selector || !element.attributes) return false; let selectors = selector.split(' ').reverse(); if (!matchSelectors(selectors[0], element)) return false; let curElement = element; let matched = 1; // 递归寻找父级元素匹配 while (curElement.parentElement !== null && matched < selectors.length) { curElement = curElement.parentElement; if (matchSelectors(selectors[matched], curElement)) matched++; } // 所有选择器匹配上为 匹配成功,否则是失败 if (matched !== selectors.length) return false; return true; } let matchResult = match('div #id.class', document.getElementById('id')); console.log('Match example by 三钻'); console.log('matchResult', matchResult); </script> </html>
첫 번째 줄
은 조판 후의 줄
에 대한 것입니다. 실제로 우리 소스 코드의 첫 번째 줄
과는 아무런 관련이 없습니다. . 브라우저가 서로 다른 렌더링 너비를 제공하는 경우 두 환경에서 첫 번째 줄
로 묶인 요소 수가 달라집니다. 따라서 이 선택기를 사용할 때는 필요에 따라 사용해야 합니다. 개발 컴퓨터와 사용자 컴퓨터의 렌더링 효과가 다를 가능성이 매우 높습니다! 글꼴 시리즈색상 시리즈배경 시리즈
프로그래밍 비디오를 방문하세요! !
위 내용은 CSS의 선택자 자세히 살펴보기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!