12個你未必知道的CSS小知識

雖然CSS並不是一種很複雜的技術,但就算你是一個使用CSS多年的高手,仍然會有很多CSS用法/屬性/屬性值你從來沒使用過,甚至從來沒聽說過。

1.CSS的color屬性並非只能用於文本顯示

對於CSS的color屬性,相信所有Web開發人員都使用過。如果你並不是一個特別有經驗的程序員,我相信你未必知道color屬性除了能用在文本顯示,還可以用作其它地方。

你可以先看一下下面的演示:

HTML代碼

<img alt="Example alt text" width="200" height="200">

<ul>
  <li>Example list item</li>
</ul>

<ol>
  <li>Example list item</li>
</ol>

<hr>

CSS代碼

body {
  color: yellow;
  background: #444;
  font-size: 20px;
  font-family: Arial, sans-serif;
  text-align: center;
}

ul {
  border: solid 2px;
  text-align: left;
}

ol {
  text-align: left;
}

hr {
  border-color: inherit;
}

請注意,上面的代碼裏只使用了一個color屬性,就是在body元素上,設置成了yellow。但是,你也看到了,所有這個頁面上的東西都變成了黃色,包括:

  • 無法顯示的圖片的alt文字
  • list元素的邊框
  • 無序list元素前面的小點
  • 有序list元素前面的數字
  • 還有hr元素

有趣的是,這個hr元素,缺省情況下它並不從body上繼承color的屬性,但我使用border-color: inherit強制讓它繼承。這是個很詭異的特徵。

CSS規範裏是這樣說的:

這個屬性聲明瞭元素文本內容的前景色(foreground color)。除此之外,它的值還被用於其它地方間接的引用….比如,其它可以接受顏色值的屬性。

我無法想象出還有什麼地方的屬性能用“前景色”來描述,如果你知道,請在評論裏告訴我。

2.CSS裏的visibility屬性有個collapse屬性值:collapse

對於CSS裏的visibility屬性,相信你用過不下幾百次。大多時候,你會把它的值設置成visible(這是所有頁面元素的缺省值),或者是hidden。後者相當於display: none,但仍然佔用頁面空間。

其實visibility可以有第三種值,就是collapse。當一個元素的visibility屬性被設置成collapse值後,對於一般的元素,它的表現跟hidden是一樣的。但例外的是,如果這個元素是table相關的元素,例如table行,table group,table列,table column group,它的表現卻跟display: none一樣,也就是說,它們佔用的空間也會釋放。

但遺憾的是,各種瀏覽器對collapse值的處理方式不一樣。看一下下面的演示:

HTML代碼

<table cellspacing="0" class="table">
  <tr>
    <th>Fruits</th>
    <th>Vegetables</th>
    <th>Rocks</th>
  </tr>
  <tr>
    <td>Apple</td>
    <td>Celery</td>
    <td>Granite</td>
  </tr>
  <tr>
    <td>Orange</td>
    <td>Cabbage</td>
    <td>Flint</td>
  </tr>
</table>

<p><button>collapse行1</button></p>

<p><button>hide行1</button></p>

<p><button>重置</button></p>

CSS代碼

body {
  text-align: center;
  padding-top: 20px;
  font-family: Arial, sans-serif;
}

table {
  border-collapse: separate;
  border-spacing: 5px;
  border: solid 1px black;
  width: 500px;
  margin: 0 auto;
}

th, td {
  text-align: center;
  border: solid 1px black;
  padding: 10px;
}

.vc {
  visibility: collapse;
}

.vh {
  visibility: hidden;
}

button {
  margin-top: 5px;
}

Javascript代碼

var btns = document.getElementsByTagName('button'),
    rows = document.getElementsByTagName('tr');

btns[0].addEventListener('click', function () {
  rows[1].className = 'vc';
}, false);

btns[1].addEventListener('click', function () {
  rows[1].className = 'vh';
}, false);

btns[2].addEventListener('click', function () {
  rows[1].className = '';
}, false);

演示

CSS-Tricks的Almanac建議說不要使用這個值,因爲瀏覽器的不統一。

據我的觀察:

  • 在谷歌瀏覽器裏,使用collapse值和使用hidden值沒有什麼區別。 (Seethis bug report and comments)
  • 在火狐瀏覽器、Opera和IE11裏,使用collapse值的效果就如它的字面意思:table的行會消失,它的下面一行會補充它的位置。

說實話,估計這個值很少人會使用它,但你要知道確實可以使用這樣的一個值,如果以前不知道它,那麼,現在,在有些罕見的地方,你也許就會變得聰明一點了。

3.CSS的background簡寫方式裏新增了新的屬性值

