2009-10-21 17:40

[PHP] 利用 strtr() 做變數(樣版)置換

以前在處理 SQL 指令時都是使用 sprintf() 去做變數替換,但常常會遇到兩個問題。
  1. 先後順序固定缺乏彈性,尤其在多語處理的時候
  2. 變數定義缺乏語意(%s),在維護時難以閱讀不直覺


後來找到 strtr() 這個函數可以執行多個字串的取代,在變數替換時蠻方便的,可以有效的克服上面的問題,當然根據使用上的需求最好還是包裝一下。
<?php
$query = "
    INSERT INTO `system_uesr` 
    SET `Id` = :id,
        `Name` = :name
";

$bind = array(
    ":id" => "'1'", 
    ":name" => "'jax'"
);


echo strtr($query, $bind);
// 結果:
//    INSERT INTO `system_uesr` 
//    SET `Id` = '1',
//        `Name` = 'jax' 



參考文章:
PHP: strtr - Manual
PHP strtr() 函数
strtr --- 轉換某些字元
2009-07-24 05:05

CSS 部屬經驗-表格樣式

為了 IE6 的相容這裡我不會用太新穎的選擇器,希望有一天 IE6 的使用群可以消失,這樣在排版時可以不去顧慮 IE6 的問題。

主旨:
  1. 如何規劃一個表格樣式
  2. HTML 結構
  3. CSS 設定

如何規劃一個表格樣式
網路上其實已經有很多表格樣式可以參考了,但除了表格樣式外,欄位的屬性很重要。

利用 class 去作欄位定義,讓每一欄都有不一樣的成員名稱,就算有些欄位根本不需要定義樣式,但建議最好還是保留名稱的設定,也許有一天會去用到,這樣之後要作欄位調整時才不用大興土木,去為每個樣版裡改表格樣式。

在 HTML 的規劃上最好用一個 <div></div> 包起來,再處理邊界上的設定時才不會因為瀏覽器的差異造成問題。



這裡我用到 hover 的方式去處理滑鼠滑過的效果,對於 IE6 的處理方式請看利用 JavaScript 讓 IE6 支援 CSS 2.0 hover 的方法

對於表格在之前有遇過一個奇怪的狀況,就是在設有 white-space:nowrap; 的欄位上寬度只能用 % 去定義,在 (IE6) white-space 在表格中怪問題 有說明。




HTML 結構

<div class="TableList">
<table cellspacing="0" cellpadding="0">
<tr>
<th class="Image">Picture</th>
<th class="Title">Title</th>
<th class="Date">Date</th>
</tr>

<tr class="Odd">
<td class="Image"><!--圖片--></td>
<td class="Title"><!--文字--></td>
<td class="Date"><!--日期--></td>
</tr>
<tr class="Even">
<td class="Image"><!--圖片--></td>
<td class="Title"><!--文字--></td>
<td class="Date"><!--日期--></td>
</tr>
<tr class="Odd">
<td class="Image"><!--圖片--></td>
<td class="Title"><!--文字--></td>
<td class="Date"><!--日期--></td>
</tr>
<tr class="Even">
<td class="Image"><!--圖片--></td>
<td class="Title"><!--文字--></td>
<td class="Date"><!--日期--></td>
</tr>
</table>
</div>



CSS 設定

/*=( 表格列表樣式 )=*/
.TableList {
text-align:center;
padding:1em;
}
.TableList table{
border-collapse:collapse;
font-size:0.9em;
width:100%;
text-align:center;
}


/*欄位間距*/
.TableList th,
.TableList td{
padding:.5em;
}


