顯示具有 網頁製作心得 標籤的文章。 顯示所有文章
顯示具有 網頁製作心得 標籤的文章。 顯示所有文章
2023-03-10 14:33

TypeScript 強轉型的地雷

用 Visual Studio 撰寫 TypeScript 一整個就很開心開心,只要好好的進行型態宣告,就可享受到跟強型別一樣的 IntelliSense 提示,實在太開心了,然後就大意了,忘記了其實骨子裡還是 JavaScript 這件事。

在取回後端的 json 資料的時候,貪圖方便就直接進行強轉型,哈哈!這裡存在不確定性,我就踩到地雷了!當然如果後端是可靠的,直接強轉型是不會有問題的。

我想都已經進行型別宣告了,難到不能自動轉型嗎?哈哈!在網路上找了很久都沒找到,找到的方式都需要二次宣定去做轉型。

簡單的展示一下這個問題,建立一個 any 的物件 a,然後強轉型成 DataModel 的物件 b,這時候 a 跟 b 其實還是同一個 Instance

interface DataModel {
    id: number;
    status: string;
}

let a: any = { id: '1', status: 3 };

let b: DataModel = a as DataModel;

在存取 property 時都還是 a 的資料型態,這樣在調用該型態的方法時就會出錯。

為了型態的正確必須進行轉換:

let b: DataModel = <DataModel>{
    id: Number(a.id),
    status: String(a.status),
};
2014-01-21 00:23

[Less] 簡單做到背景漸層

對選顏色不擅長,又想在網頁做出 CSS 漸層效果,Less 提供了兩個方便的函數 lighten(加亮顏色)、darken(加深顏色),透過這兩個函數就可以輕鬆產生漸層所需要的色差,然後調整百比值就可以控制漸層的色階。

.toolbar {
    @color: #914;
    @lighten: lighten(@color, 3%);
    @darken: darken(@color, 3%);

    background-color: @color;
    background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@lighten), to(@darken));
    background-image: -webkit-linear-gradient(top, @lighten, @darken);
    background-image: -moz-linear-gradient(top, @lighten, @darken);
    background-image: -ms-linear-gradient(top, @lighten, @darken);
    background-image: -o-linear-gradient(top, @lighten, @darken);
    background-image: linear-gradient(to bottom, @lighten, @darken);
}

上面除了用 linear-gradient 來產生漸層,額外還加上了 background-color 這個保險,讓不支援 CSS3 的 browser 也能有基本的底色。


這樣寫還是有點麻煩,如果包成 mixin 會更方便,如下:
.bg-vertical-gradient(@color, @amount:3%) {
    @lighten: lighten(@color, @amount);
    @darken: darken(@color, @amount);

    background-color: @color;
    background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@lighten), to(@darken));
    background-image: -webkit-linear-gradient(top, @lighten, @darken);
    background-image: -moz-linear-gradient(top, @lighten, @darken);
    background-image: -ms-linear-gradient(top, @lighten, @darken);
    background-image: -o-linear-gradient(top, @lighten, @darken);
    background-image: linear-gradient(to bottom, @lighten, @darken);
}