在CSS2.1裏,background屬性的簡寫方式包含五種屬性值 –background-colorbackground-imagebackground-repeat,background-attachment, and background-position。從CSS3開始,又增加了3個新的屬性值,加起來一共8個。下面是按順序分別代表的意思:

background: [background-color] [background-image] [background-repeat]
            [background-attachment] [background-position] / [ background-size]
            [background-origin] [background-clip];

注意裏面的反斜槓,它更font和border-radius裏簡寫方式使用的反斜槓的用法相似。反斜槓可以在支持這種寫法的瀏覽器裏在position後面接着寫background-size

除此之外,你開可以增加另外兩個描述它的屬性值: background-origin和 background-clip.

它的語法用起來像下面這個樣子:

.example {
  background: aquamarine url(img.png)
              no-repeat
              scroll
              center center / 50%
              content-box content-box;
}

你可以用下面的演示檢測你的瀏覽器是否支持這種寫法:

關於瀏覽器的支持情況,大概所有的現代瀏覽器都支持這些新屬性值,但對於一些非常老舊的瀏覽器(IE6/7/8),最好在代碼裏提供一些萬一不支持的補救機制。

4.CSS的clip屬性只在絕對定位的元素上纔會生效

之前說到了background-clip,你可能會想到clip屬性。它的用法是下面這個樣子:

.example {
    clip: rect(110px, 160px, 170px, 60px);
}

它的作用是按指定的尺寸、規定的大小裁剪元素。很多簡單,但唯一你需要注意的事情是,clip只會在絕對定位的元素上生效。所有,你必須這樣做:

.example {
    position: absolute;
    clip: rect(110px, 160px, 170px, 60px);
}

在下面的演示中,你可以看到當元素在絕對定位/相對定位的切換中表現出來的效果:

但是,你也可以將元素的position設置成position: fixed,因爲,根據css官方規範fixed的元素也屬於‘absolutely positioned’元素。

5.元素豎向的百分比設定是相對於容器的寬度,而不是高度

這是一個很讓人困惑的CSS特徵,我之前也談到過它。我們大家都知道,當按百分比設定一個元素的寬度時,它是相對於父容器的寬度計算的,但是,對於一些表示豎向距離的屬性,例如padding-top,padding-bottom,margin-top,margin-bottom等,當按百分比設定它們時,依據的也是父容器的寬度,而不是高度。

下面是一個實例演示,你可以調整容器的寬度,但你會發現,黃塊塊的padding-bottom的距離也會隨之寬度而變大或變小。

HTML代碼

<div class="wrapper" id="w">
  <div class="box" id="b"></div>
</div>

<input type="range" min="120" max="400" value="400" class="range" id="r">
<output>寬度是: <span id="op">400px</span></output>
<output>黃塊塊的Padding bottom是:<br><span id="op2">10%</span></output>

CSS代碼

body {
  font-family: Arial, sans-serif;
  padding-top: 30px;
  text-align: center;
}

.wrapper {
  width: 400px;
  margin: 0 auto;
  border: solid 1px black;
}

.box {
  width: 100px;
  height: 100px;
  background: gold;
  margin-left: auto;
  margin-right: auto;
  padding-top: 10%;
  padding-bottom: 10%;
  margin-bottom: 5%;
}

.range {
  display: block;
  margin: 20px auto;
}

output {
  text-align: center;
  display: block;
  font-weight: bold;
  padding-bottom: 20px;
}

output span {
  font-weight: normal;
}

實例演示

上面的代碼中,我們對內部子元素聲明瞭3個豎向的距離,都是百分比形式。當移動滑塊時,我們的js代碼只需修改了容器的寬度。但是,這個這三個屬性高度都跟隨着變化,可以看出,它們的百分比計算是基於容器的寬度,而不是高度的。

6.border屬性比你想象的要複雜

我們很多人都用過這樣的寫法:

.example {
  border: solid 1px black;
}

這裏的border屬性的用法實際上是一種簡寫的形式,它分別設置了border-styleborder-width, 和border-color — 用一句代碼表示它們三個。

但不要忘記,border-styleborder-width, 和border-color也都有自己的簡寫形式。所以,border-width可以寫成這樣:

.example {
  border-width: 2px 5px 1px 0;
}

這樣,四個邊的寬度被一次設定。border-color 和 border-style 屬性也可以這樣做。下面的這個實例演示就是用的這種寫法:

HTML代碼

<div class="box">

CSS代碼

body {
  font-family: Arial, sans-serif;
}

.box {
  width: 150px;
  height: 150px;
  margin: 20px auto;
  border-color: peachpuff chartreuse thistle firebrick;
  border-style: solid dashed dotted double;
  border-width: 10px 3px 1px 8px;
}

p {
  text-align: center;
}

 

演示

其實,這些每個屬性還可以繼續細化,被拆分成border-left-style,border-top-widthborder-bottom-color….

