CSS 选择器 - Pseudo-classes

伪选择器,此选择器不选择网页元素,但却是网页元素的一部分,或者说是网页元素所处于的某一环境、或者某一状态。

Pseudo-classes

伪类是使用 ':' 连接于选择器之后的关键字。

:active

此伪类匹配被用户激活的元素。此伪类会被后声明的(:link, :hover, :visited)覆盖。为了正常加上此伪类样式,应当以 LVHA 顺序添加。:link - :visited - :hover - :active

:checked

此伪类选择器表示任何处于选中状态的 radio checkbox select元素中的option

div,
select {
  margin: 8px;
}

/* Labels for checked inputs */
input:checked + label {
  color: red;
}

/* Radio element, when checked */
input[type="radio"]:checked {
  box-shadow: 0 0 0 3px orange;
}

/* Checkbox element, when checked */
input[type="checkbox"]:checked {
  box-shadow: 0 0 0 3px hotpink;
}

/* Option elements, when selected */
option:checked {
  box-shadow: 0 0 0 3px lime;
  color: red;
}

:default

表示一组相关元素中的默认表单元素。可用于

@page :first {
  margin-left: 50%;
  margin-top: 50%;
}

p {
  page-break-after: always;
}
document.querySelector("button").onclick = function () {
  window.print();
}

:first-child

匹配一组兄弟元素中的第一个元素。

This text is selected!

This text isn't selected.

This text isn't selected: it's not a `p`.

This text isn't selected.

  • Item 1
  • Item 2
  • Item 3
    • Item 3.1
    • Item 3.2
    • Item 3.3
p:first-child {
  color: lime;
  background-color: black;
  padding: 5px;
}

ul li {
  color: blue;
}

ul li:first-child {
  color: red;
  font-weight: bold;
}

:first-of-type

匹配一组兄弟元素中同类型元素的第一个元素。

This `div` is first!
This nested `span` is first!
This nested `em` is first, but this nested `em` is last!
This nested `span` gets styled!
This `b` qualifies!
This is the final `div`.
article :first-of-type {
  background-color: pink;
}
/*
未指明单一类型选择器,会匹配此种类型组中的第一个元素。
*/

:fullscreen

匹配处于全屏模式的每一个元素。

MDN Web Docs Demo: :fullscreen pseudo-class

This demo uses the :fullscreen pseudo-class to automatically change the style of a button used to toggle full-screen mode on and off, entirely using CSS.

#fs-toggle:not(:fullscreen) {
  background-color: #afa;
}

#fs-toggle:fullscreen {
  background-color: #faa;
}

:focus

匹配获得焦点的元素。例如:表单中的输入框被点击,或者使用 Tab 键选中。



.red-input:focus {
  background: yellow;
  color: red;
}

.blue-input:focus {
  background: yellow;
  color: blue;
}

:focus-within

匹配获得焦点的元素,或者该元素所包含的元素获得焦点。指其或其后代获得焦点。

Try typing into this form.


form {
  border: 1px solid;
  color: gray;
  padding: 4px;
}

form:focus-within {
  background: #ff8;
  color: black;
}

input {
  margin: 4px;
}

:hover

匹配同光标设备互动的元素。无需进入元素,在元素上划过就会触发匹配。

Try hovering over this link.
a {
  background-color: powderblue;
  transition: background-color .5s;
}

a:hover {
  background-color: gold;
}

:indeterminate

匹配 Form 表单中处于不确定状态的元素。

此选择器的目标元素是:

的 indeterminate 属性,通过 JavaScript 设置为 true。

Form 表单中此种相同 name 值的元素未被选中的状态。

元素处于 indeterminate 状态。

input:indeterminate+label {
  background: lime;
}

:in-range

匹配 元素,此元素的值处于其 min & max 属性指定的范围之内。若未指定值的范围,此伪类不会匹配。

    Values between 1 and 10 are valid.
li {
  list-style: none;
  margin-bottom: 1em;
}

input {
  border: 1px solid black;
}

input:in-range {
  background-color: rgba(0, 255, 0, 0.25);
}

input:out-of-range {
  background-color: rgba(255, 0, 0, 0.25);
  border: 2px solid red;
}

input:in-range+label::after {
  content: 'okay.';
}

input:out-of-range+label::after {
  content: 'out of range!';
}

:invalid

匹配内容未通过验证的任何 元素或其他

表单元素。


  
  
  

input:invalid {
  background-color: #ffdddd;
}

form:invalid {
  border: 5px solid #ffdddd;
}

input:valid {
  background-color: #ddffdd;
}

form:valid {
  border: 5px solid #ddffdd;
}

input:required {
  border-color: #800000;
  border-width: 3px;
}

input:required:invalid {
  border-color: #C00000;
}

:lang()

:lang()

基于语系来匹配元素。

This English quote has a nested quote inside.
This French quote has a nested quote inside.
This German quote has a nested quote inside.
:lang(en)>q {
  quotes: '\201C' '\201D' '\2018' '\2019';
}

:lang(fr)>q {
  quotes: '« ' ' »';
}