.toolbar {
    .bg-vertical-gradient(#914);
}

.banner {
    .bg-vertical-gradient(#702, 5%);
}
2010-07-09 22:37

為什麼台灣的網站都這麼的生硬

這個問題一直讓我覺得台灣大多數的網站很落後
就像一個沒有互動感的海報一樣

再來大多的特效都是用 flash 做的
明明很簡單就可以用 CSS 做出來的效果卻沒人用
還有一堆離不開 table 排版的 design
一堆四五年前的技術一直用到現在
然後一直看到國外很多很好的網站 design
不禁感嘆!這就是台灣的網站產業!
就這樣不解的問題一直找不到說服自己的理由


直到 Rogan 的一段話點醒了我
這些華麗的網站大多都是個人網站
大多公司的形象網站不太可能這樣做

就這樣我終於瞭解我一直找不到的答案了
個人網站可以不記時間不記成本
直到完成 designer 心中想要表達的 feel
2009-12-22 14:40

CSS 部屬經驗-圖文列表樣式

樣式



HTML 結構

<ul class="Img2HList ClearIt">
<li class="List Odd">
<div class="Container">
<strong class="Title">
<a><span class="Image"><img src="圖片網址" /></span>標題文字</a>
</strong>

<!--其他相關資訊-->
<p class="Info">描述文字</p>
<div class="Meta">文字</div>
<blockquote>文字</blockquote>
</div>
</li>
<li class="List">
<div class="Container">
<strong class="Title">
<a><span class="Image"><img src="圖片網址" /></span>標題文字</a>
</strong>

<!--其他相關資訊-->
<p class="Info">描述文字</p>
<div class="Meta">文字</div>
<blockquote>文字</blockquote>
</div>
</li>
</ul>



CSS 設定

ul.Img2HList {
margin: 1em 0;
overflow: hidden;
}
ul.Img2HList li.List {
position:relative;
display: block;
float: left;
width: 49%;
margin: 0 0 30px 0;
font-size: 11px;
}
ul.Img2HList .Container {
padding: 0 0 0 79px;
}
ul.Img2HList li.Odd {
clear: left;
}
ul.Img2HList li.Odd .Container{
margin-right: 30px;
}
ul.Img2HList strong.Title {
display: block;
font-size:1.1em;
border-bottom: 1px solid #ccc;
}
ul.Img2HList strong.Title span.Image {
float: left;
margin: 0 0 0 -79px;
cursor: pointer;
}



參考頁面:
Last.fm
Wacanai.com
2009-12-22 09:12

HTML 與 CSS 觀念上的區別

HTML:在定義網頁的 結構語意
  • h1:第一標題
  • h2:第二標題
  • p:段落
  • li:清單條目
  • em:強調
  • strong:更強調
  • blockquote:引言

CSS:在定義網頁的呈現 樣式
  • color:文字顏色
  • text:文字
  • font:字體
  • margin:邊界距離
  • padding:內緣距離
  • background:背景底色
2009-11-24 22:03

今天終於見識到了

今天去一家公司面試
見到一個令我驚訝的事

那就是用 JavaScript 寫 application
整個架構都是 Object-Oriented
光這點還不足已驚訝
架構上幾乎是跟 Java 的 Swing 差不多
所有的 HTML 都是 Object 再控制
整體的顯示效果跟 flash 差不多
真是給他妙的說

不過聽 engineer 說有一個嚴重問題
就是 memory 會用掉 500 Mbyte
engineer 是想利用回收 Object 的方式來減少 memory 的用量
但至於要如何減少 memory 的用量
還真是個大問題

雖然方法很多
但要不影響當前的架構去處理
能用的方法就很有限了
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-03-29 08:09

iGoogle 小工具製作心得

iGoogle 小工具主要是以 XML 為主體,再加上 HTML、CSS 及 JavaScript 所組成的,基本上只要會後面三種語言,要開發 iGoogle 小工具是非常快樂的一件事。

在這裡我只做一些的教學及心得分享,詳細的規範及 API 說明,請察看官方網站 Google 小工具 API 開發人員指南,開發指南裡面寫的很清楚,還有很多的範例可以參考。

心得建議:
  • 開發時建議 XML 的檔名不要太正式,iGoogle 的平台會 cache XML,造成檢視上會出現不一致情況,等到要發佈時再取一個正式的檔名,避免不必要的問題發生。
  • 如果要使用 session 和 cookie 做登入驗證的話,最好使用 <iframe> 去處理,會比較容易達成且安全問題也比較少。
  • 在 ModulePrefs 中的 category 屬性也記得加上去,在官方的開發人員指南中並沒有說明,共有:
    • politics
    • tools
    • funandgames
    • lifestyle
    • finance
    • communication
    • 等...。

  • 多利用[便條簿]做測試可以減少不少時間。
  • 測試時最好在 iGoogle 上另開一個[分頁],免得自己原本常用的小工具被打亂。
  • 在測試的[分頁]中最好加上[開發人員小工具]這個小工具去管理 cache 問題。

小工具範例:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs
title="單位換算"
description="更方便的介面處理單位制度上的換算"
directory_title="單位換算"
author="Jax"
author_email="weskerjax+feed@gmail.com"
thumbnail=
"http://weskerjax.googlepages.com/unit_converter_thumbnail.png"
screenshot=
"http://weskerjax.googlepages.com/unit_converter_screenshot.png"
title_url="http://jax-work-archive.blogspot.com/"
category="tools"
height="300">
<Locale lang="zh-tw" country="TW"/>
<Require feature="tabs"/>
<Require feature="dynamic-height"/>
</ModulePrefs>
<UserPref
name="type"
display_name="預設開啟的頁籤"
default_value="長度"
datatype="enum">
<EnumValue value="長度"/>
<EnumValue value="重量"/>
<EnumValue value="面積"/>
<EnumValue value="體積"/>
</UserPref>
<Content type="html">
<![CDATA[
<style type="text/css">
.JContent table{
margin-top:5px;
width:100%;
}
.JContent th{
background-color:#99CCFF;
padding-top:5px;
}
.JContent label{
text-align:center;
padding:3px;
display:block;
font-size:12px;
}
.JContent label input{
display:block;
text-align:left;
line-height:1.1em;
font-size:11px;
width:95%;
}
</style>
<script type="text/javascript">
var prefs = new _IG_Prefs(__MODULE_ID__);
function set_event__MODULE_ID__(tabId){
var inputs=_gel(tabId).getElementsByTagName('input');
for (var i=0, j=inputs.length; i<j; i++){
el=inputs[i];
/*設定 onkeyup 時處理單位換算*/
el.onkeyup=function(){
this.value=this.value.match(/[0-9]+[\.]?[0-9]*/);
var rate=this.getAttribute('rate');
var value=parseFloat(this.value)/parseFloat(rate);

var table=this;
while(table.tagName!="TABLE"){table=table.parentNode;}

var inputs=table.getElementsByTagName('input');
for (var i=0, j=inputs.length; i<j; i++){
chg=inputs[i];
r=chg.getAttribute('rate');
if(r==rate){continue;}

if(this.value){chg.value=value*parseFloat(r);}
else{chg.value='';}
};
};
/*設定 onfocus 選取所有文字*/
el.onfocus=function(){this.select()};
};
/*讓小工具能夠自行調整大小*/
_IG_AdjustIFrameHeight();
}
function init() {
/*建立頁籤並選定預選頁籤*/
var tabs = new _IG_Tabs(__MODULE_ID__,prefs.getString("type"));
tabs.addTab("長度","J_length",set_event__MODULE_ID__);
tabs.addTab("重量","J_weight",set_event__MODULE_ID__);
tabs.addTab("面積","J_area",set_event__MODULE_ID__);
tabs.addTab("體積","J_volume",set_event__MODULE_ID__);
}
_IG_RegisterOnloadHandler(init);/*載入時呼叫的事件處理常式*/
</script>
<div class="JContent" id="J_length">
<table border="1" cellspacing="0" cellpadding="0">
<tr>
<td><label>公尺<input rate="1" type="text" /></label></td>
<td><label>公里<input rate="0.001" type="text" /></label></td>
<td><label>海里<input rate="0.00053996" type="text" /></label></td>
<tr>
<td><label>英吋<input rate="39.370" type="text" /></label></td>
<td><label>英呎<input rate="3.2808" type="text" /></label></td>
<td><label>英碼<input rate="1.0936" type="text" /></label></td>
</tr>
<td><label>台尺<input rate="3.3003" type="text" /></label></td>
<td><label>市里<input rate="2e-3" type="text" /></label></td>
<td><label>市引<input rate="0.03" type="text" /></label></td>
</tr>
</table>
</div>
<div class="JContent" id="J_weight">
<table border="1" cellspacing="0" cellpadding="0">
<tr>
<td><label>公斤<input rate="1" type="text" /></label></td>
<td><label>公克<input rate="1e+3" type="text" /></label></td>
<td><label>公噸<input rate="1e-3" type="text" /></label></td>
</tr>
<tr>
<td><label>英磅<input rate="2.2046" type="text" /></label></td>
<td><label>盎司<input rate="35.273" type="text" /></label></td>
<td><label>英噸<input rate="9.8421e-4" type="text" /></label></td>
</tr>
<tr>
<td><label>美噸<input rate="0.0011023" type="text" /></label></td>
<td><label>格令<input rate="15432" type="text" /></label></td>
<td><label>克拉<input rate="5000" type="text" /></label></td>
</tr>
<tr>
<td><label>台斤<input rate="1.6667" type="text" /></label></td>
<td><label>台兩<input rate="26.667" type="text" /></label></td>
<td><label>市擔<input rate="0.02" type="text" /></label></td>
</tr>
</table>
</div>
<div class="JContent" id="J_area">
<table border="1" cellspacing="0" cellpadding="0">
<tr>
<td><label>公畝<input rate="100.00" type="text" /></label></td>
<td><label>公頃<input rate="1" type="text" /></label></td>
<td><label>平方公里<input rate="0.01" type="text" /></label></td>
</tr>
<tr>
<td><label>平方英寸<input rate="155e+5" type="text" /></label></td>
<td><label>平方英尺<input rate="107640" type="text" /></label></td>
<td><label>平方碼<input rate="11960" type="text" /></label></td>
</tr>
<tr>
<td><label>英畝<input rate="2.4711" type="text" /></label></td>
<td><label>平方英里<input rate="0.003861" type="text" /></label></td>
<td> </td>
</tr>
</table>
</div>
<div class="JContent" id="J_volume">
<table border="1" cellspacing="0" cellpadding="0">
<tr>
<td><label>立方公尺<input rate="1" type="text" /></label></td>
<td><label>公升<input rate="1e+3" type="text" /></label></td>
<td><label>毫升<input rate="1e+6" type="text" /></label></td>
</tr>
<tr>
<td><label>英國加侖<input rate="219.97" type="text" /></label></td>
<td><label>液體加侖<input rate="264.17" type="text" /></label></td>
<td><label>固體加侖<input rate="227.02" type="text" /></label></td>
</tr>
</table>
</div>
]]>
</Content>
</Module>


範例預覽:

範例原始檔:unit_converter.xml


第一個開發的小工具:
2008-12-05 00:52

Wacanai 改版了

花了一個多月的時間
終於將新的版面上線了
除了版面上的改變外
這次也降低 JavaScript 的使用量
根據之前的經驗
太多的 JavaScript 只會讓瀏覽器當掉
在 CSS 樣式上的規劃也改善不少
當然也為了介面與功能配置上做了一些修改
雖然整體來說還不是很完整
但希望新的版面能讓使用者感覺更親切

我們的網站:www.wacanai.com
2008-09-09 08:12

CSS 三欄排版

  1. float 排版
    CSS 三欄排版
    這是在 Table 排版之後最常見的排版方式,利用 float 與 clear 的屬性設定去達成的分欄排版。

    最近發現除了利用 clear 屬性的空 Tag 以外還有其他的方式可以達到這個效果,在最外層的 div 上加入以下屬性也可以達到相同的效果:
    * html #demo_1{
        height: 1%;
    }
    #demo_1:after {
        content: ".";
        display: block;
        height: 0;
        clear: both;
        visibility: hidden;
    }
    #demo_1 {
        zoom: 1;
    }
    


  2. table 排版
    CSS 三欄排版
    這是最早期排版方式,雖然有種種的缺點,但還是有很多網站使用,除了利用原有的 Table Tag,也可以使用其他 Tag 設定 display 屬性去達到 Table 排版的效果,雖然在寬度的定義上的彈性,但還是建議保持只有一個欄位的彈性寬度,過多的彈性寬度只會造成意想不到的後果。


  3. margin and float 排版
    CSS 三欄排版
    這是利用中欄的 margin 屬性空出側欄位空間,再利用 float 及負邊界方式去達成的三欄排版,因為 float 屬性不會對整體高度做出貢獻,如果需要側欄的高度影響,必須上擁有 clear 屬性的 Tag 或利用第一個範例的方法,由於中欄沒有 float 屬性所以不能在內容使用 clear 屬性。


  4. margin and position排版
    CSS 三欄排版
    這是利用中欄的 margin 屬性空出側欄位空間,再利用 position 的定位方式去達成的三欄排版,因為 position 屬性不像 float 屬性,可以利用 clear 屬性做出高度的貢獻,所以側欄的高度不可以大於主欄,要不然會造成顯示重疊。


  5. padding and float排版
    CSS 三欄排版
    這是結合 (float 排版) 及 (margin and float 排版) 的排版方式,主要是解決 (margin and float 排版) 的主欄中不可以使用 clear 屬性的問題,CSS 的差別只在於利用外匡的 padding 屬性去做預留空間的設定。