/*標題列*/
.TableList th{
border:1px solid #fff;
white-space:nowrap;
background:#328aa4 url(tr_bg1.gif) repeat-x;
color:#fff;
}
.TableList th a{color:#fff;}


/*單列底線樣式*/
.TableList tr{
border-bottom:1px solid #fff;
_behavior: url(ie_hover.htc);/*IE6 hover*/
}
/*奇數列底色樣式*/
.TableList tr.Odd {background:#FFF;}
/*偶數列底色樣式*/
.TableList tr.Even {background:#eee;}


/*hover 樣式*/
.TableList tr.hover td,
.TableList tr:hover td{
background:#e5f1f4;
}


/*=( 欄位設定 )=*/
/*圖片*/
.TableList th.Image,
.TableList td.Image{
width:50px;
}
.TableList td.Image img{
width:30px;
height:30px;
}

/*標題*/
.TableList td.Title{
text-align:left;
font-size:14px;
}

/*日期*/
.TableList td.Date{
width:3%;
white-space:nowrap;
}



參考頁面:
Last.fm
Wacanai.com
2009-07-24 04:00

CSS 部屬經驗-表單樣式

為了 IE6 的相容這裡我不會用太新穎的選擇器,希望有一天 IE6 的使用群可以消失,這樣在排版時可以不去顧慮 IE6 的問題。

主旨:
  1. 為什麼要用<table>作表單排版
  2. HTML 結構
  3. CSS 設定


為什麼要用<table>作表單排版
下面是利用 <table> 的排版方式,雖在排版上我非常不喜歡用 <table>,但在使用很多種排版方式及撰寫 JavaScript 的使用者介面輔助後,將 <table> 用在表單上可以有比較好的樣式結構,而且在 JavaScript 的輔助開發上對版面的操作也比較不會造成跑版問題。

如果有過在表單上做過很複雜的 JavaScript 介面輔助後,你一定會瞭解我在說什麼。


實際頁面 Wacanai.com


HTML 結構

<table class="FormList" border="0" cellspacing="0" cellpadding="0">
<tr class="NotNull">
<th><label for="name">欄位名稱</label></th>
<td>
<input class="Full" type="text" value="" id="name" name="name"/>
<small class="Explain">欄位說明</small>
<div class="Error">錯誤訊息</div>
</td>
</tr>

<tr class="NotNull">
<th><label for="email">欄位名稱</label></th>
<td>
<input class="Full" type="text" value="" id="name" name="name"/>
<span class="Error">錯誤訊息</span>
<small class="Explain">欄位說明</small>
</td>
</tr>
</table>

在結構我設置了 JavaScript 會用到的訊息樣式,在下面的 CSS 設定中會先將這些訊息隱藏,之後在用 JavaScript 去處理顯示的動作,這樣的好處是 JavaScript 可以用很簡單的方法做到很複雜的介面輔助。


CSS 設定

/*讓表格寬度撐開*/
table.FormList{
width:100%;
}

/*基本的間距設定*/
table.FormList th,
table.FormList td{
padding:6px 10px 6px 4px;
}
table.FormList th{
width:25%;
text-align: right;
vertical-align:top;
font-weight:normal;
white-space:nowrap;
}

/* 必填項樣式 */
table.FormList tr.NotNull th label{
padding-left:20px;
}

/* 欄位寬度設定 */
table.FormList .Full{
width:95%;
}
table.FormList .Verify{
width:40px;
}

/*標示說明文的樣式*/
table.FormList small.Explain {
display: block;
font-size: 0.8em;
margin: 0 0 5px 0;
padding: 1px 3px;
}


/*錯誤訊息的樣式*/
table.FormList div.Error ,
table.FormList span.Error {
color: #f00;
display: none;
font-size: 1.2em;
font-weight: bold;
}
/*警示訊息的樣式*/
table.FormList div.Warning ,
table.FormList span.Warning {
color: #00f;
display: none;
font-size: 1.2em;
font-weight: bold;
}

/*套用在整列的錯誤樣式*/
table.FormList tr.Error label{
color: #F00;
}
table.FormList tr.Error textarea,
table.FormList tr.Error select,
table.FormList tr.Error input{
border: 1px solid #F00;
}



參考頁面:
Last.fm
Wacanai.com
2009-07-24 02:43

CSS 部屬經驗-按鈕樣式

為了 IE6 的相容這裡我不會用太新穎的選擇器,希望有一天 IE6 的使用群可以消失,這樣在排版時可以不去顧慮 IE6 的問題。

主旨:
  1. 用 <a></a> 元素來作按鈕
  2. 利用原有樣式建立延伸樣式
  3. 套用在 <input> 的樣式

用 <a></a> 元素來作按鈕
連結元素的優點救是 IE6 有支援 hover 偽類,所以使用連結元素用在按鈕上可以用簡單的 CSS 做出點選效果。

當然在 CSS2 上面還有很多樣式上的選擇器,對於美工或使用者介面都有很方便的 CSS 設定,不用為了一點小東西去寫 JavaScript,總結就是 IE6 趕快消失吧!


利用原有樣式建立延伸樣式



在上面的三個按鈕樣式中可以發現只有底圖上的差異,所以在樣式上的規劃可以利用延伸複寫的方式去建立樣式。

首先我先看看這三個按鈕的 HTML 結構:

<a class="Button">
<span>按鈕文字</span>
</a>

<a class="Button AddButton">
<span>按鈕文字</span>
</a>

<a class="Button TagButton">
<span>按鈕文字</span>
</a>

可以發現在 class 上的套用上是有層級的,藉由樣式複寫的方式去延伸原有的樣式。


現在我們來看看 CSS 的設定:

/* 按鈕樣式 */
a.Button {
/*針對 Mozilla 系列瀏覽器的 inline-block*/
display: -moz-inline-box;

display: inline-block;
color: #fff;
text-decoration: none;
text-align: right;
vertical-align: middle;
cursor: pointer;
text-shadow: #163551 0 -1px 1px;

height: 23px;
background: #163551 url(button_right.png) no-repeat right top;
font-size: 11px;
padding: 0 3px 0 0;
}
a.Button strong,
a.Button span{
/*針對 Mozilla 系列瀏覽器的 inline-block*/
display: -moz-inline-box;

display: inline-block;
vertical-align: top;

height: 19px;
padding: 2px 5px 2px 8px;
background: #16517d url(button_left.png) no-repeat left top;
line-height: 19px;
}


/* 按鈕的 hover 效果設定,變換底圖定位及文字顏色 */
a.Button:hover,
a.Button:hover {
background-position: right bottom;
color: #fff;
text-decoration: none;
}
a.Button:hover span,
a.Button:hover strong {
background-position: left bottom;
color: #fff;
text-decoration: none;
}


/* 延伸的按鈕樣式 (AddButton)*/
a.AddButton span,
a.AddButton strong {
padding-left:25px;
color:#003366;
background: #2a2a2a url(button_add_left.png) no-repeat left top;
}

基礎樣式所用到的圖片:

botton_left.png


button_right.png


接著是延伸樣式所用到的圖片:

button_add_left.png


如果還要延伸其他樣式只要改改顏色或圖示就可以了。
上面的 CSS 有用到在 CSS 部屬經驗-樣式命名 提到的限制樣式對象的使用方式,這樣的選擇器設定只能讓樣式套用在連結元素上,這樣的好處是讓樣式與元素有一個關連性。

套用在 <input/> 的樣式
已經為連結元素建立美美的按鈕了,總不能讓 <input/> 這樣醜醜的見人吧!
CSS 樣式:

input.Button {
background: #9b9b9b url(button_bg.png) left top repeat-x;
border: 1px solid #ccc;
border-color: #999 #858585 #666 #858585;
color: #fff;
cursor: pointer;
cursor:hand;
font-size: 11px;
font-weight: bold;
line-height: 16px;
padding: 0 4px;
text-decoration: none;
text-shadow: #9b9b9b 0 -1px 1px;
vertical-align: middle;
vertical-align: baseline;

/*各瀏覽器的圓角設定,這裡捨棄對 IE6 的支援*/
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
-khtml-border-radius: 2px;
}

所用到的圖片:

button_bg.png


這裡我也使用相同的 class 名稱,但在限制樣式對象的作用下這兩個樣式是不會互相衝突的。

參考頁面:
Last.fm
Wacanai.com
2009-07-23 23:46

CSS 部屬經驗-容器樣式

為了 IE6 的相容這裡我不會用太新穎的選擇器,希望有一天 IE6 的使用群可以消失,這樣在排版時可以不去顧慮 IE6 的問題。

主旨:
  1. 容器樣式的概念
  2. 容器樣式定義
  3. 建構一個容器


容器樣式的概念


我們會發現在上面這三個樣式裡外匡是一樣的,除了顏色上的差異,而這些外匡的 HTML 結構也是一樣的,我稱這樣的外匡為容器,主要只提供樣式的框架,不處理資料的呈現。

將容器與樣式分離的好處是版面的呈現變靈活了,讓排版就像堆積木一樣,而樣式的重複利用性也會變高,樣式定義的複雜度也會降低。


上面這張圖就是容器的架構概念,在容器裡放入資料呈現的樣式,再將容器加入頁面排版裡。


容器樣式定義
如果已經瞭解什麼是容器了,接著要開始為容器的定義作一些規範:
  1. 不處理資料的呈現,例如資料的列表。
  2. 容器裡不可以在包含容器,過份的疊加套用會讓整體的架構變的很亂,所以讓容器間的關係保持平等是比較好的。
  3. 不要設定太多會繼承的樣式屬性,這樣會讓包在裡面的樣式要額外設定一些複寫的樣式屬性,例如字體顏色、對齊方式等。
  4. 不要為容器設定高度與寬度的屬性,高度應該要隨著內容而變動,寬度則應該適應版面的大小,這樣才不容易出現跑版的異常問題。


建構一個容器
針對上面的樣式來建構容器的 HTML,當然不一定照著一樣的方式建立,依照容器樣式的需求去建立就行了。

這裡會發現我之前在 CSS 部屬經驗-樣式命名 中提到的樣式成員名稱,這裡我還為每個樣式成員都加上了 "Area" 這個名稱前綴,以避免選擇意外套用到不該套用的元素上。

<div class="AreaBox_1">
<h3 class="AreaTitle">標題文字</h3>
<div class="AreaContent">
<!--
其他樣式元素...
-->
</div>
<div class="AreaBottom">
<div></div>
</div>
</div>


這裡可以看出 CSS 的選擇器的層級最多只有三層,如果樣式的層級太深以後要接手的人會很難進入狀況,層級太淺樣式又會很沒結構感,造成樣式很零散,兩層到三層之間的選擇器設定是比較好維護的。

關於容器的樣式設定我並沒有設定的很完整,請自由發揮吧!

.AreaBox_1 {
/*右上角的底圖*/
background:transparent url(../images/xxxx.gif) no-repeat right top;
/*上下的間距*/
margin:5px auto;
}
.AreaBox_1 .AreaTitle{
/*左上角的底圖*/
background:transparent url(../images/xxxx.gif) no-repeat left top;
/*標題設定*/
color:#585E1A;
font-size:16px;
padding:10px 0 14px 35px;
}
.AreaBox_1 .AreaContent{
/*中間的底圖*/
background:transparent url(../images/xxxx.gif) repeat-y left center;
padding:0 12px;
}
.AreaBox_1 .AreaBottom{
/*右下角的底圖*/
background:transparent url(../images/xxxx.gif) repeat-y right top;
}
.AreaBox_1 .AreaBottom div{
/*左下角的底圖*/
background:transparent url(../images/xxxx.gif) repeat-y left top;
height:10px;
}



參考頁面:
Last.fm
Wacanai.com
2009-07-22 20:42

CSS 部屬經驗-頁面排版

為了 IE6 的相容這裡我不會用太新穎的選擇器,希望有一天 IE6 的使用群可以消失,這樣在排版時可以不去顧慮 IE6 的問題。

主旨:
  1. 分析版面架構
  2. 定義所需要的排版區域
  3. 為需要設置寬度的區域增加外匡
  4. 建立 HTML 架構
  5. CSS 排版設定


如何分析版面架構
一般網頁架構都差不多,大部分都是由幾個主要的區域建構而成,只是在部屬上有些差異而已。

在下面幾個網頁排版中我們可以發現,除了兩欄或三籃的差異外,基本上整體的頁面部屬是一樣的。

天然の屋


TERRANOVA 朵拉大地


Jamboree購物網


定義所需要的排版區域
根據上面第一個版型,可以分析出以下的版面架構,要部屬這樣的架構其實不難,依照一個很直覺的方式去部屬就可以了。



為需要設置寬度的區域增加外匡
在之前的文章 寬度(width)不要與其他屬性同時設定[CSS] 有提到寬度定義的手則,所以接著要為具有寬度定義的區域增加外匡,然後在外匡上設定寬度的大小。

不管是排版或是樣式定義,除非必要的樣式,其餘請不要設置高度與寬度的樣式屬性,頁面是會隨著內容而變動的,愈是增加不必要的限制,頁面愈容易跑版。




建立 HTML 架構
依照上面的架構圖我們可以建立以下的 HTML 架構。
這裡也是一個很簡單架設觀念,只要把每個方匡都想成是 <div></div>,然後在從外到內一層一層去部屬就可以了。

對於 ContentWrapper 的結構位置建議放置在分欄區域(MainWrapper)的起始位置,這樣可以讓內容資訊有較好的 SEO。

<div id="ContainerWrapper" class="ClearIt">
<div id="Container">

<div id="Header" class="ClearIt">
Header
</div>

<div id="Banner">
Banner
</div>

<div id="MainWrapper" class="ClearIt">
<div id="ContentWrapper">
<div id="Content">
Content
</div>
</div>

<div id="SidebarWrapper">
<div id="Sidebar">
Sidebar
</div>
</div>
</div>

</div>
</div>

<div id="FooterWrapper">
<div id="Footer">
Footer
</div>
</div>



CSS 排版設定
要設定 CSS 也是一個簡單的事情,先將所有的 id 取出至 CSS 檔建出以下的文件。

/* 整體頁面區域 */
#ContainerWrapper{}
#Container{}

/* 頁首區域 */
#Header{}

/* 橫幅區域 */
#Banner{}

/* 主要內容區域 */
#MainWrapper{}

/* 主欄區域 */
#ContentWrapper{}
#Content{}

/* 側欄 區域 */
#SidebarWrapper{}
#Sidebar{}

/* 頁尾 區域 */
#FooterWrapper{}
#Footer{}


接著為版型作位置及寬度上的配置,在設定時會很難察覺區域的情況,建議為每個區域都先設置不同的底色加以區別。

/*先定義代替 <div style="display:block;"></div> 的樣式設定*/
.ClearIt:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
/*針對 IE6 的方式*/
.ClearIt {
_zoom: 1;
}


/* 整體頁面區域 */
#ContainerWrapper{
/* 設定寬度並整體置中 */
width:982px;
margin:0 auto;
}
#Container{}


/* 頁首區域 */
#Header{}


/* 橫幅區域 */
#Banner{}


/* 主要內容區域 */
#MainWrapper{}


/* 主欄區域 */
#ContentWrapper{
/* 設定主欄的位置 */
float:right;

/* 設定內容溢出的處理方式,這裡建議設置隱藏,避免非預期的跑版出現。 */
overflow:hidden;

/* 設定主欄的寬度 */
width:736px;
}
#Content{
/* 這裡建議設定最小高度,當內容高度不足時,不置於讓版面變得很奇怪。 */
min-height:500px;

/*IE6 最小高的設定*/
_height:500px;
_overflow:visible;
}


