分类为‘html+css’的一些文章

关于IE透明度失效的问题

近期项目中,发现这个诡异的问题,IE(以下如有特殊说明,指全部IE系列浏览器)下透明滤镜竟然会失效。起因在于,在做一个lightbox时,发现遮罩层透明效果是失效的,在第一时间里,我当然是把问题定位在YUI组建设计的缺陷上,但是当我用IE调试工具看到遮罩层渲染的样式时,我震惊了。如下图:

ss

从渲染的css上看,没有任何问题,百思不得其解,更为让我疑惑的是,在我同事的机器上,遮罩层的透明效果是有的,难道我RP有问题?太不可思议了。

既然问题出了,就要去想办法解决,没有任何回避的理由,经过一番细心的排查,发现我和同事的机器唯一的差别就在于装的操作系统不一样,他的是XP,而我机器上装的是WIN7。这可能就是问题的所在了,但是细想,WIN7不可能不支持filter-alpha-opacity的,这样的结论相信没有人相信,因为我看到我以前写的遮罩层组件是可以正常工作的,所以排除WIN7不支持alpha的可能,那么问题到底出在哪里呢,请看可以正常工作的遮罩层CSS:

ssss

如果你足够细心,我想应该会发现区别在哪儿,没错,就是高度不一样,一个是20000px(失效),一个是1801px(有效)。既然高度会影响filter的渲染,那么肯定会有一个临界点,事实证明,的确如我所料,在WIN7的环境中,如果元素的高度超过4096px,就一定会导致filter-alpha-opacity失效,而这一切在XP环境中并不会发生,真是验证了一句话,在MS的世界里,没有什么不可能!

拓展:在vista系统中,也存在相同的问题,元素高度的临界点为2048px。所谓标准浏览器(firefox、chrome、safari之流)中,opacity渲染的透明度是跨系统的,不会存在失效问题

PS:邪恶的WIN7,邪恶的IE,永远遭我BS.

探讨文本阴影和盒阴影

定义文本阴影格式为text-shadow:length1 lenth2 length3 color,其中length1、length2分别为在水平方向和垂直方向的偏移量,length3是模糊半径,color为颜色值,如果 length1为正值,说明向右偏移,负值则向左偏移;同理,length2为正值,说明向下偏移,负值则向上偏移。具体效果见下图:

探讨文本阴影和盒阴影

可喜的是除了以Trident为渲染引擎的浏览器外(IE内核),其他主流浏览器的较新版本都可以完美支持此属性,通过上图也可以看到此属性的神奇效果也是立竿见影。

相对于文本阴影,盒阴影的定义要复杂那么一点点,由于盒模型还在进一步的发展中,所有要想体验它的魔幻特性,要通过浏览器的私有属性来声明。

  1. Firefox3.5通过私有属性-moz-box-shadow来声明,包括多阴影、inset关键字和传播半径。
  2. Safari/Chrome跟Firefox实现方式类似,通过私有属性-webkit-box-shadow来支持阴影,多阴影从4.0版本开始支持,但是还不支持inset关键字和传播半径。
  3. Opera和微软IE浏览器还没有实现盒子阴影属性,但是在IE浏览器,您可以试着使用他们私有的DropShadow过滤器。

具体格式如下:

  • -moz-box-shadow:length1 length2 length3 length4 color;
  • -webkit-box-shadow:length1 length2 length3 length4 color;

其中length1,length2的特性和text-shadow中的一样,分别表示水平和垂直偏移量,length3表示模糊半径,length4表示传播半径,可以是正值也可以是负值,使用正值表示影子拉长,使用负值表示影子缩短,而这个长度是相对于父元素的大小而言的,在一般情况下,可以不用这个参数。

例如:

  1. #box{
  2.   margin:50px;
  3.   padding:10px;
  4.   border:1px solid #999;
  5.   -moz-box-shadow:2px 2px 6px 0 #999;
  6.   -webkit-box-shadow:2px 2px 6px #999;
  7. }
  8. <div id="box">Safari,Chrome,Mozilla Firefox3.5+下可以看到效果</div>

效果图见上,需要指出的是,盒阴影不占据普通流空间,对于这一点,有兴趣的同学可以测试一下!

脆弱的list-style

