这篇文章发布于 2015年07月30日,星期四,23:42,归类于 CSS相关。 阅读 30127 次, 今日 3 次 11 条评论
by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=4876
一、不仅仅是IE7浏览器
本文所展示的一系列特性,以及一些思维方式的转变不仅适用于IE7浏览器,如果你的项目只需要兼容IE9+,或者你直接捣鼓移动端,其实都是适用的。
静心阅读,说不定会发现一些以前没注意的点。
虽然说,整个大中国,IE7份额远不如IE6浏览器,但是,我所从事的几个项目,IE6的占有率相当小,IE7却有6%多。
因此,IE7浏览器还是需要考量的。
以前在我还需要兼容IE6浏览器的时候,我总觉得IE6和IE7浏览器是一个路子的一个货色,很多bug和行为表现是一致的。认为,要兼容IE7和兼容IE7基本上没多大差别。后来深入实践发现,之前的想法有些天真了。实际上,IE7浏览器下,我们也能实现很多好玩且有价值的东西。
二、IE7新支持选择器以及作用
1. 多类选择器
所谓多类选择器指的是类似.classA.classB
这种多个类名写在一起的选择器,实际上,IE6浏览器也是支持的,但是呢?有bug. .a.c
和.b.c
貌似会冲突(年代久远,75%的确信),好像是要写成.c.a
和.c.b
.
IE7浏览器大家可以放心大胆地使用,没有任何bug存在。但是呢,根据数年前我在Chrome浏览器下的测试和分析,多类选择器是CSS选择器中性能相当低下的选择器,好像没有之一。但是呢,CSS选择器本身就很快,对吧,1~2毫秒的差异其实大家也不必在意。毕竟,没人会整个CSS文件全部都是多类选择器,那就太傻了!
IE7支持多类选择器,使得我们在CSS构建的时候,可以放心大胆使用状态类名对整个项目进行控制。
所谓状态类名,有些对应于HTML控件中的一些属性,例如:.disabled
, .checked
, .active
, .selected
. 对的,这些特性整站通用,有些人可能会疑问,到处使用,不怕冲突吗?
不怕,这些状态类名,除了通用特性,其余处于一种辅助UI的角色,需要与特定场景相关联,并不会独立使用。
例如,我们项目中有两种按钮,一种是红色,一种是绿色。类名分别是:.button_red
, .button_green
. 在IE6年代,要实现这两种按钮的禁用态,一般是两个新的独立的类名:.button_red_disabled
, .button_green_disabled
. 对于按钮本身而言,貌似没什么问题,但是从整个项目来看,有失体系。
现在,IE7支持多类选择器,我们就可以使用整站通用的.disabled
状态类名,红色和绿色按钮的禁用态书写,直接就是:.button_red.disabled {}
和.button_green.disabled {}
. 然后其他什么禁用,我们就是.xxx.disabled
等。
2. 相邻父子选择器
所谓相邻父子选择器指的是类似 .classA > .classB
这种写法的选择器,只会控制下一层级的元素。IE6浏览器支持的选择器是“后代选择器”,也就是类似.classA .classB
,两个选择器之间直接是空格,然而,这种选择器在面对复杂场景的时候,容易样式冲突,不好控制。
例如,连续的ul
,li
嵌套,单纯使用ul li
选择器非常容易出问题,因为ul
下面所有的li
标签都受影响了,而实际上,我们只想控制本ul
下面的li
元素。在IE7+浏览器下面,就没有这样的担忧,使用ul > li
选择器则完全没有这样的问题。
除了有效降低冲突,提高选择的精确度,我们还可以使用相邻父子选择器实现一些巧妙的功能。举个例子:我也页面上实现藏了几个弹框要加载的DOM元素,默认是要隐藏的,然后,加载到弹框的之前,需要是显示的。怎么搞?
我以前的做法是弹框要加载的时候,使用JS让DOM元素显示。后来鄙人发现,不需要动用JS. 由于默认的DOM元素直接放在<body>
下,而弹框装载后到了弹框里面,于是,我使用了一个小小的父子选择器就搞定了整个儿显示问题。
body > .dom { display: none; }
元素一旦载入弹框,就会自动显示,因为,它已经不是<body>
下相邻的子元素了。
3. 相邻兄弟选择器
相邻兄弟选择器指的是类似 .classA + .classB
这种写法的选择器,表示紧跟在我后面的兄弟选择器,注意必须是紧跟着的兄弟,其他远一点的,或者前面的兄弟都不行。
别小看这个选择器,我们可以让IE7浏览器也绽放夺目的光彩。
先举个简单实用的小例子。我们使用弹框的时候,右下角或左下角或者中间都有两个按钮,按钮之间有一定的距离,假设20像素:
有没有什么方法实现单纯的20像素间距,而没有其他多余的margin呢?
传统思路可能是这样:
.button { margin-left: 20px; } .button:first-child { margin-left: 0; }
中文释义就是,左边20像素间距,其中,第一个按钮左间距为0. 鼓掌。其实不失为一个好方法。如果我们转换下思路,实现起来可能就更加简单了:
.button + .button { margin-left: 20px; }
天然第一个按钮不会有margin-left
间距值。
再举个大点的也更实用的例子,大家可能听过CSS3单复选框技术. 在IE9+浏览器下,我们可以使用单选框和复选框的一些特性,实现展开收起,选项卡,开关效果等。
实际上,我们IE7浏览器也能近似实现这样的效果。IE7、IE8虽然不支持原生的CSS3选择器:checked
, 但是,属性选择器还是基本支持的,加上同样支持各类兄弟选择器,于是,IE7浏览器也能渐进使用这类CSS3新技术。
:checked + .xxx { /* IE9+选中效果 */ } [checked] + .xxx { /* IE8选中效果 */ } [defaultChecked] + .xxx { /* IE7选中效果 */ }
4. 兄弟选择器
兄弟选择器指的是类似 .classA ~ .classB
这种写法的选择器,使用的是弯弯符号,表示A元素后面的所有兄弟元素。对,只能是后面的元素。严格来说,这是个CSS3选择器,但是IE7浏览器支持之,且我使用下来还没遇到过什么诡异问题。
IE7+浏览器下,由于相邻兄弟选择器和兄弟选择器的存在,我们在JS构建一些DOM元素来实现一些UI组件效果的时候,我们的处理方法可能就会发生一些变化。举个例子,placeholder
占位符效果。从实现上讲,input
元素前插入构建的含placeholder
值的元素是最简单也更容易定位的;但是,实际实现的时候,确实要遵循后置原则, 也就是创建的元素要在目标元素的后面。
为什么呢?
原因很简单,在CSS中,我们没有前兄弟选择器,只有后兄弟选择器。于是,我们只能根据前面兄弟控制后面。
还是上面placeholder
例子,由于我们是后置实现,于是,我们就能轻松通过CSS实现focus时候,placeholder
文字透明度降低到40%的效果:
input:focus + .xxx { filter: alpha(opacity=40); }
但是,要是你前置,或者包裹,都是不行滴!
5. 属性选择器
包括CSS 2.1水平的属性选择器[attr]
, [attr="val"]
, [attr~="val"]
, [attr|="bar"]
以及CSS3水平的属性选择器[foo^="bar"]
, [foo$="bar"]
, [foo*="bar"]
.
没错,所有这些属性选择器IE7浏览器都是支持的,虽然某些细节上有些小bug, 但是,基本的属性全部都是支持的。
于是,我们就可以使用属性选择器,隐藏项目中所有的单复选框以及submit按钮,而使用UI更好的自定义<label>
控件元素替换显示。
input[type='radio'], input[type='checkbox'], input[type='submit'] { position: absolute; clip: rect(0 0 0 0); }
好了,老一代的前端由于IE6不支持属性选择器,可能不太认识;新一代的移动端的前端可能只知道CSS3属性选择器,这里有必要简单科普下,尤其[attr~="val"]
, [attr|="bar"]
这两厮。
[attr~=”val”]
这个表示,属性值中间,有匹配val
的单词,注意这里的名词——“单词”。CSS3中有一个[foo*="bar"]
,表示,属性值中间,有匹配的字符内容,这里这里的名词——“字符”。大家都知道,CSS选择器这东西是老外弄出来的,老外的的母语是English, English的句子都是一个单词+空格+一个单词实现的。这这里的[attr~="val"]
就是用来匹配这些单词的。因此:
<div attr="val"></div> <div attr="text val"></div> <div attr="value"></div> <div attr="val-ue"></div>
表情出卖了一切。笑脸是支持,能识别,抓狂是不能识别。而[attr*="val"]
上面4个都是支持的,因为,每个attr
属性值都有val
字符。
[attr|=”bar”]
这个表示,属性值开头必须是bar
的单词,或者开头是bar-
。CSS3中有一个[foo^="bar"]
,表示属性值以bar
字符开头即可。类似上面的单词和字符的区别,因此有:
<div attr="bar"></div> <div attr="bar-val"></div> <div attr="barval"></div> <div attr="bar val"></div>
同样的,如果是使用[foo^="bar"]
CSS3选择器,则上面4个都是支持的,因为,每个attr
属性值开头都是bar
字符。
其他属性选择器,通俗易懂,我就不详细说明了。
6. first-child伪类选择器
IE7浏览器还支持:first-child
伪类,可以选择第一个子元素。
但是呢,与之对应的:last-child
伪类却不支持,别说IE7浏览器了,IE8浏览器也不支持:last-child
伪类,一直到IE9浏览器才支持。
这个伪类能做的事情可多了,各种列表啊,或者细节带图标的按钮啊,等等,对吧,绝对可以释放更多的页面构建的创造力。
三、新支持的CSS声明或特性
1. position:fixed固定定位
IE6浏览器只支持absolute定位,IE7——开始支持fixed定位,也就是浏览器观点,元素位置不变,纹丝不动,不被滚走。
position:fixed
除了基本的定位功能,还能实现纯CSS控制的全屏遮罩效果,以前的JS动态计算就不用了等等,一些珍藏秘籍,以后有机会再分享。
2. min/max-width/height最大/小宽度高度
可以实现特定宽度区间内的自适应布局。例如:1024像素到1280像素,就可以使用min/max-width/height
控制,不需要JS参与,兼容IE7+浏览器。
min/max-width/height
本质上也属于响应式CSS属性。其作用还是很强的,使用频率也是相当之高,以前棘手的特定范围内的图片尺寸控制也有了新思路。
3. absolute拉伸
absolute
元素,如果没有明显的尺寸限制说,当left/right
和top/bottom
对立方向的属性值同时存在的时候,元素的尺寸会被拉伸,同时,该拉伸的元素内部支持百分比高度,于是我们就能四线高度自适应效果实现。
并再次基础上衍生出内滚动布局等等。
4. png alpha透明
以前IE6浏览器只支持索引透明,IE7浏览器下面,不仅索引透明支持,Alpha通道透明也支持。于是乎,我们的布局更自由,图片资源利用率更好了,因为PNG图片适用于各种场景各种背景,从此告别传统年代图标的毛刺的效果图。
5. border-color:transparent透明
以前IE6浏览器,边框颜色设为transparent
实际上显示的是黑色,但是IE7浏览器支持边框透明色,使用border模拟图形的时候,就少了很多阻碍。
四、JS部分
Ajax请求可以使用XMLHttpRequest了。
等。
五、结语部分
总之,最近做的些不用管IE6,需要兼容IE7的项目,让我发现了很多好玩地东西,页面重构的创造力也比IE6时代要高很多很多。
CSS/HTML技术有时候就是那么回事,看上去挺简单的,但是一旦深入下去,加上自己的创造力和新思维,会发现,尼玛原来做的事情可以有这么多!
好了,已经开始打瞌睡了。已经没有以前结尾可以洋洋洒洒吐槽一大波文字的精气神了。
姿势有限,如果大家发现有错误之处,欢迎纠正,不甚感谢!也欢迎诸位补充可能遗漏的一些IE7的闪光点。
感谢阅读!
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:http://www.zhangxinxu.com/wordpress/?p=4876
(本篇完)
- 理解CSS3 transform中的Matrix(矩阵) (0.292)
- 借助SVG文字尺寸自动缩放甚至突破Chrome 12px限制 (0.292)
- JS之我用单img元素实现了图像resize拉伸效果 (0.292)
- IE7浏览器下CSS属性选择器二三事 (0.279)
- js页面滚动时层智能浮动定位实现(jQuery/MooTools) (0.234)
- CSS3 transform对普通元素的N多渲染影响 (0.234)
- 深入理解CSS中的层叠上下文和层叠顺序 (0.234)
- 杀了个回马枪,还是说说position:sticky吧 (0.234)
- IE6下png背景不透明问题的综合拓展 (0.195)
- 关于gif图片(或png8)杂边锯齿的问题 (0.195)
- Chrome absolute绝对定位display/visibility渲染bug (RANDOM - 0.039)
大神,ie9下用position:fixed来写遮罩层和弹窗,遮罩无效(用的rgba,背景色不起作用),弹窗掉到了页面底部;改用position:absolute来写遮罩和弹窗,弹窗在页面中显示出来了,但是不随页面滚动而滚动,遮罩也无效(用的rgba,背景色不起作用)。求大神指点。
ie9下固定定位失效
好文章!
~=和|=精髓!
感谢分享~~
赞,又学到了
我感觉大神去掉洋洋洒洒的吐槽会更让人感觉容易理解
“要兼容IE7和兼容IE7基本上没多大差别” 这句,有文字错误。哈哈
旭哥你好,这段文字没看懂
“我以前的做法是弹框要加载的时候,使用JS让DOM元素显示。后来鄙人发现,不需要动用JS. 由于默认的DOM元素直接放在下,而弹框装载后到了弹框里面,于是,我使用了一个小小的父子选择器就搞定了整个儿显示问题。”.
不知道是不是你写的太简洁了还是我思维没转过来,可是没理解,为什么增加body > .dom{}就可以在加载的时候显示呢!
@jason 因为在加载的时候,该DOM在弹框内部,已经不是body的相邻子元素,而是相距很远的子元素。此时
body > .dom{}
是没有效果的。旭哥,我的理解是,该DOM元素原本属于body的相邻子元素,然后利用js将该DOM复制到某一个节点中,从而使>选择不起作用,显示该DOM元素?