優劣差異:
floattablemargin
float
margin
position
padding
float
靈活性
親和力
HTML 結構簡單複雜簡單簡單簡單
寬度彈性noyesyesyesyes
允許彈性的欄位數0all111
overflow 容錯
瀏覽器的解析差異
欄位的高度影響allallall1all


展示頁面(Demo Page)
2008-08-20 17:27

Ajax 模組架構的應用

Ajax 模組架構的應用
一樣的就之前所提到的問題(Ajax 開發所產生的問題),這是另一種以模組架構為基礎的方法,模組開發的好處我就不多作說明了,主要的行為模式是:
  1. 在請求 Page 時就先將 Module Include,讓頁面再第一次讀取時就可以完整呈現。
  2. 在頁面需要執行局部置換時,再利用 Ajax 向 Module 請求局部內容。

這樣做既不會失去模組開發的優點,也不會有 Ajax 造成的過長等待,讓 Ajax 主要應用在局部置換及 UI 處理。
2008-08-19 16:17

利用屏壁來延長頁面的呈現時間

就之前提到的問題(Ajax 開發所產生的問題),這很可能連帶出現以下問題:
  1. 瀏覽者再頁面尚未完整呈現時誤觸連結,造成錯誤操作。
  2. 功能的初始未完成,瀏覽者再使用上出現無法動作的錯愕情形。


