CSS选择器有很多种,每次看别人写的跟背书一样,没办法,种类就那么多,只能一一罗列,还能玩出什么花样?所以重要的就是清楚为什么要这样用,好处在哪里了。
如果我们的网页只是像老板吩咐我们做3件事的清单那样简单,做完一件划掉它,所以一眼可以看出哪件已做,哪件没做,而html网页是有结构的、嵌套的标签组织起来的文本形式,又多又长,所以需要选择器来快速定位,以应用我们添加给它的样式,因此了解选择器很有意义。
1. 标签选择器
在CSS中,有的标签本身已经具有一些样式,比如h1,通常会作为标题,它的字体比一般的大,默认为粗体,而且是块级标签,四周有margin值。标签选择器,本质上来说,就是给一个标签重新定义样式。还是h1,因为用它作标题有利于搜索引擎,所以经常用,但它自带的样式有时(恐怕是多时)与网页布局显得很不合理,所以我们完全可以重写它的样式,改变字体大小,去掉margin等,以达到整体控制的效果。只要重定义了它的样式,直接用h1将显示运用了新样式后的文本内容,这样更和谐了。
h1{font-size:1em;}
2. 类选择器
既然是类,更多的是对一个或几个元素产生影响,为了减少工作量和精确控制,对相同的类型的一些元素给一个相同的class名,是很不错的选择,重点是可以在一个class中添加多个类名,更加省时。如这里三个选择器各添加不同的样式,都会加载到这段文本上。当然CSS样式是就近原则,后面的覆盖前面的,优先级高的覆盖优先级低的,所以假如mr也设置了font-size,它将覆盖掉ft选择器中的font-size。
.ft{font-size:24px;} .mr{margin:10px;} .fl{float:left;} <p class="ft mr fl ">Hello World</p>
专业的前端通常会同时使用几个类,一个fl,表示飘浮到页面左边,单独写一个样式,需要时就加上,因此它更像一个工具,拆分成多个类名,扩展性更强。注意类名中可以出现 - 或 _ ,这是允许的。
3. ID选择器
ID给人一种唯一标识的感觉,所以它经常是刻划网页上一个特殊的部位,更多的是表示某一部分内容,比如横幅(banner)、边栏(sidebar)、主要内容(main)等,如划分一个大块时经常这样像下面这样,当然如果你说我就喜欢用ID选择器,我把所有的标签都加ID,唯一结果就是肯定不会有人过去咬你-_-#
#news{ margin-left:10%; font-family:"Times New Roman" } <div id="news"> ........ </div>
关于ID有个重点就是它具有高优先级,比如下面
#link{ color:red; } .link{ color:blue; } <a id="link" class="link" href="#">To Somewhere</a>
它是红色还是蓝色?演示就知道是红色,因为ID选择器具有更高的优先级,浏览器会根据ID和class(或者组合)计算出一个权重值,谁的大用谁的样式(理论上是这样,但用Chrome试过好像也不一定),权重值的计算如果深究也有点麻烦,特别是不只一个ID、class、标签纠缠在一起时。如何计算权值网上也有文章分析,当然我们何必要为难自己呢,至少我自己(向前端学的)有时做简单的页面,只用类选择器,只在有时用js时为了快速取到元素才加id,基本不用ID选择器添加样式,避免麻烦。
4. 群选择器
如果看过专业前端的css代码,肯定在最开头有类似这样的:
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li{ margin: 0; padding: 0; }
一开始偶不明白为何弄这样一大堆标签,以为是设计时对样式从整体到局部的把握,所以先给所有的标签元素一两个基本的、整体的样式,像这里margin、padding就是让它们所有的标签都归为0。后来发现,这么说也不能说全错,但更重要的是,很多浏览器在处理一些自带样式的标签时(如h1~hn),虽然左右是有空白的,但有的使用margin,有的使用padding,不统一可能带来样式上的错乱,为了让样式在更多浏览器上显示一致,所以这里干脆去掉它们的margin、padding,当要使用某个标签时,再给单独添加margin、padding。这里的一大堆标签,以逗号分隔的选择器,称为群选择器,表示把它们都设置成一个后面括号中样式。群选择器不限于标签,class、id也可以这样干:.link, .news, #banner{...}。群选择器在设置一大堆具有相同样式的标签、类、ID时很方便。关于上面那个一大堆把margin、padding置为0的、提高显示一致性设计,有个名字叫CSS Reset,样式重置,这是偶这种小白平常用不到的。
5. 通用选择器
群选择器一次设置多个很爽,堆在一起用逗号分隔即可,还有更爽的,就是通用选择器,它就是一个 * ,代表所有选择器(通用嘛),比如下面
h1, h2, p{font-weight:bold;} * {font-weight:bold;}
第二个通用选择器等同于设置了第一个群选择器的内容,当然能比它代表更多的东西。
6. 派生选择器
这应该是专业前端最最常用的类型了,也称后代选择器。我们知道html标签是嵌套的,外面的是父元素,里面的是子元素,当然父子关系是相对的,这叫做html的族谱,当然它也有根节点,兄弟节点等,这根二叉树完全一样,所以也有相应的父标签、祖先标签、兄弟标签等等。比如像这样的
<div id="nav"> <ul class="nav"> <li></li> <li></li> </ul> </div>
ul是div的子标签,li是ul的子标签,id选择器在类选择器nav的标签的父标签里边,所以定位到<li>标签的选择器可以这样写:
#nav .nav li{...}
需要注意的地方就是中间有空格,空格表示子标签,或者是位于子标签中的选择器,即一种父子关系,子孙关系也可,爷孙关系当然也行,总之就是:派生关系。对于派生选择器,如果不隔一个空格就是完全另一种情况,比如这里如果写 div#nav ul{...}(div紧挨着#nav)表示的就是:<div id="nav"><ul>,给id为nav的div标签,它的子标签为ul设置样式,是一个限制的并且关系,如果是div #nav ul{...},就是div标签的id为nav的子标签,它的子标签为 li 时的情况。空格很重要!
看看专业前端的代码,派生选择器会占到百分之八九十,而且风格比较统一,派生时尽可能用class,当然最后会有一些标签选择器,但风格真的很好,不是一会儿类选择器,又夹个ID选择器,再来个标签选择器,最后再搞个ID选择器,这样看起来十分紊乱,一点也不丝滑,专业人士写的就是有种和谐的美感。
除了一会ID选择器一会儿类选择器不好看之外,有个很大的原因是:很有可能你设计的这个样式根本没有运用到指定的地方,虽然很希望是它用到你指定的地方。比如
<div id="id_wrap" class="cl_wrap"> <p id="id_seg" class="cl_seg"> Hello World </p> </div> 1 div p {...} 2 #id_wrap #id_seg{...} 3 .cl_wrap .cl_seg{...} 4 .cl_wrap #id_seg{...} 5 div #id_seg{...} 6 div .cl_seg{...} 6 .cl_wrap p{...} 7 #id_wrap p{...} 8 div.cl_wrap p{...} 9 #id_wrap p.cl_seg{...} ... ...
这9个样式都可以运用到Hello World上(单独写的话),继续组合下去,还有,如果把这些都写出来,最后哪一个会真正加载到文本内容上呢?这里就有一个权重值的问题,前面说过,就权值来说,ID选择器最大(在选择器中),看过一本书上说:标签选择器1分,类选择器10分,ID选择器100分,内建样式1000分。内建样式即是类似<div style="width:100px;">这样的,直接在标签上给style。然后将用到的选择器权值按类型不同相加(如div p 是2分,.cl_wrap #id_seg 是110分,div.cl_wrap p是12分),结果最大的最终运用到指定内容上,但是貌似也不准确...不知道我测的对不对。计算完了,还要结合就近原则,看看哪些属性被覆盖了,哪些是继承了父元素的(如font-size,如果父元素是16px,子元素的font-size如果写的是100%就是16px,如果父元素是24px,子元素设置150%就是36px),还要看看哪些是永远保留的样式(下面,就近原则也覆盖不了)等等,这么搞下去怕迟早要疯掉...
/* !important表示这个属性将永远不会被覆盖 */ .seg{ font-style:bold !import; }
有文章对这个权值进行计算分析,偶就还是懒惰的逃避了...所以专业前端的用类选择器是没有错的,只要定位得够精确,遵循统一规范,不临时变道加个ID选择器之类的,基本不会出错。
使用派生选择器的另一大优点就是节省工作量。一个划分好布局的网页上,一块块的div中风格总是尽量的保持统一,从父元素到子元素总有很多属性相同,而css的样式是可以继承的,比如父元素的字体时16px,如果子元素不设置font-size,子元素中的字体大小将也是16px,当然也不是所有的样式都可以继承(有专门列表),如line-height行间距,这是合理的,如果父元素16px的字体大小行间距是16px,如果现在子元素的字体为54px额行间距仍是16px,就可能使得子元素中的字体行之间很紧凑甚至发生重叠,因为字体大小增大了很多行间距没变,试试可以看到效果。正式由于样式的可继承性,导致派生选择器更好用了。
7. 子选择器
根据html中标签结构的父子之分而来,形式 A > B,尖括号表示父子关系,注意说B是A的子节点,不一定是直接后代,可能是可能是孙子、曾孙、曾曾孙,编程中的父子结构相信你知道。但在这里,div > p{...}表示div标签中的所有直接子标签p,而div p表示的是div的所有直接或间接的后代节点中的p标签。
8. 同胞选择器
对共一个父元素的标签而言,它们是兄弟(或者姊妹?)关系,在css中叫同胞,而在位置上紧挨着的是临近同胞,所以css针对这种结构有一种称为临近同胞选择器,如
<div> <h1>head</h1> <p>Hello</p> </div> /******/ h1 + p {...}
h1和p是临近同胞(兄弟),h1 + p 则表示选则了紧挨在h1后面,与h1共父元素的标签p。
9. 通用同胞选择器
它是对同胞选择器的延伸,h1 + p只能对具有兄弟关系,且紧挨在h1后面的p元素起作用,那么 h1 ~ p就表示选中了具有兄弟关系的,h1后面的所有p标签。
<div> <h1>Hello</h1> <strong>Hello</strong> <p>我被选中</p> <em>Hello</em> <p>我被选中</p> </div>
10. 伪类
伪类选择器有很多,有时我们匹配的不是单个元素,而是某种状态,某种特殊的结构(简单的兄弟选择器表达不出来),或者某个动作的瞬间,比如鼠标滑过链接时,无序列表中的奇数列,这种情况的选择器,css给了个名字:伪类。
捕捉动作的,最常见的是链接,,a:link,a:visited,a:hover,a:active,分别表示未访问前,已访问过,滑过时,鼠标点击的一瞬间,a与:之间没有空格。这四个伪类的设置是有顺序的,就是这里所列出的,如果hover放到了link的前面(如下),鼠标滑过时会发现链接还是绿色的,因为他们的权重都相同,按照就近原则,后边的样式覆盖前边的(样式冲突),鼠标滑过应用的将是a:link的样式,所以要按顺序来,某书介绍了一种记法 LoVe, HAte。 在有些选择器上,hover不仅是链接的专利,比如p:hover,滑过段落时改变样式,当然只是一些浏览器、一些高版本的可以,得看具体情况。伪类的书写不一定前面就是标签,<a id="lnk">可以是#lnk:hover,css很多地方均是同理,不要理解的很死板。
a:hover{color:red;} a:link{color:green;}
:focus捕捉当获得焦点时的响应,如文本框变背景色。
匹配目标,:target,如果一个url中带有#aaa,恰好html中有带有id为aaa的标签,则匹配的是它,它用在页面内的锚点,如下,点击跳到页面内跳到锚点处可以发现它的样式已经改了(不知道br够不够)
div :target{background-color:red;} <p><a href="#goto">跳到页面内goto</a></p> <br/><br/><br/><br/><br/><br/><br/> <br/><br/><br/><br/><br/><br/><br/> <br/><br/><br/><br/><br/><br/><br/> <br/><br/><br/><br/><br/><br/><br/> <br/><br/><br/><br/><br/><br/><br/> <br/><br/><br/><br/><br/><br/><br/> <div> <p name="goto" id="goto">锚点goto</p> </div>
捕捉根节点,:root,html页面就是html节点了。
捕捉特殊子节点的,:first-child、:last-child、:first-of-type、:last-of-type等。字面义可看出是第一个子节点,或第一个子类型。值得注意的是p:first-child与p :first-child完全不同(后者两个之间有空格),前一个很容易以为,它是指p标签的第一个子节点,但实际上第二个才是这样的正确写法,而p:first-child指的是,p作为其他标签的第一个子标签,它匹配的应该是这样的
<div> <p>匹配了这里</p> <span><p>也匹配了这里</p></span> </div>
同理,p:first-of-type,指的是,作为其他元素的子元素,匹配的第一个出现的标签为p的元素,即首先,p是其他元素的子元素,第二,匹配的是子元素中第一个出现的p标签,前面有其他的类型子标签不要紧,只要不是p就行,即使它后边还有相同的p兄弟标签,因为不是第一个出现的,也不符合。
这种有点麻烦的情况,就要问问,它是它的子元素吗?它是它下面第一个出现的x标签吗?符合就是对的,如
<div> <h1>标题</h1> <span> <p>我是span的子标签中第一个出现的p</p> </span> <p>我是div的子标签中第一个出现的p</p> </div>
而 p :first-of-type(有空格),是指p标签下的第一个子元素,因为没指定类型,所以只要是p标签下边的第一个子类型,就会匹配到,等同于p :first-child,如果是p span:first-of-type,就是指
新闻热点
疑难解答