使用純CSS來製作魔術方塊電影牆


(圖片取自網路,僅為範例示範用)

使用純CSS來製作魔術方塊一般的電影牆面,讓你的滑鼠點到其中一張相片就能動態的滑動到完整的整張大圖,看起來就像是相片自己知道該到哪裡一般,自動的換相片,在切換的過程中,你的圖片會自動往上下左右四種方向移動,畫面效果十足喔!

Amos一直不斷的思考~到底純CSS可以發揮到什麼樣的程度?許多時候會先做出一個概念性的範例,接著再去搭配程式或者是專案做實務上的應用,這個「CSS魔術方塊電影牆」就是一個概念性的範例,姑且不論這範例在實務上的應用便利性與否,做了再說吧!至於如果要用在專案上面,在文章最後面Amos會再建議實務上更便利的作法喔。

不多說,馬上來看看Amos是怎麼製作這個「CSS電影牆」範例的,首先先準備16個li清單項目,這些項目是為了製作畫面上看到的那15宮格,而最後一個則是為了放置這15宮格所要顯示的圖片所用的,而為了讓CSS控制電影圖片,在最後一個li中則放入15個div,接著每個清單都給他一個class名稱,這樣可以讓CSS寫的簡單一點,就不會因為使用偽類選取氣而把CSS寫的太長,綜合以上的HTML原始碼如下:

<ul class="slider_wall">
	<li tabindex="0" class="box1">B</li>
	<li tabindex="0" class="box2">C</li>
	<li tabindex="0" class="box3">A</li>
	<li tabindex="0" class="box4">B</li>
	<li tabindex="0" class="box5">D</li>
	<li tabindex="0" class="box6">A</li>
	<li tabindex="0" class="box7">D</li>
	<li tabindex="0" class="box8">C</li>
	<li tabindex="0" class="box9">D</li>
	<li tabindex="0" class="box10">B</li>
	<li tabindex="0" class="box11">D</li>
	<li tabindex="0" class="box12">A</li>
	<li tabindex="0" class="box13">D</li>
	<li tabindex="0" class="box14">C</li>
	<li tabindex="0" class="box15">D</li>
	<li tabindex="0" class="picGroup">
    	  <div class="pic1"></div>
    	  <div class="pic2"></div>
    	  <div class="pic3"></div>
    	  <div class="pic4"></div>
    	  <div class="pic5"></div>
    	  <div class="pic6"></div>
    	  <div class="pic7"></div>
    	  <div class="pic8"></div>
    	  <div class="pic9"></div>
    	  <div class="pic10"></div>
    	  <div class="pic11"></div>
    	  <div class="pic12"></div>
    	  <div class="pic13"></div>
    	  <div class="pic14"></div>
    	  <div class="pic15"></div>
      </li>
</ul>

接下來使用CSS把版面編排出來,每一橫列放置5張相片,直欄則放置3張相片,全部加起來就是剛好15張相片,我把整個牆面的寬度設定為1000px,所以每一個格子的大小剛好就是200px*200px,並且為了讓每一個格子能夠被點選到,我先設定 「position:relative; z-index:2; 」然後把最後一個li設定為 「position:absolute; z-index:0;」 這樣就能夠讓li格子浮在最後一個li的上方囉,最後,讓最後一個li裡面的div排列的跟li一模一樣的大小跟位置就大致完成了格式的安排。

