> 原文出處:http://www.w3cplus.com/css3/css-secrets/diamond-images.html
## 問題
用菱形裁剪圖片在視覺設計中非常常見,但是這種效果沒辦法直接用CSS完成。實際上,直到最近,這基本上還是不可能做到的。因為,當網頁設計師想要使用這種樣式,他們通常會先用圖像編輯器預裁剪圖像。當然,不用想都知道,這對于應用任何效果都不是一種可維護的方式,如果后面有人想要改變圖像樣式,最后的結果都會變得非常混亂。
當然,現在有一個更好的方法,對吧?實際上,有兩個耶!

*圖注:這是2013年的設計,24ways.org現在用菱形裁剪展示作者的簡介圖片,使用了這里討論的技術*
## 基于變換的解決方案
主要的思想和在[上一節“多邊形”中的第一個解決方案](http://www.w3cplus.com/css3/css-secrets/parallelograms.html)一樣,我們需要用一個`<div>`包裹我們的圖像,然后給它們應用相反的`rotate()`變換:
~~~
<div class="picture">
<img src="adam-catlace.jpg" alt="…" />
</div>
.picture {
width: 400px;
transform: rotate(45deg);
overflow: hidden;
}
.picture > img {
max-width: 100%;
transform: rotate(-45deg);
}
~~~

*圖注:我們的原始圖像,我們將要把它裁剪成菱形*
但是,下圖所示效果這并不是我們想要完成的效果。

*圖注:反方向的`rotate()`不足以完成這個效果(`.picture`div用一個虛線框標出)*
除非我們是要把圖像裁剪成八邊形的形狀,這樣我們現在就可以停下來,然后去做其它的事情。如果是把它裁剪成菱形,我們還有很多工作要做。
主要是`max-width: 100%`的聲明。`100%`對應的是我們的`.picture`容器的邊長。但是,我希望我們的圖片和它的對角線一樣長,而不是它的邊。你可能已經猜到了,沒錯我們要再次使用勾股定理了(如果你需要復習,在[第二章第五節的“Diagonal stripes”一小節中](http://www.w3cplus.com/css3/css-secrets/striped-backgrounds.html)有提到)。定理告訴我們,方形的對角線等于它的邊長乘以`根號(2)≈1.414213562`。因此,把它的`max-width`設置為`根號(2)×100%≈141.4213562%`,約等于`142%`。因為我們不希望它在任何哪種情況下會變小(但稍微大一點是可以接受的,因為我們的圖像是被裁剪的)。
事實上,通過`scale()`變換來放大元素,有以下幾個原因:
* 我們希望圖片的大小保持`100%`,如果CSS變換沒有被支持
* 通過`scale()`變換來放大圖像可以將它從中心放大(除非另外指定了一個不同的`transform-origin`值)。如果是使用`width`屬性來直接進行大小的調整,那么它會從左上角開始放大,這樣我們最后還要使用負邊距來移動它。
綜上所述,我們最后的代碼如下:
~~~
.picture {
width: 400px;
transform: rotate(45deg);
overflow: hidden;
}
.picture > img {
max-width: 100%;
transform: rotate(-45deg) scale(1.42);
}
~~~
下圖所示效果,這就是我們想要的效果。

*圖注:最后裁剪出的圖像*
## 基于`clip-path`的解決方案
前面的解決方案是可行的,但是它基本上是hack。它需要額外的HTML元素,而且也很混亂、復雜,并且脆弱:如果碰巧我們要處理的不是正方形圖像,最終的結果就會非常糟糕:

*圖注:如果處理的是非正方形的圖像,基于變換的解決方案將變得非常糟糕*
實際上,還有一個更好的方法。主要的思想是使用[`clip-path`](http://www.w3cplus.com/blog/tags/431.html)屬性,這是從SVG借來的另一個特性,現在它已經可以被應用于HTML元素了(至少在支持它的瀏覽器中),用好的、可讀性強的語法,不像它的SVG副本,據說用起來容易讓人抓狂。它的主要問題瀏覽器支持有限(我寫這篇文章時)。但是,它的降級非常優雅(沒有裁剪),所以這至少是可考慮的選擇。
你可以在使用像Photoshop這樣的圖形編輯器,因為你對clipping path非常熟悉。Clipping path允許我們把元素裁剪成我們想要的形狀。在這里,我們使用`polygon()`來指定一個菱形,這個形狀允許我們使用一系列用逗號分隔的坐標點來指定任何多邊形形狀。
~~~
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
~~~
就是它了!實現下圖效果,相比之前需要兩行HTML元素和八行隱蔽的CSS代碼,現在只需要簡單的一行。

`clip-path`的令人驚嘆之處不僅于此。這個屬性是可添加動畫的,只要是在兩個相同的形狀函數(這里是`polygon()`)之間,然后另一個形狀有相同數量的坐標點。因此,如果我們想要在鼠標懸停的時候顯示一幅完整的圖像,我們可以這樣寫:
~~~
img {
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
transition: 1s clip-path;
}
img:hover {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
~~~
還有,這個方法可以很好地應用到非正方形的圖像上,如下圖所示。

*圖注:`clip-path`方法可以很好地應用于非正方形圖像中*
啊~~現代CSS的樂趣~~
## 總結
在這一節中通過使用CSS的`transfrom`屬性配合一定的數學計算,實現鉆石圖片效果。但這具有一定的局限性,對于正方形圖片效果較好,但對于非正方形的圖形效果就不太理想。實際上除了`transform`屬性之外,還有更理想的方案,那就是使用`clip-path`對圖片直接進行鉆石形狀的裁剪,從而實現我們需要的效果。