改造 pixnet 部落格
十二月初小空閒了幾天, 把我的 pixnet 部落格小小的改造了一下. 順便把以前改的和這一次更動的部份記錄一下作為備忘.
整體來說大概完成了以下幾樣工作:
- 把太過老舊 (IE) 又不合標準的 CSS 設定拿掉.
這一項太簡單, 完全不用思考. - 儘量把不是很必要的背景圖去掉, 改以 CSS 完成需要的圖案.
這一項應該也不難, 也的確如此. - 把 box-sizing 設定改為 border-box.
這一項原本以為很簡單 (以前就弄過), 可結果遇到了 2 個區塊有問題, 而且很不好調整. 為了不影響到大家的閱讀及操作, 暫時先不動這 2 個區塊, 將它們的 CSS 附加設定改回 box-sizing:content-box; - 儘可能改成 RWD (響應式網頁設計).
這一項原本以為需要多花一點時間的, 結果進行的非常順利.
本次改造學到 CSS 小技巧
- 如何避免 iPhone 橫放時, slider (滑動功能的區塊) 溢出到左右二側多出來的空白: slider 必須用二層容器包裹. 內層容器固定寬度 (顯示內容才不會跑掉), 外層容器要設定 overflow 時不顯示 (hide). 移動時則外層同時改變寬度並使用 transform:translate() 向左/右移動. 這樣原本要隱藏起來的內容才不會跑到左/右側多出來的空白處.
- 在 pseudo-element 的 content 中, 使用 SVG.
.box-title::before { content: url(data_string); ... }
- 外掛 SVG 檔時: data_string 內容為 SVG 檔案的 URL
- 內嵌 SVG 內容: data_string 內容為:
- 'data:image/svg+xml; utf8,' 再加上 SVG 內容 (要注意單引號, 雙引號搭配的問題).
- 或者 'data:image/svg+xml,' 再加上以 url_encode 編碼的 SVG 內容 (不用擔心單雙引號問題).
- 上述的 SVG 中要使用 color value 時, 要把 "#" 換成 "%23".
- font 簡式設定格式: 必需包含 font-size, font-family.
可以選擇性包含 font-style, font-variant, font-weight, line-height. 同時 font-style, font-variant, font-weight 必需放在 font-size 之前.設定內含 line-height 時, 需符合格式 font-size/line-height.
.publish { font: italic bold 15px/18px "Century gothic", arial, sans-serif ; ... }
- background 簡式設定格式(註二):
background 是多層次的, 圖層和圖層之間用 , 串起來. 寫在後面的圖層會顯示在下層. 所以 background-color 只能設在最後一層 (顯示在最下層). 除此之外, 每層可以選擇性包含 1~n 個後列的屬性 (不必依序):- background-image: 底圖的圖片來源, 設定格式: url(data_string) 或者 src(data_string)
- 外掛圖檔時: data_string 內容為圖檔的 URL
- 內嵌圖檔內容: data_string 內容為 'data:image/png; base64,' 再加上以 base64 編碼的 png 圖檔內容.
- background-origin: 布放啟始位置, 即左上角 (border-box, padding-box, content-box 3 選 1)
- background-clip: 超出時裁剪位置, 即右下角 (border-box, padding-box, content-box 3 選 1)
- background-origin 和 background-clip 的設定值同為 ...-box. 此類設定值可出現 0, 1, 2 次. 只出現 1 次為同時設定二者. 出現 2 次為第 1 個是設定 background-origin, 第 2 個才是設定 background-clip.
- background-position [ /background-size ]: 圖片位置和圖片大小.
圖片大小 background-size 設定不能單獨設定, 需符合格式 background-position/background-size. - background-repeat: 圖板 (可顯示底圖的範圍) 比圖片大時, 如何重覆.
- background-attachment: 底圖與其附著元件的附著方法. 它和捲軸相關, 設定值有三種:
- scroll: 底圖附著在內容元件上, 底圖不依內容的捲動而捲動.
- fixed: 底圖位置固定在 view port 上, 底圖不依內容的捲動而捲動, 其外層捲動也不動.
- local: 底圖附著在內容上, 底圖依內容的捲動而捲動.
當底圖附著的元件有捲軸, 而其外層元件也有捲軸時, 二個捲軸的捲動與底圖的互動關係如下(註一):
- scroll: 底圖附著在內容元件上, 底圖不依內容的捲動而捲動. 所以: 內捲軸捲動, 底圖不動, 內容捲動. 外捲軸捲動, 底圖+內容一起捲動.
- fixed: 底圖位置固定在 view port 上, 底圖不依內容的捲動而捲動. 所以: 內外二個捲軸的捲動都不會捲動底圖. 此處可以看到 scroll 和 fixed 的不同.
- local: 底圖附著在內容上, 底圖依內容的捲動而捲動. 所以: 內捲軸捲動, 底圖+內容一起捲動. 外捲軸捲動, 底圖+內容一起捲動.
- local, scroll: 外捲軸捲動, 底圖+內容一起捲動. 二個設定依多套用在多個 background 的圖層上. 故: 內捲軸捲動時, 第奇數 (1,3,5...) 個底圖套用 local 設定隨內容一起捲動, 第偶數 (2,4,6...) 個底圖套用 scroll 設定不一起捲動.
- scroll, local: 外捲軸捲動, 底圖+內容一起捲動. 二個設定依多套用在多個 background 的圖層上. 故: 內捲軸捲動時, 第奇數 (1,3,5...) 個底圖套用 scroll 設定不一起捲動, 第偶數 (2,4,6...) 個底圖套用 local 設定隨內容一起捲動.
.article-head { background:url(https://pic.pimg.tw/pixnetvisual/49dacf25546bf.png) right top/100% 100% no-repeat; ... }
- background-image: 底圖的圖片來源, 設定格式: url(data_string) 或者 src(data_string)
註一: 此處 background-attachment的設定沒有附著在 background 內的 image 圖層裡, 而是另外以 style 設在其附著的 div 元件上. 故可以有第 4,5 項的變化.
註二: background 語法:
- ?: 表示前項可不出現. (0 or 1)
- #: 表示前項可出現一次以上. (1 or N)
- { min, max }: 表示前項出現次數, 至少 min 次, 至多 max 次.
- |: 用以連接選項, 這些選項只能選一個.
- ||: 用以連接選項, 這些選項至少要選一個. 選項不必依序出現.
- &&: 用以連接選項, 這些選項都必需出現. 選項不必依序出現.
- [, ]: 用以將多個選項結合起來, 並將之視為一體.
background = <bg-layer>#? , <final-bg-layer> <bg-layer> = <bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <visual-box> || <visual-box> <final-bg-layer> = <bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <visual-box> || <visual-box> || <'background-color'> <bg-image> = <image> | none <bg-position> = [ left | center | right | top | bottom | <length-percentage> ] | [ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ] | [ center | [ left | right ] <length-percentage>? ] && [ center | [ top | bottom ] <length-percentage>? ] <bg-size> = [ <length-percentage [0,∞]> | auto ]{1,2} | cover | contain <repeat-style> = repeat-x | repeat-y | [ repeat | space | round | no-repeat ]{1,2} <attachment> = scroll | fixed | local <visual-box> = content-box | padding-box | border-box <background-color> = <color> <image> = <url> | <gradient> <length-percentage> = <length> | <percentage> <url> = <url()> | <src()> <url()> = url( <string> <url-modifier>* ) | <url-token> <src()> = src( <string> <url-modifier>* )
CSS 改造記錄
- 移除舊版 IE 獨有的 CSS 設定. 例如以下幾項:
- _height
- _overflow
- _padding-top
- *font-size
原本的 header image, 以 background-image 放在 #header 位置, 像這樣:

原本放在 #header 當背景的 image.
我調整了背景圖位置等設定, 遮住不必要的部份. 最後變成這個樣子:

調整設定, 遮住 #header 不必要的部份.
#header {
background:url(https://pic.pimg.tw/pixnetvisual/49dacf273c6a6.png) -1px -61px no-repeat;
height:96px;
/* width:900px; */
border:solid 1px #93d1e5;
border-radius: 12px 12px 0 0;
margin-top:5px;
}
- #navigation li
- #navigation li#link-album a
- #navigation li#link-blog a
- #navigation li#link-guestbook a
- #navigation li#link-profile a
並進行相關 CSS 調整, 最後變成這個樣子:

#header 疊上段落文字及 #navigation項目後長這個樣子.
#navigation 相關的 CSS 設定:
#navigation li {
float:left;
padding:0 10px;
margin:0 5px;
line-height:32px;
border:solid #4d7b96 1px;
border-radius:5px;
background-color:rgba(200,250,250,0.5);
}
#navigation a {
color:#2e7eab;
}
#navigation a:hover {
color:#0f4253
}
/* 關掉 相簿, 留言 */
#link-album,
#link-guestbook { display:none }
原本的 footer image, 以 background-image 放在 #footer 位置, 像這樣:

原本放在 #footer 當背景的 image.

疊上 footer 段落文字後, 原本的 #footer 長這個樣子.
改用指定區塊顏色, 邊框, 邊框圓角...等技巧, 最後變成這個樣子:

footer 段落只用 CSS, 疊上段落文字後長這個樣子.
#footer 的 CSS 設定:
#footer {
padding:1em 10px;
height:4.5em;
text-align:center;
background-color:#b3e0ed;
border:solid #93d1e5 1px;
border-top-width:5px;
border-radius:0px 0px 12px 12px;
}

原本 .box-title 的背景圖.

.box-title 段落使用 CSS+SVG, 疊上段落文字後長這個樣子.
更動後的 CSS 設定如下:
.box-title::before {
content: url('data:image/svg+xml; utf8, <svg class="svg-icon" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 40 40" style="vertical-align:middle; enable-background:new 0 0 40 40;" xml:space="preserve"><g><circle cx="20" cy="20" r="18" fill="skyblue" /><polygon points="15,12 15,28 29,20" fill="steelblue" stroke="steelblue" stroke-width="5" stroke-linejoin="round" /></g></svg>');
height:1.5em;
width:1.5em;
margin-right:0.5em;
display: inline-block;
vertical-align:middle;
font-size:0.9em;
}
.box-title {
background: #CDE5EC ;
padding:6px;
color:steelblue; /* #4a8395 */
font-weight:bold;
font-size:1.3em;
}
這一部份原先直接使用 unicode 的 play 符號字元 U+25B6. 後來發現在 windows 平台上 "微軟正黑體" 不包含這個字符 (系統改用 browser 的預設字型), 而 mac OSX 上的黑體字型 "Heiti TC" 卻有這個字符. 結果是二邊的字高字寬及基線不相容, 二邊調不出一致的效果.
最後才改用 SVG 來呈現, 不過使用 SVG 過程也是很坎坷: 最主要的問題是在 pseudo-element (例如: ::before) 的 content 裡填 SVG, 無法使用 color value (#abcdef) 格式, 只能使用 color names(註三), 很是奇怪. 最後是找了 color value 接近的顏色, 改用 color name 才算是搞定.
原先使用 unicode 的 play 符號字元時的設定如下:
.box-title::before {
content:"▶";
height:1em;
width:1em;
padding:2px 1px 5px 6px;
border-radius:50%;
background:#8ed1e8;
color:#4a8395;
margin-right:0.5em;
display: inline-block;
vertical-align:middle;
/* font-family:math; */
font-size:0.9em;
}
.box-title {
background: #CDE5EC;
padding:5px;
color:#4a8395;
font-weight:bold;
font-size:1.3em;
}
註三: 已經查到如何在 SVG (放在 pseudo-element 的 content 裡的) 中使用 color value 了! 要把 "#" 換成 "%23".
例如: fill="#4a8395" 必需轉換成 fill="%234a8395".
更動後的 CSS 設定如下:
.box li {
width:100%;
padding:5px;
line-height:150%;
}
.box li:not(:first-child) { border-top:solid 1px white; }
.box li:not(:last-child) { border-bottom:solid 1px #d1ebf3; }
另外還把 .box 的 CSS 設定關閉, 以避免第一個資訊項目標題前的一個小留白. 但去除了它之後, 有些資訊項的卻要調整一下留白. 另外還有:
- 訪客的大頭貼列表改成用 flex 來表現.
- 修正 QRCode 右側的黑線不見了的問題.
- 調整文章分類列表的項目對齊.
/* .box {
margin:5px 0
} */
/* Fix extra spaces on #links */
#search form { padding: 10px 0; }
#user-info .user-img { padding: 10px 0 0 0; }
.box-text { padding:0; }
/* 調整 Visitors */
#ul-visitors {
display:flex;
flex-flow:row wrap;
}
#ul-visitors li { width: auto; }
/* 調整 QRCode */
#qrcode .qrcode > img { width: 163px }
/* 調整文章分類 */
#category ul > li { margin-left: 1.5em; }
#category .box-text.entry-content > ul > li a { font-weight:bold; color:#369 }
- #spotlight
- #spotlight h5
- #spotlight-text
最後變成這個樣子:

#spotlight 段落只用 CSS, 疊上段落文字後長這個樣子.
更動後的 CSS 設定如下:
#spotlight {
width:calc(100% - 40px);
margin:10px auto;
border: solid 1px #b9e3f0;
border-radius: 7px;
}
#spotlight h5 {
background-color: #d0f1f7;
border:solid 1px white;
border-bottom:none;
border-radius:6px 6px 0 0;
height:31px;
padding-left:10px;
color:#2e7eab;
font-weight:bold;
font-size:14px;
line-height:30px
}
#spotlight-text {
padding:10px;
color:#369;
background-color:#ddfaf8;
border: solid 1px white;
border-top: none;
border-radius: 0 0 6px 6px;
}
我把發表日期及貼文標題都換成用 flex 來展現. 這樣貼文標題太長折到下一行時也會自行對齊, 不會被上鎖或置頂的圖示干擾. 因而可以展現更長的標題, 或者在畫面寬度變小時依然可以有良好的呈現效果.
另外, 發表日期 (月和日) 的字型設定原為 "Century gothic", 卻沒有設定 fallback 字型, 也一併修正了.
最後變成這個樣子:

修改後, 正常寬度時發表日期及貼文標題的外觀

修改後, 寬度太短時發表日期及貼文標題的外觀
更動後的 CSS 設定如下:
.article-head {
background:url(https://pic.pimg.tw/pixnetvisual/49dacf25546bf.png) right top/100% 100% no-repeat;
display:flex;
align-items:center;
color:#235e7f;
}
.publish {
font:bold 15px/18px "Century gothic", arial, sans-serif ;
text-transform:uppercase;
width:72px;
padding:4px 8px 2px;
display:flex;
flex-flow:row wrap;
justify-content:space-between;
flex:0 0 auto;
}
.publish .month,.publish .date {
}
.publish .day, .publish .year {
font-size:10px;
line-height:14px;
letter-spacing:-0.05em;
}
.publish .year {
letter-spacing:-0.02em;
}
.publish .time {
display:none
}
.title h2 {
display: flex;
align-items:center;
padding:4px;
}
.title img {
width:11px;
height:13px;
}
.title a {
font-size:16px;
font-weight:bold;
color:#235e7f;
margin:2px 0 0 5px;
text-shadow: 1px 1px 2px steelblue;
}
這一部份的作法很簡單: 只要在 CSS 的最前面加上以下的一行即可.
* { -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; }
不過有 2 個區塊的外觀會跑掉, 而且不好調整, 所以暫時把它改回用 content-box. 第 1 個區塊是前一篇 (滑鼠移動到畫面左側的灰色大於符號上時出現的那一小區塊), 第 2 個區塊是後一篇, 這二個要額外加一段設定:
#pix_article_switch .title_display { box-sizing:content-box!important; }
原先的 CSS 我以前有調整過一次, 不過那次沒有使用 calc(). 這次把它改成使用 calc() 來設定.
#body-div {
width:900px;
...
}
#content {
width:690px;
...
}
#spotlight {
width:650px;
...
}
#article-area {
width:650px;
...
}
.post-text {
width:470px;
...
}
.reply-text {
width:465px;
...
}
改用 calc() 來設定, 方便簡化下一項 RWD 設定. CSS 變成如下:
#body-div {
/* width:900px; */
...
}
#content {
width:calc(100% - 210px); /* =690px, #links 寬度 210px */
...
}
#spotlight {
width:calc(100% - 40px); /* =650px, 上層為 690px, 二側各留 20px margin */
...
}
#article-area {
width:calc(100% - 40px); /* =650px, 上層為 690px, 二側各留 20px margin */
...
}
.post-text {
width:calc(100% - 120px); /* =520px, 上層為 650px, 右側留 120px 給大頭貼 */
...
}
/* 原為 465px 改用 border-box 變為 520px */
.reply-text {
width:calc(100% - 120px); /* =520px, 上層為 650px, 右側留 120px 給大頭貼. */
...
}
這裡我以 640px 及 900px 為界限把螢幕寬度分為三段. 並在設定 media query 時用了一個小技巧: 我的第一組 media query 用 min-width 設定最大的區段, 接下來的都用 max-width, 而且判斷數值是由大排到小. 這樣在中間的 media query 就可以不必同時寫 max-width 和 min-width, 當我們需要更改邊界的判斷值時只要改一組就好.
不過這樣會使這三組 media query 設定除了第一組是獨立的, 其餘的二組 (或多組, 如果界限不只 2 個) 並不是各自獨立的, 而是會一直疊加上去, 這一點要特別小心.
- 螢幕寬度大於 900px 只會套用第 1 組 "大於 900px" 這一組設定.
- 螢幕寬度介於 640px 至 900px 則只會套用第 2 組 "小於 900px".
- 螢幕寬度小於 640px 至下一組界限值則會先套用第 2 組 "小於 900px" 再套用 第 3 組 "小於 640px", 總共 2 組.
- 如果還有更小的寬度界限值的 (例如: 480px), 則類推: 螢幕寬度小於 480px 則會先套用第 2 組 "小於 900px", 再套用第 3 組 "小於 640px", 再套用 第 3 組 "小於 480px", 總共 3 組.
所以依據第 2, 3 點第 2 組和第 3 組共用的部份要寫在第 2 組設定裡, 而不是第 3 組. (其實你要是覺得麻煩, 就自己加一組用於中間值的完全獨立的設定也是可行的).
還有一點: 由於 iPhone 橫放時, 左右二側會多出一些空白處, 所以右側部落格相關資訊的滑動, 不能只動一層; 必需要內層容器固定寬度 (顯示內容才不會跑掉), 外層容器要設定 overflow 時不顯示, 移動時則外層同時改變寬度並向左移動. 這樣原本要隱藏起來的內容才不會跑到右側多出來的空白處.
新增加 RWD 功能的 CSS 設定如下:
/* view port > 900px */
@media only screen
and (min-width: 900px) {
#body-div { max-width:900px }
#links { margin-right: 0px }
#pix_article_switch {
width:980px !important; margin-left: -510px !important; margin-top:-60px!important; transition: 500ms
}
}
/* view port < 900px */
@media only screen
and (max-width: 900px) {
#content { width:calc(100% - 15px); transition: width 500ms ease-in-out 500ms; }
#sidebar__inner { width:210px }
#links { transform:translate(0); width: 15px; transition: all 500ms ease-in-out 500ms; position:absolute; overflow:hidden }
#links:hover { transform:translate(calc(15px - 210px)); width:210px }
#pix_article_switch {
width:calc(100% + 30px)!important; margin-left:calc(-40px - 50%)!important; margin-top:-60px!important; transition: 500ms
}
}
/* view port < 640px */
@media only screen
and (max-width: 640px) {
#body-div { max-width:640px; transition: 500ms }
#content { width:100%; transition: 500ms }
#links:hover,
#links { transform:translate(0); margin-left:15%; width:70%; position:relative }
}
下圖是 browser 寬度大於 900px, 部落格相關資訊會顯示在貼文的右側.
圖15. 是 browser 寬度介於 640px 和 900px 之間, 原本在貼文右側的部落格相關資訊向右縮到只剩下 15px. 滑鼠停在它上面時則向左滑出來.
圖16. 是 browser 寬度小於 640px, 右側沒有顯示部落格相關資訊的狀況. 圖17. 則是部落格相關資訊顯示於網頁的最下方的狀況.