這些問題可以用一個有效的方法去延長瀏覽者的等待時間,在一開始的頁面裡預設疊上一個遮蓋整個頁面的等待圖示,在 JavaScript 處理完後再移出屏壁,一個很好的範例就是 Gmail,再一個主要的頁面呈現前,置入一個等待圖示去避免一些可能的不當操作。

順帶一提,Gmail 利用 ifreme 去做出局部置換的效果,這樣做的好處是,瀏覽器會自動去紀錄上下頁,在 Ajax 的應用上瀏覽紀錄這件事是必須額外處理的。
2008-08-18 17:27

利用 Ajax 減少 Server 運算量

在 Ajax 還沒有出現時 JavaScript 本身就可以執行許多計算方面的程式了,像之前的文章『HTML 比較(diff)』、『數獨(sudoku)解題』、『線性代數-計算機』等都是利用 JavaScript 去達成的計算程式,象 Yahoo 也有在 Login 時利用 JavaScript 做 md5 的計算,其實瀏覽器還是可以做一些有規模的運算。

利用 Ajax 減少 Server 運算量

主要是將運算資料取回,計算結果明細後,再跟 Server 取得剩餘的詳細資料,這個架構可以讓 Server 原本的運算量轉由瀏覽器執行,是一個以空間換時間的作法,當然有一好沒兩好,沒錯這樣的方法明顯會發生之前所說的問題(Ajax 開發所產生的問題),是否要用這個方法就看各位的考量了。

