前言
这篇记入一些我常用到.
以前写的笔记
Whatever (*)
* {}
By Id (#)
#id {}
By Class (.)
.class-name {}
By Tag
p {}
By Attribute
[data-value] {}
方括弧配上 attribute name
注: 这个 attribute name 是 full match, 它是做不到 starts with, contains 之类匹配的哦. stackoverflow
attribute value 的匹配则有许多种:
full match (=)
<div class="my-class1 my-class2">value</div>
[class="my-class1 my-class2"] 一定要写完整.
[class="my-class1"] 这样是匹配不到的
starts with (^)
^ 和 regex 表示 starts with 是一样的
[class^="my-class1"] 匹配成功
[class^="my-class2"] 匹配不到
ends with ($)
^ 和 regex 表示 ends with 是一样的
[class$="my-class2"] 匹配成功
like (*)
[class*="1 m"] = SQL LIKE %1 m%
1 m 就是最中间的值
匹配单词 (~)
<div class="my-class1 my-class2 my-class3">value</div> <div class="my-class1my-class2my-class3">value</div>
[class~="my-class2"] 第一个 div 会被匹配到.
这个单词是以空格来分割的哦
starts with 字 hypen (|)
和 ^ starts with 不同之处
<div class="myclass1">value</div> <div class="my-class1">value</div> <div class="other my-class1">value</div>
CSS
[class^="my"] { background-color: yellow; } [class|="my"] { background-color: red; }
结果
^ 可以匹配到 div1,2 "myclass1" "my-class1"
| 则只能匹配到 div 2 "my-class1"
| 的特别是它的 my 必须是一个完整的字, 或者是一个被 hypen 切割了的完整字, 所以 class="my" or class="my-" 才匹配的到.
而 ^ 就没有完整字的概念, 只要是 starts with my 就可以, 所以 class="mysterious" 也是可以匹配到的.
div3 两个都匹配不到, 因为 div3 starts with “other”
And
Search by tag and class
p.class-name {}
粘着写就可以了
Or (, :is :where)
Search by tag1 or tag2
p, a {}
用逗号 comma
参考:
Youtube – How you can simplify your CSS with :is()
/* before */ .container1 .box1, .container1 .box2 { background-color: blue; } /* after */ .container1 :is(.box1, .box2) { background-color: blue; } /* before */ .container1 .box1, .container2 .box1 { background-color: blue; } /* after */ :is(.container1, .container2) .box1 { background-color: blue; }
在有层次的情况下使用 is 可以减少很多重复的 selector.
小心坑:
.container1 :is(.box1, div) { background-color: chocolate; } .container1 div { background-color: crimson; }
下面的 div 无法 override 上面的. 原因是 is(.box1, div) 里面有一个 class selector. 所以整个 is 的权重就上去了. 如果没有这个 .box1 那么 div 对 div 就可以 override 成功.
where 和 is 完全一样, 区别就在它没有这个权重问题. 它权重就是 0. 所以下面可以 override 到它.
Child (>)
.parent > span {}
用大过箭头 greater than sign
Descendant (空格)
.parent span {}
用空格
Next One Sibling Element (+)
Search class "target" next whatever element
.target + *
它只能匹配 next 的 1 个 element 哦. 如果 next 没有匹配到就 stop 了
注: 没有 prevous selector 的哦. stackoverflow
Next All Sibling Element (~)
.target ~ *
和 + 类似, 只是它不只匹配 1 个, 会一直 next 下去匹配.
选择第 n 个 (nth-of)
参考: 深入理解css3中nth-child和 nth-of-type的区别
有 nth-of-type 和 nth-child
它们都是用来获取 child element 的 (如果没有指定 parent, 那么每一个 parent 的 child 都可能被匹配到)
它们不同之处在于 type, of-type 会跟 tag 跑. of-child 则不管 tag
nth-child
<div>value1</div> <div>value2</div> <div>value3</div> <div>value4</div>
div:nth-child(2) { red }
这句表示, 找第 2 个元素, 同时如果它是 div 就给红色.
所以上面这个 HTML 的第 2 个 div 会红色.
但如果
<div>value1</div> <p>value1.5</p> <div>value2</div> <div>value3</div> <div>value4</div>
第 2 个元素不是 div 而是 p 的话, 那么就不会红色了.
nth-of-type
div:nth-of-type(2) { red }
只是把 child 换成了 of-type, 它的表示是, 找第 2 个 div 给红色. (和刚才的 child 差很多吧)
所以第 2 个 div 会变红色
when no specify tag
那如果我们没有声明 tag 会怎样?
div:nth-child 的 div 算是一种限制, 如果没有限制, 那么只要是第 2 个 element 就能变红色
div:nth-of-type 的 div 是一种匹配, 如果拿掉的话, 它会变成每一种 tag 都匹配.
<div>value1</div> <p>value1</p> <div>value2</div> <!-- red --> <div>value3</div> <div>value4</div> <p>value2</p> <!-- red -->
第 2 个 div 和 第 2 个 p 都变成红色了.
odd/even 和 n 的玩法
:nth-child(2) 是指第 2 个元素, 它是 starts with 1 而不是 0 哦.
:nth-child(odd) 奇数
:nth-child(even) 偶数
:nth-child(2n+1)
n 表示一个 looping index, 从 0 到所以 child element count, 举例我们有 7 个 div
2n + 1 的算法和结果:
依据左边的算法结果, 第 1, 3, 5, 7, 8, 11, 13, 15 的 div 要红色.
比较常用到的:
n + 3 表示 >= 3
- n + 3 表示 <= 3
nth-child(n+3):nth-child(-n+5) 写 2 个, 表示 between 3 – 5
局限
jquery 有 .eq() 函数, CSS 是无法做到这个的哦.
参考: stackoverflow – Is there a standard CSS selector similar to :eq() in jQuery?
有时候会想要先 select 出 class 然后再从中选出第 n 个. jQuery 要实现的话用 $('.class').eq(n)
CSS selector 是无法做到这一点的. 经常会以为 .class-name:nth-child(2) 会是答案.
但其实这个的意思是 第 2 个 element 同时它需要是 .class-name. 如果有一个 element 有 class-name 但它是第一个 child 那就 select 不到了.
所以不要搞错哦.
:target
URL 的 # hash 可以用 :target 来 select
比如 index.html#some-id
:target { background-color: red; }
这是 some-id 就变成红色的了
这技术经常用来让 CSS 具备点击能力. 通过 anchor + href hash 让另一个 element 有 style.
:not()
反向匹配. 比如: 匹配除了 paragraph 以外的元素
:not(p) { background: #ff0000; }
匹配 input text
input:not([type]), input[type='text'] { width: 100px; }
没有声明 type 默认就是 type="text" 所以也要匹配出来, 这时就可以用到 :not
常见的, 不要最后一条线
CSS Style
> *:not(:last-child) { border-bottom: 1px solid red; }
当 user input 放入 attribute 然后需要被 select (CSS.escape)
今天遇到了一个非常基础的问题. 踩了一个坑.
<div data-value="@product.name"></div>
用 JS query 的时候 [data-value="${product.name}"]
由于 product name 是用户输入的, 所以如果用户输入一些符号是会导致它坏掉的. 比如 quote symbol "
解决的方式是 escape 把 " 换去 \"
这和 HTML 的 escape 是不一样的哦. 不要问我为什么不一样,总之 escape 之后就可以 select 到了.
JS 的代码是 CSS.escape(product.name);
参考:
Can I escape HTML special chars in JavaScript?
Select Tag vs Class
参考: You Need to Stop Targeting Tags in CSS
HTML 有许多 tag 是有语义的, 这也让我们有机会利用它们来当作 selector.
但是大部分人不鼓励这个做法, 因为稍微复杂点的结构, 这种做法就 cover 不了了.
最常见的就是相同的 tag 有嵌套.
比较理想的方式就是给 element class 特别的命名. 它可以更加语义化. 而且完全受控.
但随之而来的就是取名字难题. 这时不妨考虑一下结合 Tailwind CSS 利用 atom class 的特性来替代 selector.
class 的命名应该是表示元素的, 而不是它的 style. 比如 blue-text 就不是一个 class selector, 而是一个 atom class.
nav-text 就是一个元素 selector.
实战例子:
Hover element A effect element B
参考: stackoverflow – How to affect other elements when one element is hovered
CSS Specificity 樣式權重
参考
铁人赛 – Day07【CSS】特異性 Specificity(樣式權重)
id, class, attribute, tag 这些 selector 是有分权重的, 比如 id 比 tag 大.
不管 style 的顺序, selector 的方式比较大就会 render 它的 style.
它有一个算分机制, 比如 1 个 class + 10 分, 一个 id + 100 分, 但 11 个 class 并不能大过 1 个 id 哦 (记分数得先看等级)
通常用 tag 的时候会比较危险, 还有当想 override 第三方类库的时候也要多注意就可以了.
用 VS Code hover 到 selector 上面可以看见分数哦