:lang(de)>q {
  quotes: '»' '«' '\2039' '\203A';
}

:last-child

匹配一组兄弟元素中的最后一个元素。

This text isn't selected.

This text is selected!

This text isn't selected.

This text isn't selected: it's not a `p`.

  • Item 1
  • Item 2
  • Item 3
    • Item 3.1
    • Item 3.2
    • Item 3.3
p:last-child {
  color: lime;
  background-color: black;
  padding: 5px;
}

ul li {
  color: blue;
}

ul li:last-child {
  border: 1px solid red;
  color: red;
}

:last-of-type

匹配一组兄弟元素中这种类型元素的最后一个元素。

Heading

Paragraph 1

Paragraph 2

This `div` is first.
This nested `span` is last!
This nested `em` is first, but this nested `em` is last!
This `b` qualifies!
This is the final `div`!
p:last-of-type {
  color: red;
  font-style: italic;
}

article :last-of-type {
  background-color: pink;
}

:left

@page 指令一同使用,表示列印文档的所有左手页。此伪类只能变更页面盒子中的 margin padding border background 属性,对于其他属性的变更会被忽略。

@page :left {
  margin: 2in 3in;
}

:link

表示还未被访问的元素。匹配每一个未被访问的,含有 href 属性的 元素。

:link 伪类会覆盖 :active :hover :visited 伪类,注意这些伪类的优先级顺序为: (LVHA) :link - :visited - :hover - :active