.slider_wall{
	margin:50px auto;
	width:1000px;
	height:auto;
	overflow:hidden;
	box-shadow:0 0 100px 0 #FFF;}
.slider_wall li{
	width:200px;
	height:200px;
	float:left;
	position:relative;
	z-index:2;
	font-size:100px;
	line-height:200px;
	text-align:center;
	color:rgba(255,255,255,0);}
.slider_wall .picGroup{
	position:absolute;
	z-index:0;
	width:1000px;
	height:600px;}
.slider_wall .picGroup div{
	float:left;
	width:200px;
	height:200px;
	transition:background-position 1s;}

重點來了~我們要把div裡面的圖片給他設定像是亂數一般的排列,所以使用 (n)來製作,為了方便測試,在還沒放置背景圖片時,我在每個格子都設定了一個背景色彩,這樣就能看到格子到底有沒有跑出亂數地感覺,而就算亂數跑出來了,這亂數結果是否在版面上排列的感覺是平衡而不是不穩的,如果你對 3 的:nth-child(n) 選取器不熟悉的話,Amos建議你先來看一下之前發表的使用CSS3 :nth-child(n) 選取器詳解

.slider_wall .picGroup div:nth-child(3n){
	background-position:0 200px; background-color:#F00;}
.slider_wall .picGroup div:nth-child(3n+1){
	background-position: 400px 0; background-color:#999;}
.slider_wall .picGroup div:nth-child(3n+2){
	background-position: 400px 0; background-color:#990;}
.slider_wall .picGroup div:nth-child(2n+5){
	background-position: 0 200px; background-color:#090;}

接下來請開始製作圖片吧~苦工開始!把每一格的圖片製作好,像是下面這樣

css-photo-wall_slice

看起來似乎很笨的作法,但是概念範例就是如此,先講求不傷身體在講求療效先講求概念再講求實用,對吧!既然圖片都已經製作好了,當然要準備進行最後一個步驟了,那就把圖片設定為背景圖片囉,請在每一個div中給他用CSS設定該位置相對應的圖片,千萬不要設定錯了喔。

.pic1{ background-image:url(images/01_final.png);}
.pic2{ background-image:url(images/02_final.png);}
.pic3{ background-image:url(images/03_final.png);}
.pic4{ background-image:url(images/04_final.png);}
.pic5{ background-image:url(images/05_final.png);}
.pic6{ background-image:url(images/06_final.png);}
.pic7{ background-image:url(images/07_final.png);}
.pic8{ background-image:url(images/08_final.png);}
.pic9{ background-image:url(images/09_final.png);}
.pic10{ background-image:url(images/10_final.png);}
.pic11{ background-image:url(images/11_final.png);}
.pic12{ background-image:url(images/12_final.png);}
.pic13{ background-image:url(images/13_final.png);}
.pic14{ background-image:url(images/14_final.png);}
.pic15{ background-image:url(images/15_final.png);}

喔耶!總算快完成了,最後一個步驟就是要設定當我的上層 li 被點擊到時,最後面的圖片要跑到對應的圖片位置去,在這邊Amos在CSS設定 li 呈現 :focus 狀態時,把最後一個 li 的相關圖片區塊背景做對應的位移,由於我一開始就有設定了div 背景的 CSS transition,所以現在設定背景位置就會自動產生動態的轉換效果囉。

.slider_wall li:nth-child(3n):focus ~ .picGroup div:nth-child(3n+1){background-position:200px 0;}
.slider_wall li:nth-child(3n):focus ~ .picGroup div:nth-child(3n+2){background-position:0 0;}
.slider_wall li:nth-child(3n):focus ~ .picGroup div:nth-child(2n+5){background-position:0 0;}

.slider_wall li:nth-child(3n+1):focus ~ .picGroup div:nth-child(3n){ background-position:0 400px;}
.slider_wall li:nth-child(3n+1):focus ~ .picGroup div:nth-child(3n+2){background-position:600px 0;}
.slider_wall li:nth-child(3n+1):focus ~ .picGroup div:nth-child(2n+5){background-position:0 600px;}

.slider_wall li:nth-child(3n+2):focus ~ .picGroup div:nth-child(3n){ background-position:0 600px;}
.slider_wall li:nth-child(3n+2):focus ~ .picGroup div:nth-child(3n+1){background-position:600px 0;}
.slider_wall li:nth-child(3n+2):focus ~ .picGroup div:nth-child(2n+5){background-position:0 400px;}

.slider_wall li:nth-child(2n+5):focus ~ .picGroup div:nth-child(3n){ background-position:0 0;}
.slider_wall li:nth-child(2n+5):focus ~ .picGroup div:nth-child(3n+1){background-position:0 0;}
.slider_wall li:nth-child(2n+5):focus ~ .picGroup div:nth-child(3n+2){background-position:200px 0;}
.slider_wall li:nth-child(2n+5):focus ~ .picGroup div:nth-child(2n+5){background-position:0 200px;}

現在你只要點到 li ,CSS就會知道你點到的是哪一個 li,並且把對應的div背景移動到正確的位置了,是不是很有趣呢!

CSS電影牆實務面的問題

這個CSS電影牆最大的問題就在於相片的製作,很多人會覺得要製作這些分割圖片很困難的樣子,其實不困難的,只要四個圖層加15個切片就可以做到,但還是需要花費一些人力工時來製作,真是笨死了對吧?!其實,有了這個概念之後,我想如果能搭配程式去處理,其實四張大圖就能做完了,根本不需要進去photoshop製作圖片,利用Javascript自動抓取圖片寬度,並產生對應數量的div塞到目前的.picGroup div中,我相信沒有多大困難度的,並且利用程式自動做圖片的定位與設定CSS overflow就能做出現在我切割的圖片一樣的畫面了,但是概念做完Amos就懶了,有程式高手想來寫看看嗎?歡迎一起研究玩樂喔^^

最後!當然要實際來玩一下囉~馬上來看看實際範例吧  ( 範例請用Firefox或Chrome觀看 )
請注意!因為使用 :focus來模擬滑鼠點擊效果,所以點擊完之後要取消時,請點擊圖片外即可恢復預設狀態喔。