Heim > Artikel > Web-Frontend > Ein genauerer Blick auf Selektoren in CSS
In diesem Artikel erfahren Sie mehr über die Selektoren in CSS und stellen die Syntax einfacher Selektoren, zusammengesetzter Selektoren, komplexer Selektoren und Selektorprioritäten vor.
Lassen Sie uns zunächst die Syntax von Selektoren verstehen und dann einen tieferen Blick auf die zugehörigen Funktionen dahinter werfen.
Einfacher Selektor
*
*
div svg|a
tagName
(标签名) 属性HTML
、SVG
、MathML
|
,CSS选择器里面单竖线是一个命名空间的分隔符,而HTML 里面命名空间分隔符是 冒号 :
。然后前面说到的命名空间是需要 @namespace 来声明的,他们是配合使用的,但是这个命名空间的使用不是很频繁,它的存在只是为了一个完备性考虑,HTML 和 SVG当中唯一一个重叠的元素名就只有一个 a
.class-name
.
开头的选择器就是 class 选择器,也是最经典之一.class
只要匹配中其中一个就可以了#id
#
开头加上 ID 名选中一个 ID[attr=value]
attr=value
,等于前面是属性名,后面是属性值~
就表示像 class 一样,可以支持拿空格分隔的值的序列:attr~=value
attr|=value
:hover
:
开头的,它主要是一些属性的特殊状态::before
::
div svg|a
tagName
(Tag-Name) im Element auswählt. Aber weil HTML auch eine Benennung hat Räumlich gesehen gibt es drei Haupttypen: HTML
, SVG
, MathML
Wenn wir bestimmte Elemente in SVG oder MathML auswählen möchten, verwenden wir die Es muss ein einzelner vertikaler Balken |
verwendet werden. Der einzelne vertikale Balken im CSS-Selektor ist ein Namespace-Trennzeichen, und das Namespace-Trennzeichen in HTML ist der Doppelpunkt :
. Dann muss der zuvor erwähnte Namespace durch @namespace deklariert werden, aber dieser Namespace wird nur der Vollständigkeit halber verwendet. Es gibt nur einen Namen a
.class -name
Der Selektor, der mit .
beginnt, ist auch einer der klassischsten Er kann auch Leerzeichen als Trennzeichen verwenden
Diese .class
passt einfach zu einem davon
|id-Selektor –#id
Beginnen Sie mit#
und fügen Sie den ID-Namen hinzu, um eine ID auszuwählen🎜🎜Dies ist eine strikte Übereinstimmung🎜🎜Sie können der ID Minuszeichen oder andere Symbole hinzufügen🎜🎜🎜🎜Attributauswahl|Attributauswahl ——[attr=value]
🎜🎜Es enthält den Klassenattributselektor und den ID-Selektor🎜🎜Die vollständige Syntax dieses Selektors lautetattr=value
, was bedeutet, dass vorne der Attributname steht, gefolgt vom Attributwert🎜🎜Das Gleichheitszeichen innen Sie können~
vorne hinzufügen, was bedeutet, dass Sie wie eine Klasse eine durch Leerzeichen getrennte Wertefolge unterstützen können:attr~=value
🎜🎜Wenn Sie hinzufügen ein einzelner vertikaler Balken vor dem Gleichheitszeichen. Dies bedeutet, dass dieses Attribut mit diesem Wert beginnt:attr|=value
🎜🎜Wenn wir keine besonderen Anforderungen an die Priorität haben, können wir theoretisch dafür Attributselektoren verwenden Ersetzen Sie Klassenselektoren und ID-Auswahlen 🎜🎜🎜🎜🎜Pseudoklasse🎜 des Geräts –:hover
🎜🎜Beginnend mit:
ist es hauptsächlich der Sonderstatus einiger Attribute🎜🎜Das hat nichts mit dem HTML zu tun, das wir schreiben, hauptsächlich mit Interaktion und Effekten🎜🎜Einige Pseudoklassenselektoren haben Pseudofunktionen -Klassenselektoren, wir können Pseudoklassen verwenden, um diese Probleme zu lösen🎜🎜🎜🎜🎜Pseudoelementselektor🎜 ——::before
🎜🎜Im Allgemeinen beginnt es mit einem Doppelpunkt von::
🎜🎜Tatsächlich unterstützt es die Verwendung eines einzelnen Doppelpunkts, wir empfehlen jedoch die Schreibweise eines Doppelpunkts🎜🎜weil wir sehen können Auf den ersten Blick erkennt man, dass es sich hierbei um eine Fälschung handelt. Elementselektoren unterscheiden sich von Pseudoklassen. 🎜🎜Pseudoelemente werden verwendet, um einige Elemente auszuwählen, die ursprünglich nicht vorhanden sind. 🎜🎜Wenn wir sie nicht auswählen, wird dieses Element hier und da nicht existieren wird nach der Auswahl ein weiteres Element sein🎜🎜🎜 🎜🎜🎜🎜Compound Selector🎜🎜🎜🎜🎜🎜🎜* Oder das Div muss vorne stehen🎜🎜 🎜🎜Komplexe erste Selektoren bestehen aus mehreren einfachen Selektoren, um sie in einen zusammengesetzten Selektor umzuwandeln. Seine Semantik besteht darin, dass das von uns ausgewählte Element gleichzeitig mit mehreren einfachen Selektoren übereinstimmen muss, wodurch eine „UND“-Beziehung entsteht. 🎜🎜🎜🎜🎜Komplexer Selektor🎜🎜🎜🎜🎜Ein zusammengesetzter Selektor kann durch die Verwendung eines Verbinders in der Mitte in einen komplexen Selektor umgewandelt werden. Ein komplexer Selektor wählt basierend auf der Struktur eines Elements aus. 🎜
Beispiel: #id div.a#id
Dies enthält zwei ID-Selektoren, einen Typselektor und einen Klassenselektor
Gemäß einem Spezifität
-Array count [Anzahl der Elemente im Inline-Stil
, Anzahl der ID-Selektoren
, Anzahl der Klassenselektoren
,tagName Anzahl der Selektoren
]
In unserem Beispiel erhalten wirpecifity = [0, 2, 1, 1]
#id div.a#id
specificity
数组的计数 [inline-style个数
,ID 选择器个数
,class 选择器个数
,tagName 选择器个数
]specificity = [0, 2, 1, 1]
N=1000000
,那么 S=2000001000001
,这个就是这个例子中选择器的 specificity
Im Standard der Selektoren gibt es einen wie diese Beschreibung, wir werden eine N-Base verwenden um die Selektorpriorität darzustellenZum Beispiel verwenden wirWir müssen nur ein großes N nehmen, und die Berechnung hat die Priorität des Selektors
N=1000000
S=2000001000001
, das ist die Spezifität
-Priorität des Selektors in diesem Beispiel
:any-link
– kann mit jedem Hyperlink übereinstimmen: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
– ein Hyperlink, der noch nicht besucht wurde
🎜🎜Baumstruktur🎜🎜🎜🎜:hover
– Der Status, nachdem der Benutzer die Maus auf das Element gesetzt hat. Bisher konnte es nur auf Hyperlinks angewendet werden. aber jetzt kann es in vielen Elementen verwendet werden🎜Sobald
:active
– es wurde früher nur bei Hyperlinks wirksam. Nach dem Klicken wird der aktuelle Link wirksam li>:focus – Dies ist der Fokuszustand in diesem Element. Es wird im Allgemeinen für Eingabe-Tags verwendet. Tatsächlich kann jedes Element verwendet werden, das den Fokus erhalten kann:target – Link zum aktuellen Ziel. Dies wird nicht für Hyperlinks verwendet, sondern für das <code>a
-Tag des Ankerpunkts. Der aktuelle HASH zeigt auf den aktuellena
Tag aktiviert die Pseudoklassetarget
:link
oder:visited
verwendet wird, können wir dies tun Ändern Sie keine anderen Attribute mehr als die Textfarbe dieses Elements. Warum ist es so konzipiert? Denn sobald wir Layout-bezogene Attribute verwenden, beispielsweise wenn wir die Größe von:visited
erhöhen, wirkt sich dies auf die Planung aus. Auf diese Weise können wir mithilfe der JavaScript-API ermitteln, ob der Link besucht wurde. Wenn wir jedoch feststellen können, ob der Link besucht wurde, können wir wissen, welche Websites der Benutzer besucht hat, was einen fatalen Schlag für die Sicherheit des Browsers darstellt. Deshalb möchte ich hier alle daran erinnern: Denken Sie nicht, dass die Herstellung einiger ausdrucksstarker Dinge nichts mit Sicherheit zu tun hat. Tatsächlich ist Sicherheit eine umfassende Überlegung. Auch CSS kann Sicherheitslücken verursachen. 🎜
:empty
—— Ob dieses Element untergeordnete Elemente hat🎜:nth-child()
—— Welches Kind ist das übergeordnete Element🎜:nth-last-child()
—— Dasselbe wie n-tes Kind
, außer von hinten nach vorne gezählt🎜:erstes-Kind :letztes-Kind :nur-Kind
ul>🎜🎜 :nth-child
ist eine sehr komplexe Pseudoklasse, die eine Syntax unterstützt. Sie können beispielsweise ungerade und gerade event
oder odd in Klammern schreiben. code>, Sie können auch <code>4N+1
, 3N-1
schreiben, was jeweils der Ganzzahlform entspricht. Da es sich um einen relativ komplexen Selektor handelt, möchten wir keine übermäßig komplexen Ausdrücke darin schreiben. Wir verwenden ihn nur, um ungerade und gerade Ausdrücke zu verarbeiten, z. B. 1 mehr, wenn 3, 1 mehr als 4 usw. 🎜🎜🎜Tatsächlich empty
, nth-last-child
, last-child
, only-child Diese beiden Selektoren zerstören das Timing-Problem der CSS-Berechnung, das wir zuvor in „Browser-Prinzipien in der Implementierung lernen“ erwähnt haben. Wir können uns vorstellen, dass wir zu Beginn der Etikettenberechnung definitiv nicht wissen, ob es Unteretiketten gibt. Die Auswirkungen von <code>empty
sind nicht besonders groß, aber die Beziehung zwischen last-child
hat tatsächlich erhebliche Auswirkungen. Daher hat das Surfen bei der Implementierung eine besondere Verarbeitung durchgeführt. Entweder implementiert der Browser dies nicht besonders gut, oder der Browser benötigt mehr Leistung, um es zu implementieren. Daher wird empfohlen, die Verwendung dieser Stoffe in großen Mengen zu vermeiden. 🎜🎜🎜logischer Typ🎜🎜🎜🎜:keine Pseudoklasse – Mainstream-Browser unterstützen nur Sequenzen einfacher Selektoren (zusammengesetzte Selektoren). Wir haben Keine Möglichkeit, komplexe Selektorsyntax darin zu schreiben🎜:where :has – diese beiden sehr leistungsstarken logischen Pseudoklassen wurden zu CSS Level 4 hinzugefügt🎜 🎜Hier ist ein herzlicher Vorschlag an alle , 🎜Ich empfehle nicht, den Selektor zu kompliziert zu schreiben🎜, 🎜Wir können oft weitere Klassen hinzufügen, um das Problem zu lösen🎜. Wenn unser Selektor zu komplex geschrieben ist, bedeutet dies, dass die HTML-Struktur in gewissem Maße unangemessen ist. Wir tun dies nicht nur, um dem Browserprojekt Ärger zu ersparen oder die Leistung zu verbessern, sondern auch aus Gründen unserer eigenen Codestruktur, sodass wir keine übermäßig komplexen Selektoren haben sollten. 🎜::before
und : :after
fügt ein Pseudoelement vor und nach dem Inhalt des Elements ein. Sobald die Vorher- und Nachher-Attribute angewendet werden, kann ein Attribut namens content
in die Deklaration geschrieben werden (allgemeine Elemente können das Inhaltsattribut nicht schreiben). Das Attribut von content
ist wie ein echtes DOM-Element. Es kann Boxen generieren und an der anschließenden Schriftsetzung und Darstellung teilnehmen. So können wir Attribute wie border
, background
usw. deklarieren. 🎜🎜🎜 kann wie folgt verstanden werden: 🎜Das Pseudoelement fügt der Schnittstelle ein nicht vorhandenes Element hinzu. 🎜🎜::first-line
und ::first-letter
haben unterschiedliche Mechanismen. Diese beiden existieren tatsächlich inhaltlich. Wie der Name schon sagt, wählen sie die „erste Reihe“ und den „ersten Buchstaben“ aus. Sie sind kein nicht existierendes Element, sie umschließen einen Teil des Textes, sodass wir ihn bearbeiten können. ::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
vorher und nachherIn unserem Konzept können wir uns vorstellen, dass ein Selektor mit einem Vorher-Pseudoelement ihm den Inhalt des tatsächlich ausgewählten Elements liefert. Nachdem wir ein Element hinzugefügt haben, müssen wir ihm nur noch Textinhalt über sein Inhaltsattribut hinzufügen. (Hier können wir dem Pseudoelement auch
content: ''
als leer zuweisen) Wir können also das Anzeigeattribut für Vorher und Nachher auf beliebige Weise angeben, genau wie bei verschiedenen Elementen.
Wenn wir einige Komponenten implementieren, verwenden wir häufig diese Methode, um der Seite dekorative Inhalte hinzuzufügen, die den DOM-Baum nicht verschmutzen, aber tatsächlich visuelle Effekte erzeugen können. <div>
<::first-line>content content content content content</::first-line>
content content content content
content content content content
content content content content
</div>
first-letter und first-line
first-letter
ist gleichbedeutend damit, dass wir ein Element haben, um das erste Element einzufügen Im Inhalt sind Buchstaben in Klammern eingeschlossen. Wir können verschiedene Attribute dieses Anfangsbuchstaben
nach Belieben deklarieren, seinen Inhalt jedoch nicht ändern. Wir alle sollten den Effekt gesehen haben, dass der erste Buchstabe in einer Zeitung größer wird und dann getrennt wird. In CSS können wir den Pseudoelement-Selektor ::first-letter
verwenden. Die Implementierung ist stabiler und der Code ist eleganter als die Verwendung von 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>
erste Zeile
ist für die Zeile
nach dem Satz. Tatsächlich hat es nichts mit der ersten Zeile
in unserem Quellcode zu tun . Wenn unsere Browser unterschiedliche Rendering-Breiten bereitstellen, ist die Anzahl der von first-line
eingeschlossenen Elemente in den beiden Umgebungen unterschiedlich. Wenn wir diesen Selektor verwenden, müssen wir ihn entsprechend den Anforderungen verwenden. Es ist sehr wahrscheinlich, dass der Rendering-Effekt auf unserem Entwicklungscomputer und dem Computer des Benutzers unterschiedlich ist! SchriftartserieFarbserieHintergrundserie
word-spacingline-height🎜Box-Modellreihe: Rand, Polsterung, Rand🎜🎜🎜🎜🎜Kleine Übung🎜 🎜 🎜🎜 🎜Schreiben Sie eine Match-Funktion. Es akzeptiert zwei Parameter, der erste Parameter ist eine Selektor-String-Eigenschaft und der zweite Parameter ist ein HTML-Element. Sie können sich dieses Element so vorstellen, wie es in einem DOM-Baum vorhanden sein muss. Verwenden Sie Selektoren und DOM-Elemente, um zu bestimmen, ob das aktuelle Element mit unserem Selektor übereinstimmen kann. (Sie können keine integrierten Browserfunktionen verwenden, sondern nur die übergeordneten und untergeordneten DOM-APIs verwenden, um zu bestimmen, ob ein Element mit einem Selektor übereinstimmen kann.) Im Folgenden finden Sie ein Beispiel für einen Aufruf. 🎜🎜rrreee🎜Weitere Programmierkenntnisse finden Sie unter: 🎜Programmiervideo🎜! ! 🎜
Das obige ist der detaillierte Inhalt vonEin genauerer Blick auf Selektoren in CSS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!