以前我接受了网上不少博文的说法,一直认为学习css的三大最重要问题是:盒模型、定位、浮动。因为这三块的内容决定了css布局的能力。但是通过上一篇日志的分析,xhtml要实现和css的解耦,就要尽量不依赖于css(或者说不要纯粹为了给css预留接口而添加不必要的class和id),那么,在用css布局之前,其实就有一个更紧迫的任务摆在我们的面前——如何将css规则准确应用到目标元素。于是,css选择符的地位在这个前提下就空前的提高了。所以,在开始学习盒模型、浮动、定位之前,有必要回顾一下选择符。
一般稍微接触过css的网页设计人员,都会很快地学会三种css选择符:
- 元素选择符(例如:body 、a 、li )
- ID选择符(例如:#head、#body、#foot)
- 类选择符(例如:.red、.item、.content)
更进一步之后,开始了解到一些进阶的选择符:
- 后代选择符(例如 #head .menu、#foot #copyright)
- 伪类选择符(例如 a:hover、a:link)
以及由这些选择符组合起来形成的综合选择符。实际上css还支持一些更丰富的选择符。但是能够被浏览器广泛支持的其实主要就是上面这几种,其它的选择符在css中往往用来区别处理不同的浏览器,或者用在jQuery一类的框架中。本文就不提了。有兴趣的可以自己在网上查一下,像属性选择符(input[type=’password’]、input[type=’radio’])、直接后代选择符(body > div、 #head > ul)等。
实际上,有了上面列出的五种主要的选择符,通过对它们的组合,已经能够满足我们绝大部分时候的要求了,这也就意味着,相同结构下的元素,父级元素或者祖先元素只要有一点点区别,我们就能够在不借助id或者class的情况下直接访问到。例如:
<ul> <li><a href="#">菜单1</a> <ul> <li><a href="#">菜单1-1</a></li> <li><a href="#">菜单1-2</a></li> <li><a href="#">菜单1-3</a></li> </ul> </li> <li><a href="#">菜单2</a> <ul> <li><a href="#">菜单2-1</a></li> <li><a href="#">菜单2-2</a></li> <li><a href="#">菜单2-3</a></li> </ul> </li> </ul>
这个结构是我在《来自微软的纯css下拉菜单》一文中用到的下拉菜单结构。在那个示例中,没有使用任何的class或者id,但是我们通过不同优先级的元素+后台选择符,对结构中的不同层次的ul、li、a实现了精确定位。如下面的代码:
ul {} li {} ul ul {} ul ul li {} li a {} ul li a {} ul li:hover ul {}
那么,在实际开发中,为什么很多网页设计人员还是离不开多如牛毛的ID和class呢(我要声明一下,我从来没有说完全抛弃id和class,我的观点是他们应该尽量少,并且由文档结构决定而不是由css需要决定)?我觉得有三方面的原因:
第一、xhtml文档结构不合理,通过元素不能体现文档的层次结构。满篇都是div。没有有效利用Hx系列标签和ul、ol、dl等不同含义的列表标签、没有有效利用p、quote、pre等标签。xhtml为我们提供了丰富的标签元素,但是如果我们只会用div,那还不如人家用table来布局的。至少他的table在一定程度上也是文档结构的体现,而满篇嵌套的div,文档结构完全没体现。
第二、css选择符掌握得不够,不善于借助文档结构层次上的细微区别,用不同的组合选择符来区别相似但其实不同的元素。例如上面的下拉菜单结构,有的人就非要用“menu”和“submenu”来区别。
第三、css选择符的优先级不清楚。css是支持继承和覆盖的,什么时候继承,什么时候覆盖。两条规则都对相同元素做出了样式规定而且样式规定重复的情况下,哪一条规则会被应用呢?这些问题不清楚,就没办法充分利用优先级实现规则的覆盖。于是只好每个要应用样式的元素都加上id或者class。关于css选择符的优先级,网上也有很多文章,我就不赘述了。
所以说,如果感觉离不了class,离不了id,那只能说明两个问题——xhtml结构不合理或者css掌握得还不够。我上一篇博文发了以后,有位朋友评论说我没做过前台开发。因为没有class和id,就不能实现css和javascript的分离。实际上,只要是长期深入学习css和javascript的朋友应该都清楚:在结构有差异的情况下,用css选择符就能精确定位某个元素;在结构完全相同的情况下,借助javascript和DOM,同样可以精确定位某个元素。
仍然以上面的下拉菜单列表为例。首先使用 ul a 对父级菜单的链接应用样式,然后用ul ul a就可以精确定位到次级菜单的链接,应用新的样式,对ul a的定义进行覆盖。那么,如果是要精确定位到第二级菜单的第二个元素呢?由于css3的选择符目前还没被广泛支持,而结构又没有差异,不借助javascript有困难了。但是借助于javascript,非常轻松,比如在jQuery中,我们可以用 $("ul ul:nth(2) li:nth(2)”) 或者 $("ul ul”).eq(1).find(“li”).eq(1) 都能得到第二个子菜单的第二个菜单元素。
css和javascript能够自己精确找到网页中的任何一个元素,那么网页自然就不用自己标识自己的每个元素。少了这层负担,我们在设计网页文档结构的时候,自然就可以抛弃一切后顾之忧,那么,xhtml中和结构无关的id和class,还有什么必要存在呢?
去除了不必要的表现元素和属性(font、center、align、height)之后,又去除了不必要的id、class、onclick、onmouseover之类的样式和行为属性,我们的网页源代码尺寸越来越小,抓一个页面下来,少量必要的结构元素之外,剩下的全是链接和内容,这样的网站,搜索引擎能不喜欢吗?
没有了后顾之忧,认清了努力方向,那么下一次我们就来谈谈css的盒模型。
作者:小李刀刀
原文链接:前台开发从头说起:谈谈CSS选择符
裁纸刀下版权所有,允许非商业用途转载,转载时请原样转载并标明来源、作者,保留原文链接。
Great site, determined a couple of something completely new! Subscribed RSS for later, wish to see more updates such as this one.
Good work, keep us posting, you are very good writer.
Very interesting post. Keep writing dude !!
Pingback引用通告: 前台开发从头说起:理解css盒模型 | 所谓技术 - 小李刀刀博客
To:@忌夏日
在实际使用中学习是最容易掌握的。加油。
To:@小馒头
你是谁啊?
呵呵···老师,好久没见你写东西了,哈哈今天终于见了篇,学习学习!
CSS学了一些,已经能够让HTML代码具有一定语义化,利用CSS实现一些常用效果;
现在打算去学JS,然后再一起搭配,一起提高……