/* 側欄 區域 */
#SidebarWrapper{
/* 設定側欄的位置 */
float:left;

/* 設定內容溢出的處理方式,這裡建議設置隱藏,避免非預期的跑版出現。 */
overflow:hidden;

/* 設定側欄的寬度 */
width:202px;
}
#Sidebar{}


/* 頁尾 區域 */
#FooterWrapper{
/* 設定寬度並整體置中 */
width:982px;
margin:0 auto;
}
#Footer{}


剩下的就是去調整其他區域的底圖、padding 及 margin,那些網頁美工的設定。


參考頁面:
Last.fm
Wacanai.com
2009-07-20 20:41

CSS 部屬經驗-樣式命名

為了 IE6 的相容這裡我不會用太新穎的選擇器,希望有一天 IE6 的使用群可以消失,這樣在排版時可以不去顧慮 IE6 的問題。

主旨:
  1. 定義樣式的命名方式,區分 CSS 與 JavaScript 的使用
  2. id , class , tag 等選擇器得使用時機

為什麼要定義定義樣式的命名方式?
CSS 在選擇器的宣告上十分自由,但為了讓其他人也能順利的閱讀自己寫的樣式,定義一個有規則的命名方式,可以減少不必要的誤會跟問題。

這裡我自己作了命名的定義:
  • CSS 命名規則:
    1. 單字開頭大寫,不使用底線(_)間隔,除最後的數字代號前(.Style_1)
    2. 除特定版型架構命名,不得以 id 方式宣告樣式,唯一樣式才可以使用 id 命名(#SidebarWrapperLeft)
    3. 所有可沿用的樣式都才採用 class 方式宣告

  • JS 命名規則:
    1. 所有單字小寫,使用底線(_)間隔(action_bt)
    2. 與 JS 元素獲取相關命名均不可帶有樣式屬性
雖然有 CSS , JS 及 HTML 樣版可以將程式與美工的部分分離,但在 HTML 架構的規劃上仍需要協同開發,為區分樣式與 JS 的程式操作最好是將命名規則分開。


如何去決定選擇器的使用?
  • id 選擇器:
    在 id 的使用上我分成[頁面排版]及[例外樣式]
    1. 頁面排版:排版是不會重複的樣式定義,而且必須擁有不容易被複寫的特性,使用 id 選擇器去定義樣式是在好不過的。

      常用的命名詞彙:
      Outer外匡
      Container容器
      Status狀態
      Header頁首
      Banner頁面橫幅
      Nav/Navigation領航
      Navbar領航列
      Content/Container內容
      Main頁面主體
      Sidebar側欄
      Footer頁尾
      Wrapper具有寬度定義的區塊


    2. 例外樣式:在頁面中具有特別需要美工修飾的樣式時,利用 id 選擇器去強制複寫原有樣式。
      這是為了特殊樣式而保留的彈性,但不建議經常性的使用,這樣就違反 CSS 樣式統一的特性,未來維護時只會帶來更多的不便。


  • class 選擇器 :
    在 class 的使用上我分成[樣式定義]及[元素類型]
    1. 樣式定義:樣式規劃上最主要的用途定義,去規劃所有可重複利用的樣式,例如:按鈕、列表、表單等區塊性的樣式。

      常用的命名詞彙:
      Summary摘要
      Widget工具集
      Toolbar工具列
      Navbar領航列
      Menu項目單
      TextLink文字連結列
      PageLink頁面連結列
      Tab頁籤
      Search搜尋
      Form表單
      List列表
      TextList文字列表
      ImageList圖片列表
      Button按鈕
      AreaBox區塊匡
      InfoBox資訊匡
      PageInfo頁面資訊
      DropMenu下拉選單
      heading/Title標題
      SecDivide區段標題


    2. 樣式成員名稱:在樣式編排時為了補 tag 不足(樣式成員),利用 class 去定義內層的原件樣式。
      命名時可依據區塊在樣式裡的角色去取名。

      常用的命名詞彙:
      Title標題
      Date日期
      Buttons按鈕群
      Bottom底部
      Logo網站標誌
      Image圖片
      Action動作
      status狀態
      Content內容
      Even偶數
      Odd奇數
      First最前的
      List最後的


  • tag (HTML 標籤)選擇器:
    在 tag 的使用上我分成[限制樣式對象]及[樣式成員]
    1. 限制樣式對象:在樣式選擇器前加入可使用此樣式的tag(HTML 標籤),去區別可使用此樣式的元素。

    2. 樣式成員:在樣式定義結構中所使用到的 tag,別太依賴 tag 去定義樣式,在 HTML 中的 tag 是有限的,適時的用 class 去區別樣式成員。
      判斷方式,當子節點超過 2 層或同類 tag 超過一個以上時,最好使用樣式成員名稱的 class 命名去增加樣式成員


在這些定義中可能還是很模糊,在之後的文章中會介紹如何去規劃樣式,在那些範例中會使用到上面的規則,應該會比較容易瞭解。

參考頁面:
Last.fm
Wacanai.com
2009-07-19 04:00

(轉載) CSS hack 區分IE6,IE7,IE8,Firefox,Opera,Google,PCManCB

今天 Cara 問了一個我沒用過的 CSS hack 方法
最後在 英創達網路有限公司 找到詳細的差異比較表
這個表清楚的各版本 CSS 的區分方法


IE6IE7IE8FirefoxOperaGooglePCManCB範例
>YYYNNNY.type {
>color: #F00;
}
.YYNNNNY.type {
.color: #F00;
}
*YYNNNNY.type {
*color: #F00;
}
_YNNNNNN.type {
_color: #F00;
}
!importantNYYYYYY.type {
color: #F00 !important;
}
*+YYNNNNY.type {
*+color: #F00;
}