說好的不寫寬度呢?那些 inline-block 區塊的處理方式
389 views,
03-22,
 0
傳說中每個 HTML 標籤都有一個詛咒
這詛咒決定他們的樣貌與能力
如果抵抗這個詛咒,那個他就會 ....
其實是不會怎麼樣啦 = =
今天要談的是屬性 CSS 的標籤 顯示模式 (display)
首先奉上 W3C 說明頁 (不要問英文在寫甚麼~~)
不知道大家有沒有這種疑惑
為什麼 div、p、span、table... 等等的標籤會長的那個樣子?
其實這些都是在規格書當中,官方決定了各個標籤的 display 屬性
並定義各種值的顯示方式
這邊列舉幾個標籤的顯示模式
有興趣的同學可以利用 瀏覽器 的 console panel 來觀察每一個標籤
但是各個標籤的預設 顯示模式 通常不會出現在 css 的觀察面版中
要開啟標籤樣式計算結果中 (那邊也可以看到其他的預設樣式喔)
以 Chrome 為例 ( Firefox請用 Firebug )

上篇中,我們提到了利用 divprofile 資訊的排版案例
其實就是 display:block 的範例

而今天要說的就是懶人...不對 比較高明 的排版方式
在 display:inline-block 不指定寬度的情況下,正確顯示的案例

我們先來看看這個需求
%E5%9C%96%E7%89%8713.png
有沒有覺得這很面熟
其實這是 Facebook 塗鴉牆的回應區塊
留言部分的區塊架構 HTML 可以這樣寫
<div class='comment clearfix'>
    <img class='photo' src='logo.jpg' />
    <textarea class='reply' placeholder='留言...'></textarea>
</div>

首先 img 和 textarea 的 display 預設都是 inline-block
這種 display 顯示方式有幾個特點
  1. 可能預設會有寬高 (通常每個流覽器定義不同),且大小不受上層 DOM 元素影響
  2. 可能預設會有 margin 或 padding
  3. 並排的元素會在單行中顯示
我們先設一些樣式
.comment {
    background:#edeff4;          /* 只是和 fb _背景一樣而已 */
    padding:4px;
    width:398px;                 /* fb 的寬度 */
    outline:0;                   /* 滑鼠 focus 時不要出現框線 (新流覽器才有) */
}
.photo {width:32px; height:32px;}
.reply {
    vertical-align:top;          /* 垂直對齊:上方 */
    border:1px solid #bdc7d8;
    width:355px;
    ...
}
主要這樣就差不多了,詳細請看 http://jsfiddle.net/zQVg8/3/

但 CSS 的故事就是要沒事找事做 ... 不對
是希望能探討各種寫法的優劣,找出能適應各種情況的 CSS 寫法
因此這寫法到底會出甚麼問題呢?

問題就出現在 .comment 和 .reply 樣式中的 寬度 (width) 屬性
網頁架構中,設寬高是件很麻煩的事 (詳情請參照上篇)

首先現實中的 .comment 應該不會設寬
因為外層應該還會有一個容器 wrapper
包住整個塗鴉牆和其他哩哩摳摳的東西 (就像是 facebook 一樣)

目前 .reply 設了寬度 355px
只要 wrapper 的寬度要做變更,你就哭哭了 o(>.<)o

你看看你,CSS 改不完了吧 q(=.=)p

Facebook 也提供 API 給其他網站嵌入塗鴉牆
他怎麼會知道那些嵌入的網站寬度留給他多少
寫死寬度真的是自己挖坑給自己跳

OK 言歸正傳
那我們要怎麼做勒?
在這個案例中
.reply 的寬度一定要佔滿去掉 .photo 寬度後的部分
這代表 .reply 的寬度必須寫成多項式
.reply.width = 100% - .photo.width
(這啥鬼 純 CSS 沒有數學運算這玩意)

咳咳~~
其實這個我們可以以用這兩種方式達成
  1. .comment 設左留白 (padding-left)
  2. .reply 設左邊界 (margin-left)

這兩個方法其實沒甚麼差別
都是要 .comment 將左方的照片空間空出來
因此值設成 .photo 的寬度即可 ( 還要再加上一點空隙 )

因為 .photo 的空間已經留下
.reply 就可以大方的將寬設成 width:100%; 而不會侵占到 .photo 的部分
如此即便 .comment 的寬度改變
.reply 也可以自動適應

但 .photo 該怎麼放到原本位置上呢?
你會說剛特易保留的空間目前已成為死區
誰也沒辦法靠近才對

其實不然
CSS 有一個屬性可以解目前的問題
就是 定位 (position) 啦

把 .comment 的定位方式設成相對後 (relative)
再把 .photo 設絕對定位 (absolute)
並調整位置到當初預留的地方
就完成塗鴉牆的架構
完成的樣式
.comment {
    background:#edeff4;
    padding:4px;
    width:100%;
    outline:0;
    padding-left:40px;
    position:relative;
    min-height:34px;
}
.photo {
    width:32px; height:32px;   
    position:absolute;
    top:4px; left:4px;
}
.reply {
    vertical-align:top;
    resize:none;
    border:1px solid #bdc7d8;
    width:100%;
    height:21px;
    padding:0;
}


這邊成品 http://jsfiddle.net/NqdnL/1/
大家可以試著調整 wrapper 的寬度來看看效果

=============== 我是找不到該說甚麼分隔線 ===============

其實 Facebook 的做法整理後大致上也是這樣
而這種做法其實還是有一點缺陷

因為 .comment 的左留白寬度無法依照 .photo 的大小改變
但現實中照片寬高不會常作調整
畢竟上傳的圖片要做第 2 次放大或縮小很麻煩
尤其又是縮圖 失真問題會很嚴重
也因此這算是可以接受的做法


附註
  1. 上面的例子只是簡單做出塗鴉牆架構並無太多細節部分的處理
  2. Facebook 的 CSS 架構很優秀,雖然可能因為還在開發而顯得語法有點亂,但還是有很多值得參考的地方
留言
訪客如要回應,請先以 Camdemy、facebook 或 google+ 帳號 登入