但是,你無法用border的簡寫分別對四個邊設置不同的值,只能分開來設置。所以,border是一個簡寫裏還有簡寫的屬性。

7.text-decoration屬性變成了屬性簡寫

我相信有些小知識會讓你大吃一驚。

跟着最新的CSS規範,text-decoration現在的寫法是這樣的:

a {
  text-decoration: overline aqua wavy;
}

text-decoration屬性現在需要用三種屬性值來表示了:text-decoration-linetext-decoration-color, andtext-decoration-style.

但不幸的是,目前只有火狐瀏覽器實現了對這些新屬性的支持。

你可以用火狐瀏覽器試一試下面的演示:

HTML代碼

<a href="#" id="a">IT'S LIKE WATER, PEOPLE

(You should see a wavy line on top. Currently works only in Firefox)

CSS代碼

body {
  padding: 30px;
  text-align: center;
  font-family: Arial, sans-serif;
}

a, a:visited {
  color: blue;
  background: aqua;
  -moz-text-decoration-color: aqua;
  -moz-text-decoration-line: overline;
  -moz-text-decoration-style: wavy;
  text-decoration-color: aqua;
  text-decoration-line: overline;
  text-decoration-style: wavy;
}

演示

在這演示中,我們沒有使用簡寫形式,而是分開描述每個屬性。這是可以更好的保證瀏覽器的向後兼容,使那些目前不支持這種寫法的瀏覽器也不受影響。

8.border-width屬性可以使用預定義常量值

也許對與你來說這並不是一個什麼新鮮信息。除了可以使用標準寬度值(例如5px或1em)外,border-width屬性可以接受預定義的常量值:medium,thin, 和 thick

事實上,如果你不給border-width屬性賦值,那它的缺省值是“medium”。下面的演示就是用了預定義常量值:

HTML代碼

<div class="example">

CSS代碼

body {
  font-family: Arial, sans-serif;
  text-align: center;
}

.example {
  width: 100px;
  height: 100px;
  margin: 20px auto;
  background: aqua;
  border: solid thick red;
}

演示

在瀏覽器使用這些預定義常量值時,CSS規範裏並沒有規定都應該是什麼寬度,但從我的觀察看,它們的值分別是 1px, 3px, 和 5px.

9.爲什麼沒有人使用border-image

之前我曾經寫過一篇關於CSS的border-image屬性的文章。現在幾乎所有的現代瀏覽器都支持這個屬性——除了IE10及以下IE版本。

看起來這是一個非常漂亮的CSS功能,它可以讓你用圖片修飾元素的邊框。下面是一個實例演示,你可以拖拽調整裏面的方塊的大小,看看有什麼邊框圖案的變化。

HTML代碼

<div class="bi">
<p><上面的方塊使用了圖片描邊。在這個方塊的右下角,有一個可以調整這個方塊大小的小三角,點住它,拖動它調整方塊大小,看看有什麼效果。.</strong></p>

<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p>
</div>

CSS代碼

body {
  font-family: Arial, sans-serif;
  text-align: center;
}