其中特別要注意的一些事項:
  1. 再資訊必須是即時性,且運算量大於一定時間以上時,考慮這種架構才會有意義,要不然只會浪費頻寬。
  2. 資料安全性問題,必須定義哪些瀏覽者可以取得計算資料,要不然會造成嚴重的漏洞。
  3. 資料量的大小,太大的資料可能會造成瀏覽器整個當掉,再規劃時要特別注意最大上限,至於詳細的範圍要依瀏覽者的設備而定。
2008-08-14 16:17

Ajax 開發所產生的問題

wacanai 的開發中發現了一個問題,就是在頁面載入後又開始執行多個 Ajax 請求,這會發生什麼現象呢?頁面一開始會空空的,然後資訊開始慢慢的呈現出來,這樣的現象會造成兩種問題:
  1. Server 在同一時間會有來自單一位址的大量請求
  2. 使用者的等待時間變長

第一個問題會使 Server 連接端口的負荷增加,雖然在流量上並沒有很大的區別,但卻會考驗 Server 的硬體資源。

第二個問題是使用者必須等待所有 Ajax 回應後才能看到完整的頁面資訊,而且會因為使用者的頻寬成倍數關係。

Ajax 開發所產生的問題

我們會發生這樣的問題,來自於過度使用以 Ajax 為基礎的模組架構,將一些沒必要利用 Ajax 處理的應用,也使用 Ajax 來呈現,Ajax 原先是用來優化呈現上的局部置換,及增加與使用者互動的應用介面,主要是用來避免重新載入已有的資訊,並讓頁面可以有更好的介面輔助,但在習慣 Ajax 的架構時,不知不覺就習慣利用這個架構去作模組的規劃。

所以再利用 Ajax 作開發時,必須考慮到 Ajax 主要的應用目的,不然在過度不當採用這個應用時,會造成更多的問題存在。
2007-11-19 22:20

初次使用 mootools.js

最近為了網頁的動態效果,從 prototype.js 改使用 mootools.js 做開發依據,雖然 mootools.js 很好用,也比 prototype.js 更簡化了許多,但也應為更簡化讓我有點不太能上手。

為了避免相容性的問題,使用其中很多的函數作媒介,雖然是個很好用的 Framework ,但效率確不如 prototype.js 快,當然不可能要馬兒跑得快,又要馬兒不吃草,mootools.js 在背後為了處理相容性的問題用掉不少時間,也簡化開發時架構的複雜度。

由於對 mootools.js 還不是熟,可能需要花點時間去瞭解,但還是一句老話:

要知道積木有那些,才能蓋出偉大的城堡