list-style实在是在太脆弱了,这是我目前给予它的评价。先看代码:

  1. <style type="text/css">
  2. *{ font-size:18px; margin:0; padding:0;} 
  3. ol{ width:600px; border:1px solid #d5d5d5; margin:100px auto;}
  4. li{ list-style:decimal inside; line-height:26px; width:100%;  /*注意这行代码*/}
  5. </style>
  6. <ol>
  7.     <li>测试list-style特性</li>
  8.     <li>测试list-style特性</li>
  9. </ol>

在Mozilla Firefox,IE8,Safari,Opera,Chrome里呈现的效果见下图(1):

脆弱的list-style脆弱的list-style

这当然是我们预期想要得到的效果,但是再看在IE6、7里呈现出来的效果,见图(2):

记得当时这个问题着实把我困住了,怎么会这样?难道是我电脑出毛病了,还是IE6、7发疯了,最后,经过一番排查,发现竟然是给列表项li设置宽度造成的,把width:100%去掉,一切恢复正常,看来list-style还真的是很脆弱啊,随便一个小动作,都能很轻松的毁掉它所提供给我们的便利的布局能力,到底不是谁都能玩的起的,-.-!

不过由此可以推出,在设置list-style-type:decimal的情况下,如果对列表项(li)设置宽度为auto之外的任意值,则数字序号不会累加,每一个列表项的前面的数字序号都是1,也算是一个意外的收获吧。

额外补充一点,在使用list-sytle的时候,在默认情况下,list-style-position为outside,必须保证列表项有至少30pt的左间距,才能显示出来,但是按照现在大多builder的CSS书写习惯,会把所有标签的间距和填充初始为0,见代码:*{margin:0;padding:0;},这就会让人用着不放心。所以推荐list-style-position:inside,这样就不必为因左间距不够而导致list-style效果无法呈现的问题而担忧了。

在li里插入浮动元素产生的3px的bug

先贴代码:

  1. <ul id="newsList">
  2.   <li><span class="txt"><a href="#">新闻标题</a></span><span class="date">[2009-10-29]</span></li>
  3.   <li><span class="txt"><a href="#">新闻标题</a></span><span class="date">[2009-10-29]</span></li>
  4.   <li><span class="txt"><a href="#">新闻标题</a></span><span class="date">[2009-10-29]</span></li>
  5.   <li><span class="txt"><a href="#">新闻标题</a></span><span class="date">[2009-10-29]</span></li>
  6. </ul>
  7. <style type="text/css">
  8. *{ margin:0; padding:0;}
  9. #newsList{ width:400px; border:1px solid #333; font-size:14px; margin:20px auto;}
  10. #newsList li{ background:gray; line-height:25px; overflow:hidden; color:#fff; width:100%; list-style:none;}
  11. #newsList li .txt{ float:left; width:300px;}
  12. #newsList li .txt a{ color:#fff;}
  13. #newsList li .date{ float:right;}
  14. </style>

firefox、Chrome、Safari、OperaW3C浏览器中没有任何问题,但是在IE系列版本(不包括IE8)中,都会产生一个3pxbug,详见下图:

在li里插入浮动元素产生的3px的bug

目前笔者所知道的解决方法有两种:

  1. li添加float属性,属性值可以是除none外的任意值
  2. li添加vertical-align属性,属性值可以是任意值

从解决问题的实质上,这两种方法并无区别,都是通过添加相应的css属性来激发li的haslayout,但是方法2更适合来解决这个问题,因为一旦给li添加浮动,那么势必要清除之,这是个棘手的问题,虽然有很多方法可以来解决浮动带来的麻烦,但是无形中增加了代码的负重,那是我们不想看到的,所以推荐使用方法2。

再谈DIV的高度自适应

关于div高度的自适应,一直是个让人头疼的问题,整理了一下以前总结的方法,仅表示我也玩过。

再谈DIV的高度自适应

html code:

  1. <div id="container">
  2.   <div id="leftSide">这边的高度自适应右侧的高度</div>
  3.   <div id="rightSide">
  4.     <script type="text/javascript">
  5.       for(i=0;i<10;i++){
  6.         document.write(i + '<br>');
  7.       }
  8.     </script>
  9.   </div>
  10. </div>

可用的方法大概有以下四种:

1,用absolute设置一个足够高的高度,在父级元素中清除溢出的部分,具体的css code如下:

  1. #container{ font-size:14px; width:300px; overflow:hidden; border:3px solid blue; margin:10px auto 0; color:#fff; position:relative;}
  2. #leftSide{ width:100px; float:left; height:200000px; left:0; top:0; position:absolute; background:gray;}
  3. #rightSide{ width:190px; float:right; text-align:center; background:purple;}

其实这种方法并没有真正的实现左右两个div等高,只是用了障眼法,利用containeroverflow:hidden清除了左侧多余的部分,以达到视觉上左右等高的目的,虽然有“白猫黑猫,逮着老鼠就是好猫”的说法,但是笔者并不着重推荐这种方法,因为给父级元素添加relative,会带来很多不必要的麻烦,况且只能是设置absolute的一侧自适应另一侧的高度,并不能让两侧中任一侧去自由去适应另一侧!

2,负外补丁和正内补丁{margin-bottom:-(num)px;padding-bottom:(num)px;}相结合

  1. #container{ font-size:14px; width:300px; overflow:hidden; border:3px solid blue; margin:10px auto 0; color:#fff;}
  2. #leftSide{ width:100px; float:left; background:gray; padding-bottom:9999px; margin-bottom:-9999px;}
  3. #rightSide{ width:190px; float:right; text-align:center; background:purple; padding-bottom:9999px; margin-bottom:-9999px;}

3,利用javascript脚本实现动态设置高度

  1. <script type="text/javascript">
  2.   var left = document.getElementById('leftSide');
  3.   var right = document.getElementById('rightSide');
  4.   if(left.offsetHeight>=right.offsetHeight){
  5.     right.style.height = left.offsetHeight + 'px';
  6.   }else{
  7.     left.style.height = right.offsetHeight + 'px';
  8.   }
  9. </script>

事实上,这种办法真正意义上实现了两侧等高,并且能让两侧中任一侧去自由去适应另一侧,但是其缺点就在于,只有当DOM加载完成后,才有会这样等高的效果,如果网速够快,这个漏洞可以忽略不计。

4,在父级元素中填充背景,css code如下:

  1. #container{ font-size:14px; width:300px; overflow:hidden; border:3px solid blue; margin:10px auto 0; color:#fff; background:url(http://www.men-ideal.com/images/unit1030.jpg) repeat-y; }
  2. #leftSide{ width:100px; float:left; }
  3. #rightSide{ width:190px; float:right; text-align:center}

目前,这种方法是最流行的,同样也是一种“欺骗性”的解决办法,不过除了多使用一张图片之外,都可以堪称完美,这也是笔者极力推荐的!

利用haslayout征服IE6、7

haslayoutWindows Internet Explorer渲染引擎的一个内部组成部分。在IE中,一个元素要么自己对自身的内容进行计算大小和组织,要么依赖于父元素来计算尺寸和组织内容。为了调节这两个不同的概念,渲染引擎采用了hasLayout的属性,属性值可以为truefalse

html元素中,负责组织自身内容的元素将默认有一个布局,主要包含以下元素: body, html, table, tr, th, td, img, hr, input, button, file, select, textarea, fieldset, marquee, frameset, frame, iframe, objects, applets, embed。而div, ul, li, h1~h6之流,在默认情况下,是没能获得layout的,按照微软给出的解释,这是出于对“性能和简洁”和间接的考虑,如果所有元素都默认有布局,会对性能和内存使用上产生有害的影响。

乍一看这段话,似乎不知所云,但是如果说在IE中稀奇古怪的bug和这个所谓的haslayout有关,或许可以吸引你的些许注意力,相信每个有过前端开发经历的人,都会对IE系列浏览器中形形色色的诸多bug搞的焦头烂额。针对这些bug,我们知道一种或者几种不同的解决办法(方法当然是有巧拙之分的),但是对于问题的根源,我们却经常不去深究,也不知道如何去更深一层的认识它!

当网页在IE中有异常表现时,可以尝试激发haslayout来看看是不是问题所在,最常用的方法是给某元素css设定zoom:1或者width/height属性,其次再考虑其他属性,因为使用这两种方法能在不改变现有环境的条件下激发元素的haslayout

事实上大部分的IE显示错误,都可以通过激发元素的haslayout属性来修正,能激发元素haslayout的属性值除zoom和width/height之外还包括:

display: inline-block
float: (left 或 right)
position: absolute
writing-mode: tb-rl

另外本文中提到的IE,只包括IE6和IE7,至于新版本的IE8,不在范围之内,貌似IE8已经解决了haslayout带来的诸多麻烦,具体情况不详!

关于absolute的一些看法

记得刚认识absolute的时候,不知道在哪本参考书上看到过关于关于它的介绍,大概意思是这样的,“一个定义了absolute的子级元素(以下简称child)总离不开一个定义relative的父级元素(以下简称parent),否则child将相对于body定位”,时至今日,我不敢说这样的理解是错误的,但是难免有点歧义或者以偏概全!废话不多说,先看实例图:

关于absolute的一些看法

  1. <div id="container_091028" style="width:300px; height:200px; margin:16px auto; background:gray;">
  2.   <div style="width:100px; height:100px; background:green;"></div>
  3.   <div style="width:100px; height:100px; position:absolute; margin:-10px; background:purple;"></div>
  4. </div>

如果将绿色块对应的html代码(未设置absolute)放在紫色块对应的html代码的下面,按照html由上而下的解析顺序,也就是先解析absolute,后解析普通流元素,那么显示效果将如下:

关于absolute的一些看法

上面的这两种情况中,仅仅用margin来控制child的位置,并没有用left、top。原因很简单,在parent中并未设置relative,而child设置了absolute,如果在此时用left、top来控制child的位置,后果可想而知,会出现child脱离parent元素而去亲近body的现象,这也恰恰印证了参考书中那句话的正确性。之所以说它有歧义,就在于它缺少了一个很重要的前提条件(child设置left、top)!

对于给每个absolute的子级元素都嵌套一个relative的父级元素的情况,我认为是absolute最标准的用法,相信也是最容易理解的,其优点在这里不再赘述!另外友情提示一下,在css2中文手册(苏沈小雨版)中关于position定位的说明有失精准,见下图:

关于absolute的一些看法

其中“此时对象不具有边距”是不准确的,事实上不但有边距,而且其边距还可以和left、top值叠加!关于absolute就说到这些,以上仅仅是我个人的理解,如有不实之处,还望各位大虾不吝雅正!