This is an ordinary link.
You've already visited this link.
Placeholder link (won't get styled)
a:link {
  background-color: gold;
  color: green;
}

:match() & :is()

表示匹配指令括号中,选择器类型列表对应指示的元素

/* Selects any paragraph inside a header, main
   or footer element that is being hovered */
:is(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

/* The above is equivalent to the following */
header p:hover,
main p:hover,
footer p:hover {
  color: red;
  cursor: pointer;
}

/* Backwards-compatible version with :-*-any() and :matches()
   (It is not possible to group selectors into single rule,
   because presence of invalid selector would invalidate whole rule.) */
:-webkit-any(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}
:-moz-any(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}
:matches(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

跨浏览器

This is my header paragraph

  • This is my first

    list item

  • This is my second

    list item

This is my footer paragraph

:-webkit-any(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

:-moz-any(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

:matches(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

:is(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}
let matchedItems;

try {
  matchedItems = document.querySelectorAll(':is(header, main, footer) p');
} catch (e) {
  try {
    matchedItems = document.querySelectorAll(':matches(header, main, footer) p');
  } catch (e) {
    try {
      matchedItems = document.querySelectorAll(':-webkit-any(header, main, footer) p');
    } catch (e) {
      try {
        matchedItems = document.querySelectorAll(':-moz-any(header, main, footer) p');
      } catch (e) {
        console.log('Your browser doesn\'t support :is(), :matches(), or :any()');
      }
    }
  }
}

matchedItems.forEach(applyHandler);

function applyHandler(elem) {
  elem.addEventListener('click', function(e) {
    alert('This paragraph is inside a ' + e.target.parentNode.nodeName);
  });
}

:not()

表示不匹配指令括号中,选择器类型列表对应指示的元素。

I am a paragraph.

I am so very fancy!

I am NOT a paragraph.
.fancy {
  text-shadow: 2px 2px 3px gold;
}

/* 

elements that are not in the class `.fancy` */ p:not(.fancy) { color: green; } /* Elements that are not

elements */ body :not(p) { text-decoration: underline; } /* Elements that are not

or elements */ body :not(div):not(span) { font-weight: bold; } /* Elements that are not `.crazy` or `.fancy` */ /* Note that this syntax is not well supported yet. */ body :not(.crazy, .fancy) { font-family: sans-serif; }

:nth-child()

基于该元素在一组兄弟元素中所处的位置来匹配该元素。该指令的括号中,只有一个用以指定位置的参数。

/*
表示奇数索引
2n+1 = 2*0+1, 2*1+1, 2*2+1, 2*3+1, ......
*/
tr:nth-child(odd)
tr:nth-child(2n+1)

/*
表示偶数索引
2n = 2*0, 2*1, 2*2, 2*3, ......
*/
tr:nth-child(even)
tr:nth-child(2n)

/*表示第 7 个元素*/
:nth-child(7)

/*表示(5n = 5*0, 5*1, 5*2, 5*3, ......)索引元素*/
:nth-child(5n)

/*表示(3n+4 = 3*0+4, 3*1+4, 3*2+4, 3*3+4, ......)索引元素*/
:nth-child(3n+4)

/*表示(-n+3 = -0+3, -1+3, -2+3, -3+3, ......)索引元素*/
:nth-child(-n+3)

/*表示一组兄弟元素中的每一个 

元素*/ p:nth-child(n) /*表示一组兄弟元素中的第一个

元素,同 :first-child 伪类作用相同*/ p:nth-child(1) p:nth-child(0n+1) /*表示一组兄弟元素中的第八个至第十五个

元素*/ p:nth-child(n+8):nth-child(-n+15)

    

span:nth-child(2n+1), WITHOUT an <em> among the child elements.

Children 1, 3, 5, and 7 are selected.

Span 1! Span 2 Span 3! Span 4 Span 5! Span 6 Span 7!

span:nth-child(2n+1), WITH an <em> among the child elements.

Children 1, 5, and 7 are selected.
3 is used in the counting because it is a child, but it isn't selected because it isn't a <span>.

Span! Span This is an `em`. Span Span! Span Span! Span

span:nth-of-type(2n+1), WITH an <em> among the child elements.

Children 1, 4, 6, and 8 are selected.
3 isn't used in the counting or selected because it is an <em>, not a <span>, and nth-of-type only selects children of that type. The <em> is completely skipped over and ignored.

Span! Span This is an `em`. Span! Span Span! Span Span!
html {
    font-family: sans-serif;
}

span,
div em {
    padding: 5px;
    border: 1px solid green;
    display: inline-block;
    margin-bottom: 3px;
}

.first span:nth-child(2n+1),
.second span:nth-child(2n+1),
.third span:nth-of-type(2n+1) {
    background-color: lime;
}

:nth-last-child()

基于该元素在一组兄弟元素中所处的位置来匹配该元素(不过此时,以倒序来索引元素位置)。该指令的括号中,只有一个用以指定位置的参数。

/*
表示奇数索引
2n+1 = 2*0+1, 2*1+1, 2*2+1, 2*3+1, ......
从后往前计算索引
*/
tr:nth-last-child(odd)
tr:nth-last-child(2n+1)

/*
表示偶数索引
2n = 2*0, 2*1, 2*2, 2*3, ......
从后往前计算索引
*/
tr:nth-last-child(even)
tr:nth-last-child(2n)

/*
表示第 7 个元素
从后往前计算索引
*/
:nth-last-child(7)

/*
表示(5n = 5*0, 5*1, 5*2, 5*3, ......)索引元素
从后往前计算索引
*/
:nth-last-child(5n)

/*
表示(3n+4 = 3*0+4, 3*1+4, 3*2+4, 3*3+4, ......)索引元素
从后往前计算索引
*/
:nth-last-child(3n+4)

/*
表示(-n+3 = -0+3, -1+3, -2+3, -3+3, ......)索引元素
从后往前计算索引
*/
:nth-last-child(-n+3)

/*
表示一组兄弟元素中的每一个 

元素 从后往前计算索引 */ p:nth-last-child(n) /* 表示一组兄弟元素中的第一个

元素,同 :last-child 伪类作用相同 从后往前计算索引 */ p:nth-last-child(1) p:nth-last-child(0n+1) /* 表示一组兄弟元素中的第八个至第十五个

元素 从后往前计算索引 */ p:nth-last-child(n+8):nth-child(-n+15)

    
First line
Second line
Third line
Fourth line
Fifth line
table {
    border: 1px solid blue;
}

/* Selects the last three elements */
tr:nth-last-child(-n+3) {
    background-color: pink;
}

/* Selects every element starting from the second to last item */
tr:nth-last-child(n+2) {
    color: blue;
}

/* Select only the last second element */
tr:nth-last-child(2) {
    font-weight: 600;
}

:nth-last-of-type()

基于其在一组兄弟元素中的位置,来匹配给定类型的元素,元素索引从后向前计算。该指令只包含一个位置参数。

    
This is a span. This is another span. This is emphasized. Wow, this span gets limed!!! This is struck through. Here is one last span.
span:nth-last-of-type(2) {
    background-color: lime;
}

:nth-of-type()

基于其在一组兄弟元素中的位置,来匹配给定类型的元素,元素索引从前向后计算。该指令只包含一个位置参数。

    
This element isn't counted.

1st paragraph.

2nd paragraph.

This element isn't counted.

3rd paragraph.

4th paragraph.

/* Odd paragraphs */
p:nth-of-type(2n+1) {
    color: red;
}

/* Even paragraphs */
p:nth-of-type(2n) {
    color: blue;
}

/* First paragraph */
p:nth-of-type(1) {
    font-weight: bold;
}

:only-child

表示没有任何兄弟元素的元素。类同: :first-child:last-child :nth-child(1):nth-last-child(1)

    
I am an only child.
I am the 1st sibling.
I am the 2nd sibling.
I am the 3rd sibling,
but this is an only child.
  1. First
    • This list has just one element.
  2. Second
    • This list has three elements.
    • This list has three elements.
    • This list has three elements.
div:only-child {
    color: red;
}

div {
   display: inline-block;
   margin: 6px;
   outline: 1px solid;
}

li li {
    list-style-type: disc;
}

li:only-child {
    color: red;
    list-style-type: square;
}

:only-of-type

表示没有相同类型兄弟元素的元素。

    
I am `div` #1.

I am the only `p` among my siblings.

I am `div` #2.
I am `div` #3. I am the only `i` child. I am `em` #1. I am `em` #2.
main :only-of-type {
    color: red;
}

:optional

表示任何一个未设定 required 属性的