ThoughtWorks®

Css selector

Created by

WANG Lina

CSS selector

  • id选择器(#myid)
  • 类选择器(.myclassname)
  • 标签选择器(div,h1,p)
  • 相邻选择器(h1+p)
  • 子选择器(ul > li)
  • 后代选择器(li a)
  • 通配符选择器(*)
  • 属性选择器(a[rel="external"])
  • 伪类选择器(a:hover,li:nth-child)

CSS Weights

                    
.count {color: yellow}

body header div nav ul li div p a span em {color: red}
                    
                

!important > inline > id > class > tag

html标签 (1); class (10); id (100)

div p 1+1 = 2

span.test 1+10 = 11

#id.test 100 +10 = 110

A,B,C,D

A:如果规则是写在标签的style属性中(内联样式),则A=1,否则,A=0. 对于内联样式,由于没有选择器,所以B、C、D的值都为0,即A=1, B=0, C=0, D=0(简写为1,0,0,0); B:计算该选择器中ID的数量。(#header,0, 1, 0, 0); C:计算该选择器中伪类及其它属性的数量(包括class、属性选择器等,不包括伪元素)。 (.logo[id='site-logo'],0, 0, 2, 0); D:计算该选择器中伪元素及标签的数量。(p:first-letter ,0, 0, 0, 2)。
                    
.count {color: yellow}  0, 0, 1, 0
body header div nav ul li div p a span em {color: red}  0, 0, 0, 11
                    
                
A,B,C,D四组值,从左到右,分组比较,如果A相同,比较B,如果B相同,比较C,如果C相同,比较D,如果D相同,后定义的优先。
                        
                    

div #in-div VS #out-div div .myclassname VS #out-div p.myclassname #myid VS p#myid .myclassname VS p.myclassname

浏览器是如何读取选择器,以识别样式,并将相应的样式附于对应的HTML元素,达到美化页面的效果捏??

选择器从右到左的原则

浏览器读取选择器的顺序是由右到左进行
                            div.nav > ul li a[title]
                            
                        
浏览器首先会尝试在HTML标签中寻找“a[title]”元素,再匹配“li和ul”,最后匹配“div.nav”
选择器的最后一部分(a[title]) 关键选择器 ,它将决定你的选择器的效率

如何让关键选择器更有效,性能化更高呢?

  • 尽量避免 universal rules
  •                 [hidden="true"] { ... } /* A universal rule */
                    
    查找页面上的所有节点。 越具体的关键选择器,其性能越高
  • Id-categorized 规则与 tag name 或 class 规则并行
            
                button#goButton          VS    #goButton
                .fundation#testIcon      VS    #testIcon
            
                    

    用相对更具体的选择器来定位一个节点往往比组合定位更加快捷

  • 尽量避免使用 descendant selector
  • Child selector

                    #toc > li {font-weight: bold}
                    

    Descendant selector

                    #toc li {font-weight: bold}
                    
    浏览器先遍历所有的“li”节点,然后步步上溯其父节点,直到 DOM 结构的根节点,如果有某个节点的 id 为“toc”,则匹配成功,继续查找下一个“li”节点。
    
        treehead treerow treecell  VS  treehead > treerow > treecell
    
                    
    如果能用 child 选择器替代就应该尽量这样去做。
  • 尽量减少规则数量
  •                     
        Span[mailfolder="true"] > table > tr > td.columnClass
        .span-mailfolder-tbl-tdCol
                        
                    
    前一种规则需要进行 6 项匹配,先找“columnClass”,再找“td”,然后是“tr”,“table”,最后是符合“mailfolder”为“true”的 span,这种效率是非常慢的。 如果用一个比较特殊的 class 替代(span-mailfolder-tbl-tdCol),效率会快上好几倍。
  • 尽量利用 CSS 的继承机制
  • 
        Color
        Font
        Letter-spacing
        Line-height
        List-style
        Text-align
        Text-indent
        Text-transform
        White-space
        Word-spacing
    
    
        #bookmark > .menu-left {list-style-image: url(blah)}
        #bookmark {list-style-image: url(blah)}
    
                    
    如果很多子节点都需要设定该 CSS 属性值,可以统一设定其父节点的该 CSS 属性,这样一来,所有的子节点再无需做额外设定,加速了 CSS 的分析效率

    m-site example

    
    .REA-details-page section.description .descriptionWrapper p,
    .REA-agent_details-page section.description .descriptionWrapper p{
        line-height: 18px;
        padding-bottom: 10px;
    }
    
    
    .REA-details-page .classicproject .contactBlock ul li a span,
    .REA-details-page .signatureproject .contactBlock ul li a span,
    .REA-details-page .midtier .contactBlock ul li a span,
    .REA-details-page .signature .contactBlock ul li a span{
        display: block;
        position: relative;
    }
    
                    

    pseudo classes

    动态

  • :link
  • :visited
  • :hover
  • :active
  • :focus
  • demo

    元素状态

  • :enabled
  • :disabled
  • :checked
  • :unchecked
  • nth选择器

  • :first-child :last-child
  • :nth-child() :nth-last-child()
  • :nth-of-type() :nth-last-of-type()
  • :first-of-type :last-of-type
  • :only-child :only-of-type
  • :empty
  • :not
  • demo

    pseudo elements

    • ::first-line
    • ::first-letter
    • ::before
    • ::after
    p>i:first-child {color: red}
    
                    

    first second

    .first-child {color: red}
    
                    

    first second

    p:first-letter {color: red}
    
                    

    I am stephen lee.

    .first-letter {color: red}
    
        

    I am stephen lee.

    伪类的效果可以通过添加一个实际的类来达到,而伪元素的效果则需要通过添加一个实际的元素才能达到。

    Thank you!