2013年4月7日 星期日

inline-block 來一個殺一個 來兩個殺一對

我們都知道,現今社會險惡  人心不古
人們不再單純
 導致慾望無窮無盡

HTML 標籤也是一樣的 ( 啥鬼 )
不單純的標籤就難以排版


舉個案例
顯示模式為區塊 display:block 的經典標籤 <div>
就是個容易排版的標籤  不論搭配哪種哪種 CSS 樣式
都可以輕鬆表現出來

但加上個固定 margin-top, margin-bottom
就變成了 <p> 或 <pre>
但這 margin 難道就是想要的大小嗎?

如果終究得覆蓋它  那當初為甚麼不用 <div> 還比較好控制
( 以上純粹是個人觀點,當然那些標籤有各自的功用 )

然而有時事情沒這麼單純
最早 CSS 顯示模式 display 能改的值 只有幾種 
( 支援較完整,各瀏覽器差異不大的 )
  1. block 系列:<div> <p> <pre> ...
  2. inline 系列:<a> <span>  ...
  3. table 系列:<table> <tr> <td> ...
  4. none:你看不到我~~
隨著 HTML 的演進
顯示模式 display 的值增加了 inline-block ( 不過舊版 IE 還是有問題 )

因此今天我們就來談談
這種顯示模式的常見案例

案例1. <img>

圖片一直都是一個重要元素
好的圖片可以讓內容更有趣   也可以簡化很多 CSS 的撰寫
總之就是說有多好就有多好的一個標籤


但它排版時卻很尷尬
inline-block 標籤的大小通常跟內容物有關
<img> 的寬高就是圖片大小

但遇到大小切剛好的圖片機會不多
通常多少都需要放大縮小一番

但放大或縮小都會失真  
如果要硬塞進長寬比例不同的容器
又會變得很怪

以萬年 profile 架構來舉例

<div class='profile clearfix'>
 <div class='photo'><img src='photo.jpg' /></div>
 <div class='note'>文字部分</div>
</div>

因為圖片比例剛好所以看起來很正常 (正方形 n x n)

如果運氣不佳  圖片大小沒有這麼適合
已排版的角度來看
我們會希望圖片
  1. 最大:至少不要超過 .photo 的範圍
  2. 太小:不要放大、置中就好
其實怎麼作都會有缺陷  
純 CSS 也沒有甚麼更好的作法  ( 這樣至少排板不會亂掉 )
除非像 Facebook 的大頭貼去記錄你要顯示的部分
但這也是個大工程

說到底問題還是在圖片本身
如果可以改變圖片的來源當然最好
但如果沒辦法的話 
先天不良了  至少後天不要失調其實就夠了

針對此我們的 CSS 該如何撰寫呢?

<style>
.profile {margin:10px;padding:10px; border:1px solid}
   .profile .photo {
      float:left; 
      width:100px; height:100px; 
      margin-right:10px; 
      
      /* 讓圖片置中 這部分可以自由發揮 看怎樣最適合 */
      text-align:center;
      background:#eee; 
      border:1px solid #aaa;
   }
      
      .profile .photo img {
         max-width:100%; max-height:100%; 
         /* 讓圖片最大只有 100% 的大小,不會破壞排版 */
      } 

   .profile .note {overflow:hidden}
</style>


實際測試:http://jsfiddle.net/aXwQy/

這邊用了 4 張大小不同的圖
分別是 50x50  100x100  100x200  200x100因為 max-width:100% 和 max-height:100% 會限制圖片的範圍 ( 但 IE6 並不支援 )
所以它不會超出空間破壞版面
而不夠大的情況圖片也不會被放大失真

=============== 我是 css take a break 分隔線 ===============

案例 2. <input type='file'>

其實 display:inline-block 的標籤絕大部分都是表單元件
例如像  <input> 系列、<select> ...等等
這些有預設樣式的標籤在套用 CSS 時就格外麻煩

但不知道大家有沒有發現
一些網站居然能讓它長的完全不一樣
舉例來說 像 YouTube 的授權選擇


這跟原生的 <select> 差很多吧
而這種效果的作法
都利用額外標籤蓋住原本的位置
YouTube 就是拿 <span> 蓋住 <select> 
點擊時連帶觸發 <select> 的按鈕
果還不錯吧


除了剛剛的例子外
最常見的應該就是上傳按鈕
預設的按鈕很醜
而且每個瀏覽器預設還都長的不同 = =











以 Blogger 的上傳圖片來說吧
這樣子很漂亮吧




為了達到這效果
HTML 可以這樣寫 ( 喜歡吃辣的人可以多一點辣油 ^.^ )
<div class='uploader'>
  <input type='file' />
  <div class='btn'>選擇檔案</div>
</div>
以 Chrome 來看  預設長這樣子 










現在就是見證奇蹟的時刻
在這架構下各個標籤的分工該怎麼作呢?

  1. .uploader:外圍部分,主要任務是要包住上傳按鈕
  2. .btn:看起來像按鈕但實際上是裝飾品,大小需要和 .uploader 一樣大
  3. <input>:真正上傳的按鈕但必須看不到,點擊範圍也要與 .uploader 一樣大

將各自需要的功能拆開後
CSS 的部分就很容易想的到該怎麼寫

<style>
.uploader {
   position:relative;
   height:29px;
   
   display:inline-block;  /* 讓區塊大小由內容物決定 (.uploader .btn) */
   -webkit-user-select: none;
}

.uploader .btn {    /* 負責裝飾的假按鈕 */
   padding:6px 10px 6px 30px; /* 撐開按紐 */
   border:1px solid #aaa; border-radius:1px;
   
   background:url(../icon-uploader.png) no-repeat 10px center #f3f3f3;
   
   font-size:13px; font-weight:bold; color:#333;
   
   position:relative;
   z-index:1;     /* 實際 z 高度需要比 <input> 低 */
}

.uploader input[type='file'] {
   position:absolute;   /* 上下左右填滿整個 .uploader 部分 */
   top:0; bottom:0;   /* 讓你想點不到都難 */
   left:0; right:0;
   
   opacity:0;     /* 透明度設為 0 就看不到了,IE 需用 filter */
   
   z-index:2;     /* 實際 z 高度需要比裝飾的高 */
}
</style>


實際成果:http://jsfiddle.net/mpUht/

其實案例 2 最難的部分應屬 .uploader 的 display:inline-block;
沒有寫寬度的關係,
裝飾用按鈕會自動撐開到與母元素一樣寬
而我又非常忌諱寫寬度,因為哪天換了字還是變更設計後又要重算大小
容易錯又容易漏

寬度實際上就是裝飾用按鈕一樣就好
因此將 .uploader display 設成 inline-block 或是 table
外圍就可以隨著裝飾用按鈕變寬與縮小
大家可以試著拿掉
.uploader 的 display
就更能理解為什麼要這樣作

=============== 我是 css storia 分隔線 ===============

最近在研究 Google blogger 的 theme 寫法
花了不少時間  雖然有些地方覺得不滿意  但之後慢慢調整並且會先修飾過去的文章

因為我並不是美工專門人員
因此介紹 CSS 並不以美觀為主  
而是在模組的架構上和排版觀念
再美觀的 CSS 要有好的架構上才容易維護
否則寫越多只會越痛苦而已

謝謝大家的收看
並敬請期待下期的 css storia: SMACSS 那是甚麼?可以吃嗎?


沒有留言:

張貼留言