CSS 技巧汇总

时间:2023-03-09 07:00:01
CSS 技巧汇总

CSS 选择符优先级

!important 声明>内联样式(style)>id 选择符(#id)>类选择符(.class)=伪类选择符(:hover )=属性选择符([attr] )>类型选择符(标签)=伪元素选择符(:first-child)

sticky 定位问题

sticky 定位的元素受父级块级元素影响,其宽度继承的是父级的宽度,另外其只能显示在父级的内容区,当滚动距离超过其父级的高度时,即超过内容区后,其也会相应得被推出可视区域,使用时要注意。
注:sticky 元素的父级元素不能含有 overflow:hidden 和 overflow:auto 属性。

display:inline-block 详解及兼容性方法

2002 年 W3C 推出 CSS2.1 规范时,给 元素的 display 属性增加了 inline-block 值。其作用是 “这个值导致一个元素产生一个块状盒模型(block box),而本身作为单一的内联盒模型(inline box)流动排列(flow)”。即 display 为 inline-block 的元素既可以像块状元素一样定义高度宽度,又可以和内联元素(比如文字)排列在一行。
这个效果在页面设计的时候,很多地方都可以带来便利,最常见的莫过于在对链接进行 “以图换字” 时,既可以像内联元素那样实现一行排列,又可以设置像块状元素那样设置单个链接大小,还可以通过 text-indent 来隐藏文字显示背景图片。
现在对于 inline-block 属性运用的需求也越来越多,可惜依旧只有 Firefox、Safari/Chrome、Opera、IE8+ 支持。但 IE6、7 可以通过触发 hasLayout 属性来模拟(因为 inline-block 会触发 IE 的 hasLayout,从而使内联元素具有类似 inline-block 元素的属性)。Firefox2 有 -moz-inline-box 和 -moz-inline-stack 私有属性,在实际应用中两者都有一些 bug:-moz-inline-box 会存在 text-align(无法水平居中 / 居右,使用 -moz-box-pack:center/end 来修正)、line-height(无法垂直居中,使用 -moz-box-align:center 来修正)等属性无效的问题; 而相对来说 -moz-inline-stack 的表现好些,但也有 bug:如果元素的父级元素具有 display:inline 属性则会使 Firefox 中其包含的链接不可点击,这个需要对元素用 position:relative 来解决,另外 text-align、line-height 等属性无效,目前无法修正)。

兼容实现方法:

display:inline-block;
*display:inline;
zoom:1;/* 这两个属性在 IE6、7 中让块状元素实现 display:inline-block 的效果 */
width:100px;
height:100px;/* 这两个属性为任意非 auto 值 */
text-indent:-999em;/* 现代浏览器中隐藏文字 */
font:0/0 "";
overflow:hidden;/* 这两个属性任选其一配合上文,实现 IE 隐藏文字 */
vertical-align:middle;/* 垂直居中,防止与其他内联元素有比较大的偏离 */

“垂直居中” 之研究

使用一个 100% 高的隐藏元素来辅助,设置 vertical-align 迫使内容区垂直居中,支持图片、多行文字(不固定高度),是目前兼容性最好的方法

<div class="vertical-center">
<div class="text-wrap">
<p>text</p>
<p>text</p>
</div>
</div>
<div class="vertical-center">
<img src="">
</div>
.vertical-center:after {
display: inline-block;
width: 0;
height: 100%;
vertical-align: middle;
content: "";
}
.text-wrap {/* 对于文本需要多包一层 */
display: inline-block;
*display: inline;
*zoom: 1;
width: 100%;
vertical-align: middle;
}

iOS 设备下 iframe 内容无法滚动的问题

很长时间以来,iOS 设备上 Safari 中超出边界的元素将不能滚动,这时候需要用个小技巧来解决这个问题。
html 代码:

<div class="ios-scroll">
<iframe height="100%" width="100%" frameBorder="0"></iframe>
</div>

注:外部包围 iframe 的容器必须有明确的高度值

css 代码:

.ios-scroll {
-webkit-overflow-scrolling:touch;
}

禁止双击时选择页面内容

在做图片滚动时,在双击左右箭头,快速切换图片滚动时,会选择附近区域的文字,感觉不是很好。
针对这个问题可以对相应的元素添加 onselectstart="return false;"(IE、Chrome),另外针对火狐添加 -moz-user-select:none,即代码如下所示:

<div onselectstart="return false;" style="-moz-user-select:none;"></div>

如何去除点击链接或按钮时出现的虚线?

有时候在点击链接或者按钮的时,总有一个虚线框在触发元素上,显得特别刺眼(如用 a 标签 做 Tab 切换),那如何去除这个虚线框呢?

在 IE 中,需要在元素的 html 代码中加入 hidefocus=”true” 属性。即:

<a href="http://www.china.com" hidefocus="true">china</a>