.bi {
    border: 45px solid transparent;
    -webkit-border-image: url(http://www.webhek.com/wordpress/wp-content/uploads/2014/07/bg-pawprints-all.jpg) 45 round;
    -moz-border-image: url(http://www.webhek.com/wordpress/wp-content/uploads/2014/07/bg-pawprints-all.jpg) 45 round;
    border-image: url(http://www.webhek.com/wordpress/wp-content/uploads/2014/07/bg-pawprints-all.jpg) 45 round;
    font-family: Arial, Helvetica, sans-serif;
    color: #222;
    width: 500px;
    margin: 30px auto 30px auto;
    overflow: hidden;
    resize: both;
}

演示

但不幸的是,這麼好的一個功能,卻沒有看到多少人使用它,也許是我的眼界太窄。如果你在哪看到過有人使用border-image屬性,或你在真正項目中使用了它,請留言告訴我。

10.你知道table裏的empty-cells屬性嗎?

css裏的empty-cells屬性是所有瀏覽器都支持的,甚至包括IE8,它的用法是下面這個樣子:

table {
  empty-cells: hide;
}

估計你從語義上已經猜出它的作用了。它是爲HTML table服務的。它會告訴瀏覽器,當一個table單元格里沒有東西時,就隱藏它。下面的演示裏,你可以點擊裏面按鈕,它會切換empty-cells的屬性值,看看table的顯示有什麼變化。

HTML代碼

<table cellspacing="0" id="table">
  <tr>
    <th>Fruits</th>
    <th>Vegetables</th>
    <th>Rocks</th>
  </tr>
  <tr>
    <td></td>
    <td>Celery</td>
    <td>Granite</td>
  </tr>
  <tr>
    <td>Orange</td>
    <td></td>
    <td>Flint</td>
  </tr>
</table>
  
<button id="b" data-ec="hide">切換EMPTY-CELLS</button>

CSS代碼

body {
  text-align: center;
  padding-top: 20px;
  font-family: Arial, sans-serif;
}

table {
  border: solid 1px black;
  border-collapse: separate;
  border-spacing: 5px;
  width: 500px;
  margin: 0 auto;
  empty-cells: hide;
  background: lightblue;
}

th, td {
  text-align: center;
  border: solid 1px black;
  padding: 10px;
}

button {
  margin-top: 20px;
}

js代碼

var b = document.getElementById('b'),
    t = document.getElementById('table');

b.onclick = function () {
  if (this.getAttribute('data-ec') === 'hide') {
    t.style.emptyCells = 'show';
    this.setAttribute('data-ec', 'show');
  } else {
    t.style.emptyCells = 'hide';
    this.setAttribute('data-ec', 'hide');
  }
};

演示

在上面的演示中,我爲能讓單元格的邊框顯示出來,在單元格的邊框間添加了空隙。有時候這個屬性不會有任何視覺效果,因爲你必須讓你裏面有可見的東西。

11.font-style的oblique屬性值

對與css的font-style屬性,我估計大家每次見到的都是使用“normal”或 “italic”兩個屬性值。但事實上,你還可以讓它賦值爲“oblique”。請看下面的演示:

HTML代碼

<h1>Oblique Text</h1>

<h1>Italic Text</h1>

CSS代碼

h1 {
  font-weight: normal;
  font-family: Georgia, serif;
  font-style: oblique;
  text-align: center;
  font-size: 50px;
}

h1:nth-child(2) {
  font-style: italic;
}

p {
  font-family: Arial, sans-serif;
  text-align: center;
}

演示

這是什麼意思?爲什麼“oblique”和斜體”italic”的效果是一樣的?

CSS規範中是這樣描述“oblique”的:

“…讓一種字體標識爲斜體(oblique),如果沒有這種格式,就使用italic字體。”

這裏描述所用的“oblique”和“italic”都是傾斜的意思。“oblique”在維基百科裏的解釋就是一種排版術語,就是一種傾斜的文字,但不是斜體。

因爲“oblique”對於font-style來說是一種合法的屬性值,它可和italic進行互換,除非真有一種字體只提供了oblique體而沒有提供斜體。

但我似乎從來沒有聽說過哪種字形提供過oblique字體,也許我錯了。研究發現,一種字庫好像不能同時提供斜體和oblique兩種字體,因爲oblique基本上是一種模仿的斜體,而不是真正的斜體。

所以,如果我沒有猜錯的話,如果一種字庫裏沒有提供斜體字,那當使用CSS的font-style: italic時,瀏覽器實際上是按font-style: oblique顯示的。

12.word-wrap和overflow-wrap是等效的

word-wrap並不是一個很常用的CSS屬性,但在特定的環境中確實非常有用的。我們經常使用的一個例子是讓頁面中顯示一個長url時換行,而不是撐破頁面,下面是一個例子。

HTML代碼

<p class="p" id="p">supercalifragilisticexpialidocious</p>

<button id="b" data-ww="break-word">TOGGLE word-wrap</button>

CSS代碼

body {
  font-family: Arial, sans-serif;
  text-align: center;
}

.p {
  font-size: 24px;
  text-align: center;
  width: 200px;
  margin: 20px auto;
  border: solid 1px black;
  min-height: 60px;
  word-wrap: break-word;
}

button {
  display: block;
  margin: 0 auto;
}

JS代碼

var p = document.getElementById('p'),
    b = document.getElementById('b');

b.onclick = function () {
  if (this.getAttribute('data-ww') === 'break-word') {
    p.style.wordWrap = 'normal';
    this.setAttribute('data-ww', 'normal');
  } else {
    p.style.wordWrap = 'break-word';
    this.setAttribute('data-ww', 'break-word');
  }
};

演示

因爲這個屬性最初是由微軟發明的,所以,所有的瀏覽器都支持這個屬性。

儘管有所有的瀏覽器都支持,但W3C決定要用overflow-wrap替換word-wrap,我想可能是他們認爲word-wrap用詞不當。overflow-wrapword-wrap具有相同的屬性值,但現在,word-wrap被當作overflow-wrap的備選寫法。

雖然已經有不少的瀏覽器支持overflow-wrap這種寫法,但看起來沒必要使用overflow-wrap來讓老的瀏覽器不支持。所有的瀏覽器都會繼續支持word-wrap這種寫法。

這其中有多少是以前不知道的?

不知道你從這篇博客裏學到了多少知識?我希望它對你有些用處。非常有經驗的Web程序員可能會知道其中的大部分,但未必全部。而如果你是新手,想必收益頗豐。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章