或者在直接给元素定义样式:

position:relative;/* 这是 IE 下的一个 bug,在自身或父级元素定义该样式会导致按钮或链接点击时失去虚线,刚好实现了我们需要的效果,有时无效 */
blr:expression(this.onFocus=this.blur());/* 会反复执行,有严重的效率问题,不推荐使用 */

而在 Firefox 等浏览器中则相对比较容易,直接给元素定义样式 outline:none; 就可以了,另外针对 Firefox 的 input/button 元素要通过私有属性特别处理:

button::-moz-focus-inner,input::-moz-focus-inner {
border-color:transparent;
}

多行文字两端对齐

多行文字尤其是表单的 label 标签,因为字数不一,却要两端排版对齐。

正确的做法是 text-align:justify。但是还需要加上 CSS3 草案的 text-justify:distribute 。
这种做法存在的问题是:除了 IE 之外,尚无浏览器实现 text-justify:distribute。且 IE 必须还加上 text-align-last:justify。
是的,尽管 IE 常为我们所不齿,但是在文字排版和国际化方面,IE 是做的最好的。仅就两端分布对齐这个特例而言,IE 领先了其他浏览器 10 年以上。

这样综合下来,有如下代码:

display:block;
width:5em;
text-align:justify;
text-align:end;/* 对于除了 IE 之外的浏览器用尾对齐覆盖之前的两端对齐方式 */
text-align-last:justify;
text-justify:distribute;

在 IE 和将来正确实现 CSS3-text 模块的浏览器中将两端分布对齐。
在当前除 IE 以外的主流浏览器中将右对齐,作为合理的 fallback。

以图换字的思路及方法

做网页的时候经常会遇到个问题:想让普通文字链接显示个性化的图片,就要对链接使用背景图片,同时让链接里的文字消失,这就需要用到 “以图换字”(Fahrner Image Replacement),就是用图片替换文字表现。

具体方法是位置移动:也就是让内容进行位置移动,移出显示区之外。

<div class="logo"><a href="URL" title="标题">标题内容</a></div>
.logo {大专栏  CSS 技巧汇总br/>    overflow:hidden;
width:100px;
height:100px;
}
.logo a {
display:block;
background:URL;
text-indent:-999em;
}

扩展阅读:Revised Image Replacement 上有更丰富的方法。

用 CSS Border 实现三角形的思路及方法

在盒模型中,上下左右边框交界处出会呈现平滑的斜线。利用这个特点,通过设置不同的上下左右边框宽度或者颜色可以得到小三角,小梯形等。

<div class="triangle"></div>
<div class="triangle2"></div>
overflow:hidden;
width:0;
height:0;
font:0/0 "";
border:10px dashed transparent;/* IE6 下,设置边框的 border-style 为 dashed,即可达到透明的效果 */
border-bottom:10px solid #FF9600;

用 CSS 实现梯形角标时在 Firefox 下出现奇异白线的问题及解决方法

利用上条的思路,可以实现在容器上显示梯形角标:

.box {
position: relative;
width: 300px;
height: 300px;
border: 1px solid #f60;
}
.box::before {
position: absolute;
top: 3px;
left: -27px;
z-index: 1;
width: 60px;
border: 18px solid transparent;
border-bottom-color: #f60;
transform: rotate(-45deg);
content: '';
}

但是在 Firefox 下会在梯形两端各出现一条白线,经确认是 Firefox 对 rotate 支持的 bug。
可以使用如下代码修复:

transform: rotate(-45deg) translate3d(0, 0, 1px);

清除(闭合)浮动

按照 CSS 规范,浮动元素(floats)会被移出文档流,不会影响到块状元素的布局而只会影响内联元素(通常是文本)的排列。因此当其高度超出父级元素时,一般父级元素不会自动伸展以适应内容的高度,从而造成内容溢出影响破坏布局的现象。这种现象叫“浮动溢出”或者“高度塌陷”,如何避免?

解决方法:

zoom:1;/* 针对 IE,触发 hasLayout */
overflow:hidden;/* 针对现代浏览器 */

注:overflow:hidden 用来布局容易出问题,一是很可能造成其内部的浮动层显示不全(致命伤);二是在某些情况下会造成双击空白处全选(没总结出规律,偶尔会出现)。此外,某些时候还会造成性能问题。

这时,现代浏览器可以使用以下方法

.clear:before,
.clear:after {
display: table; /* 不用 block,而是用 table 的原因是用于 :before 可以触发 BFC,从而避免父级与第一个子级元素外边界合并。 */
content: " "; /* 为了避免 Opera 的 bug,否则它会在被清除浮动的元素的顶部和底部产生一个可见空格 */
}
.clear:after {
clear: both;
}

另一种方法就是在父级元素内最后面插入一个额外的标签,并令其清除浮动以撑开父级元素。这种方法优点是兼容性好,缺点是需要额外的无语义的标签

.clear {
overflow:hidden;
clear:both;
height:0;
}

强制文本自动换行和不换行的方法

防止文本撑破页面,强制自动换行:

word-wrap:break-word; /* 可以把长单词强行断句;首先起一个新行来放置长单词,新的行还是放不下这个长单词则会对长单词进行强制断句(IE、Firefox3.5、Chrome、Opera 支持)。CSS3 中已经改名为 overflow-wrap(Chrome、Opera 支持)。 */
word-break:break-all; /* 可以把长单词强行断句;不会把长单词放在一个新行里,当这一行放不下的时候就直接强制断句(IE、Firefox15、Chrome 支持)。 */
table-layout:fixed; /* 针对 table 上使用,但是有副作用,会导致 td 宽度平均分配 */

强制<pre>换行:

pre {
word-wrap:break-word; /* IE6+ */
white-space:pre-wrap; /* CSS3 属性, Firefox、Safari/Chrome、Opera、IE8 */
}

注:强制文本不换行可以使用:white-space:nowrap;

IE 的 “hasLayout” 模式研究

“hasLayout” 模式

hasLayout 是 Windows Internet Explorer 渲染引擎的一个内部组成部分。在 IE 中,一个元素要么自己对自身的内容进行计算尺寸和组织,要么依赖于父元素来计算尺寸和组织内容。为了调节这两个不同的概念,渲染引擎采用了 hasLayout 的属性,属性值可以为 true 或 false。
当一个元素的 hasLayout 属性值为 true 时,我们说这个元素有一个布局(Layout)。当一个元素有一个布局时,它负责对自己和可能的子孙元素进行尺寸计算和定位,而不是依赖于祖先元素来完成这些工作。
IE6、7 上的很多布局方面 Bug 都是和这个属性有关或者可以用这个属性解决的。

触发 “hasLayout”

  • body、img、table、tr、th、td 等元素的 hasLayout 一直为 true。
  • type 为 text、button、file 或 select 的 input 的 hasLayout 一直为 true。
  • 设置 {position:absolute} 的元素的 hasLayout 为 true。
  • 设置 {float:left|right} 的元素的 hasLayout 为 true。
  • 设置 {display:inline-block} 的元素的 hasLayout 为 true。
  • 设置 {height:xx} 或 {width:xx} 的元素必须具备以下两个条件之一,其 hasLayout 才能为 true:
    1. IE8 兼容模式和 IE8 以前的浏览器中,在标准 (strict) 模式下其 display 的值是 block。
    2. 元素在怪异模式(Quirks mode)下。
  • 设置了 {zoom:xx} 的元素在 IE8 的兼容模式或 IE8 之前的浏览器中其 hasLayout 为 true,但在 IE8 的标准模式下则不会触发 hasLayout。
  • 设置了 {writing-mode:tb-rl} 的元素的 hasLayout 为 true。
  • 元素的 contentEditable 的属性值为 true。
  • 在 IE8 标准模式下设置了 {display:block} 的元素的 hasLayout 一直为 true。

防止链接变成一次链接

所谓伪类就是指依赖于浏览器或是用户的状态。对于链接来讲,存在 link,hover,visited,active 四种状态,即四种伪类选择器:a:link(存在链接,但无鼠标动作),a:visited(被点击或访问过),a:hover(鼠标悬停于链接上时的状态),a:active(鼠标点击与释放之间的状态)。
CSS 便是以这几个伪类选择器实现了其为数不多的动态效果。目前最为常用的就是导航条和按钮的动态显示。

在使用链接的伪类选择器时,一般会发现链接点击一次后,会永远显示 visited 状态,没有办法表示 hover、active 了,所以我们要解决这个 “一次性按钮” 问题。
将样式表里面链接四种伪类选择器顺序修改成为:

link
visited
hover
active

顺序这样,后面的优先级大于前面的,就行了。

之所以排在后面的优先级大,是因为浏览器读取 CSS 文件时是自上而下的。
但这并不是充分条件。visited,hover,active 这三种状态不是独立的,它们存在交集。
比方说一个按钮,如果它被点击过,而且你正点击这个按钮,那么这个按钮既是 visited,也是 active,而且因为鼠标悬于按钮之上,所以它也处在 hover 的状态。那么这个时候,你把 CSS 文件中的 visited 置于最后的话,那么 hover 和 active 两种状态的属性都会被 visited 的属性所覆盖而不显示。
同理,active 必须置于 hover 之后才能显示其属性。

要点:

  1. visited 必须置于 hover 和 active 之上;
  2. active 必须置于 hover 之后;
  3. link 的位置无所谓,所以你只需保证 VHA 的顺序即可。

所以我们一般设置 a 的样式时候,都是按照 LVHA(简记为 LoVeHAte)的顺序来进行设置,可以避免出现上述的 bug。