1
HTML5 Form Validation のカスタマイズ
Note: This article is written in Japanese for HTML5 Advent Calendar 2012. If you’d like to read this article in English, you can read the original post I wrote on November 21 for Nokia Code Blog.
Thank you.
師走です。早いものですね。さて、HTML5 Advent Calendar 2012 2日目を書かせてもらうことになりました。元々この記事は Nokia Code Blog の一記事として私が11月21日に書いたものなのですが、クロスポスト可ということなので、せっかくですので今回はその日本語版として記事にしてみました。というわけで、HTML5 Form Validation CSS3、ウェブフォント、JavaScript を使ったカスタマイズ方法について書いています。
以前までならばユーザの入力フィールドの検証(バリデーション)は JavaScript もしくはサーバサイドで専用のロジックを書かねばばらなかったわけですが、HTML5 からは仕様に組み込まれるようになったために非常に簡単にできるようになりました。実装されるようになってかれこれ1年ほど経っているのですがその間に Internet Explorer など、サポートされるブラウザも増えてきました。まずこのバリデーションカスタム化についてのこの記事を読む前に、必須課目として HTML5 から新たに加わったフォームのインプット要素についての理解が必要ですので、基本をここやここなどでおさらいをしておいてください。さらにバリデーションについての全般的な内容については、白石 俊平さんの書かれた、「HTML5で仕様になった入力値チェック+便利な3Tips」が非常にわかりやすいと思います。
フォームバリデーションの基本
例えば必須入力のフィールドが空の状態で送信された場合の検証。これは HTML5 では <input> に required 属性を加えるだけで、下のように非常に簡単に書くことができます。
<form>
<input type="text" required>
<input type="submit" value="Submit">
</form>
単純なデモを書いたので試してみてください。仕様がサポートされているブラウザ上でフィールドを空のまま送信するとエラーメッセージが表示、もしくはエラーを示す UI が現れます。
下のスクリーンショットは、左がデスクトップ IE10 (英語版)のデフォルト、右が IE10 モバイルの UI です。

IE10 モバイル版では、エラーメッセージの吹き出しが表示されず、空フィールドの枠が赤く表示されただけの仕様になっているのですが、そのフィールドが focus された状態でバーチャルキーボードが現れるので、ユーザビリティは損なわれていないようです。
このメッセージや吹き出しの UI は、ブラウザや環境言語によって異なります。下の画像は日本語版の Chrome から。

それでは、これから 1) パターンマッチング、2) CSS3 でのビジュアル効果、3) カスタムのエラーメッセージ設定、を使ってフルカスタマイズしてみましょう。
パターンマッチング
pattern 属性では要素の値を正規表現と照合することができます。下は、6~12 文字のアルファベットと数字、句読点を含む文字セットを一致させる正規表現を使った例です。
<form>
<input id="username" type="text" pattern="[a-zA-Z0-9_-]{6,12}" autofocus required>
<input id="submit" type="submit" value="create">
</form>
pattern 属性のデモコードを試してみてください。わざと無効になるように3桁の数字などを入力てみましょう。
CSS3 ユーザインターフェイスセレクタ
CSS ではいくつかの、UI 要素状態を表す UI セレクタ(疑似クラスや疑似要素)があります。その例として、:valid, invalid, in-range, out-of-range, required, optional, read-only, read-write が挙げられます。
これを使って、入力の有効/無効状態を赤と緑の色別に表示するようにしてみましょう。
:valid {
color: green;
}
:invalid {
color: red;
}
入力値が正しい形式に一致する時は緑、値が無効なときは入力値が赤で表示されます。サンプルで試してみましょう。
ウェブフォントアイコンを使う
この上さらに、チェックマークのついたアイコンを表示させてみましょう。せっかくですので画像アイコンを使わず CSS3 をフル活用してウェブフォントを使った応用をやってみましょう。
![]()
ここでまた必須課目です!ここではちょっと変わった活用をしてみたいので、CSS3 ウェブフォントについてよくわからないという方は必ず先におさらいしておいてください。
さて、フリーのウェブフォントはいろいろあるのですが、ここでは IcoMoon が配布している Iconic という絵フォントを使います。このサイトの、IcoMoon App を使うとなんと自分の必要なものだけを選べ、それを軽量パッケージ化してくれるのです。
一旦フォントセットを作ったら、それを読み込む @font-face 規則を使って CSS を作成します。
@font-face {
font-family: 'iconic';
src: url('webfonts/iconic.eot');
src: url('webfonts/iconic.eot?#iefix') format('embedded-opentype'),
url('webfonts/iconic.svg#iconic') format('svg'),
url('webfonts/iconic.woff') format('woff'),
url('webfonts/iconic.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
疑似クラス :valid と、疑似要素 ::after (もしくは ::before)を一緒に使うと入力値が無効であった時にエレメントの後ろ(または前に)コンテントを表示するとこができます。では後ろにフォントアイコンを表示させてみましょう。
input 要素の後にアイコンを表示するのだから、input 要素と疑似クラスと疑似要素を全部一気につなげて input:valid::after としたいところですが、ちょっと待って!この input 要素 DOM にはドキュメントツリーコンテントがないので疑似要素をくっつけることができないのです。なのでここでは適当な要素、 span を使うことにします。
<input id="username" type="text" pattern="[a-zA-Z0-9_-]{6,12}" autofocus required>
<span class="icon-validation" data-icon=""></span>
data-* 属性を使って絵フォント値を指定してみましょう。ここでは span 中に data-icon というカスタム属性を作成して IcoMoon で作成した特定のフォントのキャラクター値を指定しています。
:valid + .icon-validation::before {
content: attr(data-icon);
color: green;
}
簡単な CSS ではありますがこの数行にはいろいろな意味を含んでいます。まず、+ は Adjacent Sibling (隣接)セレクタ、直後に後続する要素のみ指定しています。そして疑似要素のコンテントは定義されたカスタムデータ属性を使っています。この HTML5 カスタムデータ属性 (data-*) は、DOM ステートを保ったまま少量のプライベートデータを保存できるのです。確かに絵フォントキャラクターを ::before 疑似要素の、content プロパティで直接使うことはできるのですが、ルー大柴みたいに言ってみれば、この data-* を使ってデータバインディグする方法がセマンティックでベターだと思うぜ☆
カスタムエラーの設定
エラーメッセージの表示をカスタマイズするには大まかに2つの方法があります。
では簡単な方法から。これは title 属性を使ったインラインテキストを表示させる方法で、ここで指定されたテキストはデフォルトのエラーメッセージに下に表示されます。したの画像は Opera 12 です。

<input id="username" type="text" pattern="[a-zA-Z0-9_-]{6,12}" autofocus required
title="must be alphanumeric in 6-12 chars">
このデモで自分で試してみてください。
フルカスタム仕様には、ちょっとだけ DOM スクリプティング(ってか JavaScript)を使います。 メッセージを含む DOM ノードの validationMessage プロパティ値を変更することによって setCustomValidity メソッドでカスタムメッセージを指定することができます。
フォーム要素ノード上で checkValidity メソッドが入力フィールドを検証した際にその値が無効であった場合、そのノードで invalid イベントが発生されます。なので、ここでイベントリスナを登録してそこで入力フィールドが空もしくはミスマッチかを調べてやればよいのです。
input.addEventListener('invalid', function(e) {
if(input.validity.valueMissing){
e.target.setCustomValidity("PLZ CREATE A USERNAME, YO!");
} else if(!input.validity.valid) {
e.target.setCustomValidity("U R DOIN IT WRONG!");
}
}, false);
下の画像が Firefox 16 での結果です。

validity プロパティは、 value、 valueMissing、 typeMismatch など、要素のバリデーション状態を boolean で示すプロパティを含む ValidityState オブジェクトを返します。(ValidityState についてもっと詳しく学びたい方のためにブログの最後にリンクを貼っておきます。)
このデモで実際にどう動くか見てみてください。コードを fork して是非自分でもほかの ValidityState オブジェクト状態がどういったふうに動くのか確かめてみてください。
JavaScript と title 属性を両方使うことも可能です。これも自分で試してみてください。
Put Them All Together
さてここでフルまとめデモを見てみましょう。Windows Phone 8 メトロ UI をちょっとまねたスタイルにしてみました。なのでモバイルからもぜひためしてみてね。
実は私が試してみたところ IE 10 にはちょっとした gotcha があるのです。まあ、IE なので落とし穴があって当たり前か、とも思うのですが。このデモの場合、どうもフィールドが unfocus するまでチェックマークアイコンが表示されないようなのです。テストした他のブラウザでは入力値が有効になり次第(このデモの場合、文字数が6文字になり次第)アイコンがちゃんと表示されます。
で、下の画像は Windows Phone 8 上の IE10 Mobile の実際のスクリーンショットです。

ちょっと端折った箇所もあるのでわかりにくい所もあったかもしれませんが、これからのフォーム UX の参考になっていただけえたらうれしいです。あ、あと最後に。フォールバックについて書きませんでしたが、バリデーションがすべてのブラウザに実装されているわけではないので実際は送信されたデータはサーバサイドでもしっかり管理することが大切です。当然といえば当然なのですが念のため。
ではよいお年を(ってちょっとまだ早いか)。
Learn More
日本語
- MSDN: フォーム (Windows)
- Adobe: HTML5&CSS3入門 第4回 @font-face(ウェブフォント)の利用
英語
- WebPlatform.org: HTML5 form features
- Dive Into HTML5: A Form of Madness
- W3C: CSS Fonts Module Level 3
- Six Revisions: The Essential Guide to @font-face
- WebPlatform.org: Pseudo-elements
- MSDN: ValidityState object
9
HTML5 Dev Conf Slides

I forgot to post the slides from my talk at HTML5 Dev Conf in San Francisco on October 15 and 16.
There were so many great speakers and varieties of topics all day long for two days, and I truly enjoyed being there as an audience and as a speaker.
And I would like to say thank you so much for all of you who attended at my talk. I was surprised to see the room was completely full -actually it was overflowed so some had to sit on floor, and some turned away by staff.
Anyway, my talk was about strategies on mobile with HTML5 – pretty much same as the last talk at Innovators of The Web Conf, but with more updated info and demos.
The slides for my preso is available on github. Use arrow keys or spacebar to navigate the slides. (This is created on Google’s HTML slide template, and it is best viewed on Webkit-based browsers.)
3
Resolution in Media Queries

I realized I hardly blog about mobile web development, although I do tweet about mobile quite often! (If you have not follow me on twitter, follow @girlie_mac now.)
So I decided to post a few short topics from my last presentation, and my first topic off the preso is about CSS resolution.
CSS Resolution
This is such obscure CSS 2 feature that not many people know or have used.
The resolution media feature describes the resolution of the output device, and its unit can be-
- dpi (dots per inch)
- dpcm (dots per centimeter), and
- dppx (dots per pixel, proposed for CSS3)
Why it matters?
So why has this become relavent to mobile web development now?
Because mobile display has been up-res’ing since Apple has announced the Retina display. To be honest with you, I am not sure if other manufacturers like Samsung had high pixel density displays before Apple, however, the hi-res trend has started ever since.
Retina display has the twice as much pixel density, and its device pixel ratio is 2 (DOM window.devicePixelRatio == 2), and for example, Nexus One has 1.5.
I am not talking more details on pixel density here, however, if you would like to learn more about what “device pixels” means and how a CSS pixel differs from a device pixel, I recommend PPK’s article, “A pixel is not a pixel is not a pixel“.
Crazy vender differences on device-pixel-ratio
In Webkit, the media query to differentiate the “regular” display (where a CSS pixel equals to a device pixel) versus the high pixel density displays, device-pixel-ratio is commonly used. To be precise, you must add the webkit prefix (as of August 2012), as -webkit-min-device-pixel-ratio, to check the minimum value of 2, 1.5, etc.
So what about non-Webkit?
Well, this gets more complicated than you think- For Mozilla, prefixed min-device-pixel-ratio is min--moz-device-pixel-ratio, and for Opera, the prefix rule is similar to webkit, -o-min-device-pixel-ratio, however, Opera requires the device pixel ratio value as a fraction, as 2/1 and 3/2 (instead of 2 and 1.5, respectively).
This is too annoying, right?
Unprefix it with resolution
So here’s a solution – use resolution.
Instead of writing,
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (min--moz-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 3/2)
only screen and (min-device-pixel-ratio: 1.5) {
// some hi-res css
}
Write this:
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (min-resolution: 144dpi) {
// some hi-res css
}
On current mobile browsers, this shorter media-queries work on Webkits (Safari, Chrome, Android, MeeGo/Nokia, Dolphin etc.) and Firefox, Opera and IE9+! (Edit: IE9 and IE10 do support the resolution, however, it may recognize its value wrongly. e.g. Lumia 800 has the screen resolution of 480×800, while CSS pixel width of 320px, but the CSS resolution value is recognized as 96dpi, instead of 144dpi. Updated on Aug 23, 2012: According to Microsoft’s IE team, IE Mobile’s layout is done at 96dpi independently of the device so the dpi value not reflect the actual device.)
In case you wonder where the number 144 comes from – this is 1.5x of the regular screen resolution, 96dpi. If you want to detect Retina (Galaxy Nexus, or any displays with 2x pixel density), you use 192dpi.
Once the proposed unit, dppx is supported (no browsers support in this moment), this would be simpler like:
@media only screen and (min-resolution: 1.5dppx) {
// some hi-res css
}
So stop worrying about the confusing device-pixel-ratio. Life shouldn’t be more complicated!
References
31
HTML5: The Mobile Approach
It was great to be invited to speak at Innovators of the Web Conference at Adobe San Francisco on July 21.
My talk was about strategies on mobile with HTML5 – Adaptive approach (“Responsive Web Design”) and Mobile-only approach.
The slides for my preso is available on github. Use arrow keys or spacebar to navigate the slides. (This is created on Google’s HTML slide template, and it is best viewed on Webkit-based browsers.)
I will blog about some of the contents here or Nokia blog soon! (Yes, I went back to Nokia a few months ago, in case you didn’t know!)
24
Making Chupa-Chups using CSS3 Pseudo-elements
One of the biggest reasons why I don’t blog often is probably because I tweet a lot. Just write a few words and throw some jsfiddle or Dabblet URLs in 140 chars, and boom, I can reach sizable numbers of people. It was quick and easy for me when I had busy days…
Well, now, I have lost my job at Hewlett-Packard (as they ditched Palm hardware then dumped the webOS software as open-source, they no longer need me and my hard-working teammates), so I should no longer excuse for not writing. So here I am, I decide to write up about CSS3 shapes from the fiddles I have written recently:
Shapes with CSS3 Part.1 – Heart
Heart-shaped chocolate live demo: http://dabblet.com/gist/2190614
This Valentine’s Day demo (I really did make this on Feb.14!) shows how to create a heart shape.
Basic idea behind is that creating two rectangles with round-corners on top-left and top-right, and rotate each object in either positive or negative 45 degrees. The trick of making two objects in one HTML element is using pseudo-elements, ::before and ::after.
This code snipet shows how to create a simple heart-shape:
.heart {
position: relative;
}
.heart::before,
.heart::after {
content: "";
position: absolute;
top: 0;
background-color: red;
width: 150px;
height: 240px;
border-radius: 75px 75px 0 0;
}
.heart::before {
left: 0px;
transform: rotate(-45deg);
background-color: red;
}
.heart::after {
left: 64px;
transform: rotate(45deg);
}
In this example, I omit the vender prefix, but you do need to include them, for example, -webkit-transform to be able to make this code work on the current browsers.
Shapes with CSS3 Part.2 – Flower
Chupa-Chupsy live demo: http://codepen.io/girliemac/pen/gnfwd
This Chupa-Chups, or I’d call it Chupa-Chupsy candy, since I cannot replicate the actual design of the candy wrapper accurately. (Oh, by the way, did you know the logo was created by the surreal artist, Salvador Dalí? Seriously.)
So I tried to mimic the signature yellow flower-shape, with one HTML element using the pseudo-element. This shape is made with a combination of two rounded-corner squares. One of the square is rotated to 45 degrees.
This is how to create the basic flower-shape:
.flower-shape {
position: relative;
}
.flower-shape,
.flower-shape::before {
width: 200px;
height: 200px;
border-radius: 25%;
background: yellow;
}
.flower-shape::before {
content: "";
position: absolute;
transform: rotate(45deg);
}
In this example, I used only ::before pseudo-element, instead of both before and after. Although I used both for the heart-shape example (which is made with two rectangles), technically, you can include three objects into one HTML element by inserting each object before and after the object on the element.
So if you’d like to have a flower with 12 petals, you can define .flower-shape::after, which is rotated in 30deg. Make sure to make the .flower-shape::before in -30deg.
To mimic the candy logo, I used the most similar web-font I found on Google Web Font. Once you see the real Chupa-Chups logo, you’ll see this web-font is actually nothing resembling it. But, hey.
Shapes with CSS3 Part.3 – Speech Bubble

Klout Score Flag demo: http://jsfiddle.net/girlie_mac/2uk6U/
This is a no-image replica of the Klout score flag! Creating this speech-bubble style shape used the same technique using ::after pseudo-element.
The method of making the triangle shape is the good’ol CSS2 border shading trick using border-width and border-color. Giving think borders around a box with zero width and height. The triangle size is determined by the border-width, with the given color on the one side and transparent on the rest of the sides. You can read more about how to create a triangle on CSS-Tricks.
The basic shape can be coded like this:
.speech {
background-color: orange;
width: 200px;
height: 160px;
border-radius: 10px;
position: relative;
}
.speech:after {
content: "";
display: block;
width: 0;
height: 0;
border-bottom: 28px solid transparent;
border-right: 58px solid orange;
position: absolute;
right: 0;
}
21
Quick Fun: CSS3 Filter Effects
I quickly played with the brand-new CSS Filter Effects on the latest WebKit Nightly! (Edited: Now also supported on Chrome Canary 18.0.976.0 +)
Click the images to view in the full size.

This is a default google.com screen.
No filter added.

blur(radius) to create Gaussian blur
-webkit-filter: blur(2px);
The default is 0, no blur.
-webkit-filter: brightness(30%);
The default is 100%. Values of amount over 100% are allowed.
Updated: I am not sure when it has modified, but it seems that not the accepted value is the range between -100% (dark) and 100% (light), and the default is 0.
-webkit-filter: contrast(30%);
The default is 100%. Values of amount over 100% are allowed.
-webkit-filter: grayscale();
The default is 100%.
-webkit-filter: sepia();
The default is 100%.
-webkit-filter: invert();
The default is 100%.
-webkit-filter: opacity(30%);
The default is 100%, no transparency.
-webkit-filter: saturate(50%);
The default is 100%.

Saturate(amount) – the amount over 100% is also allowed.
-webkit-filter: saturate(300%);
-webkit-filter: hue-rotate(90deg);
The default is 0deg.
-webkit-filter: hue-rotate(300deg);
/* Adding Drop-shadow on the toolbar at the top */
#bg {
-webkit-filter: drop-shadow(rgba(0,0,0,0.5) 0 5px 5px);
}
28
HTML5 Form Field Validation with CSS3
HTML5 Built-in Form Validation
HTML5 specifications come with a full of goodness that make web devs’ lives easier.
The one of the goodies, the client form validation is the one I like a lot, because, for example, by adding required attribute to an input, I don’t need to write any additional JavaScript to warn a user, when the user submits a form without filling out the required fields. The interactive warning UI comes with browsers.

The “Speech bubble” UI is built in with HTML5-enabled browsers. (This screenshot is taken on Chrome. Other browsers like Firefox and Opera have their own interface.)
Pattern Matching
You can also validate against patterns that defined by you. The pattern attribute specifies a regular expression against the control’s value.
<input type="text" pattern="[0-9]{13,16}" title="A credit card number" />
A user is required to enter values to match a regular expression pattern, in this case, a 13 to 16 digit number.
CSS3 User Interface Selectors
There are numerous user interface state pseudo-classes. You’ve probably already known :hover, :active etc. According to this W3C Candidate Doc, there are additional pseudo-classes defined, such as :valid, invalid, in-range, out-of-range, required, optional, read-only and read-write.
So I played a bit with :valid and :invalid to check against the regular expression pattern.

The diagram shows: 1) The entry is displayed in red when the entered text is not matched.
2) The built-in HTML5 message is displayed when the user submits the form while leaving the invalid entry. No additional CSS is used.
3) The entry is in green when it matches with the defined pattern. Also, a check mark is used as an indicator to tell it is valid.
The simplified code is below. Also you can view the entire code and the working demo on jsFiddle.
<input id="cc" type="text" pattern="[0-9]{13,16}" required />
<div class="input-validation"></div>
<input id="payButton" type="submit" value="Pay Now" />
input[type="text"]:valid {
color: green;
}
input[type="text"]:valid ~ .input-validation::before {
content: "✓";
color: green;
}
input[type="text"]:invalid {
color: red;
}
I was too lazy to create an image, so I just used the unicode checkmark. Actually, what I wanted to do was that inserting the unicode content after the input with this CSS- input:valid:after. However, it is not possible to add contents to the input with the CSS since input has no document tree content. Therefore, I used the extra div after the input. (So I am using the sibling selector, ~, to specify the div).
If you would make it prettier, I suggest you should place some icons as a background-image of the input, instead of just dumping some unicode char!
input[type="text"]:valid {
background: url(thumb-up.png) no-repeat top right;
}
References
HTML5 Form Validation on SUMO (Mozilla Blog)
CSS3 Basic User Interface Module by W3C
The pattern attribute by WHATWG
29
Five CSS tricks used in Enyo JS Framework, and you can try them too!
Since I have joined Palm (now HP), I don’t blog frequently because working for the webOS have kept me super busy. Especially when working on the webOS 3.0 for the Touchpad tablet, I have been in multiple teams until I switched my position to commit for the Developer Relations team.
Anyway, in case you are not familiar with webOS and Enyo – webOS is a mobile platform running on Linux kernel/ webkit UI with V8 engine, so most of core apps are either written in JS and CSS, or native C/C++. And the JS framework for 3.0 is called Enyo. Basically working on the webOS framework and apps is just like developing web (in fact, I use Chrome for development). So here, I want to share some cool CSS tracks used in the framework!
1. Flexible Box Model
Enyo’s basic UI is created with using the CSS3 flexible box model.
You no longer have to worry about all the float craziness. I actually have written an article, CSS 3 Flexible Box Model and Enyo Flex Layout for webOS Developer Blog too, so please read it too!
Example:
When you want to achieve a layout that has an avatar at the left, and two lines of a person’s info at the right side like this,

You can create this UI without float if the browser support flex-box:
<div class="tweet">
<div class="tweet-avatar"><img src="avatar.png"></div>
<div class="tweet-contents">
<div class="tweet-username">@n00b_css3_user</div>
<div class="tweet-text">Hello, world. CSS3 Flexbox is cool.</div>
</div>
</div>
.tweet {
display: -webkit-box;
-webkit-box-orient: horizontal;
}
.tweet-contents {
margin-left: .5em;
display: -webkit-box;
-webkit-box-flex: 1;
-webkit-box-orient: vertical;
-webkit-box-pack: center;
}
Note: this is an original spec from 2009 and this is what browsers currently support (if they do), and likely to keep supporting. I have no idea why the spec has been completely re-written recently, but so far no browsers support the new specs.
2. Root Em
There is a new unit in CSS, rem unit, which stands for “root em”. The sizing only with em could be troublesome because how it relates to the parent’s font-size. However, the rem is relative to the root, which is html.
In Enyo framework, the root font size is set to 20px. So by using rem, you can set its children font-size easily without being affected by their parents.
Here’s a comparison of em and rem:
<div class="container"> <p class="subdue">48 minutes ago</p> </div>
With em
html {font-size: 20px;}
.container {font-size: .8em}
.subdue {font-size: .75em} /* the font size = 12px (20 x .8 x .75) */
With rem
html {font-size: 20px;}
.container {font-size: .8em}
.subdue {font-size: .75rem} /* the font size = 15px (20 x .75) */
3. Pointer-events
This is a little obscure and simple trick not everybody has known, and a secret(?) trick I have been using since the earlier webOS framework called Mojo.
The pointer-events property was originally defined for SVG content, and later adopted as a CSS property.
For CSS, there are only two values: auto or none.
You can control the target of the mouth event, and by setting this value none, the element is no longer a target of mouse events, so when a user click the element, it pass through to its descendant during the event bubbling.
<div style="position:relative">
<div class="overlay"></div>
<ul>
<li><a href="">link 1 on fading list</a></li>
<li><a href="">link 2 on fading list</a></li>
<li><a href="">link 3 on fading list</a></li>
</ul>
<div>
.overlay {
pointer-events: none;
}
The screenshots at left indicates that when the pointer-events property value is not set (default), the first link underneath of the visual overlay is not clickable, and when it is set none, the element becomes clickable (right).

The demo: http://jsfiddle.net/girlie_mac/7TvVY/
4. border-image with sprites
You have seen some demos how to use the CSS3 border-image.
But making multiple assets used for border-image is trivial because how an image needs to be “sliced” into 9 tiles with css.
However, if an each asset in the sprites only requires into 3 tiles. (For example, [static-left] [stretchable center] [static-right], and top and bottom borders are zero, you can create a single sprite image of multiple states of a button, and still be able to achieve the border-image.
.alert-button {
/* notice the fat border-bottom */
-webkit-border-image: url(images/alert-button.png) 0 14 111 14 repeat repeat;
/* notice that border-top and bottom are set zero */
border-width: 0 14px;
/* some visual styling here */
-webkit-box-sizing: border-box;
height: 37px;
line-height: 37px;
}
.alert-button:active {
/* the fat border-top and bottom adjusted */
-webkit-border-image: url(images/alert-button.png) 37 14 74 14 repeat repeat;
}
The demo: http://jsfiddle.net/girlie_mac/89C2T/
5. Hardware acceleration
WebKit enables hardware-acceleration to render CSS 3D transforms. Although some WebKit (like webOS) may not render 3D visuals correctly, it still uses the GPU to speed up. So all you need to take advantage of this is to use the -webkit-transform CSS property!
The easiest possible way to achieve it is using translate3d instead of translate (also scale3d instead of scale), although you are not intend to make your web in 3D visual effect.
.toaster {
-webkit-transform: translate3d(0,0,0);
}
or just set only the z-axis:
.toaster {
-webkit-transform: translateZ(0);
}
I hope some of the stuff I just wrote are new to you!
There are more fun stuff I can write about Enyo JS framework, but I keep them for the official HP webOS Dev Blog!
Bye now!
19
Open Web Camp III
I had this wonderful opportunity to speak at OpenWebCamp III at Stanford University on this weekend, and I feel very honor to be there with so many great speakers and attendees.
Apparently, I have been doing mobile development longer than most of people, I picked the subject on developing mobile web, and how it has been changed and what we can do next.
I covered the topics including:
- How the mobile development has changed from WML, XHTML-MP, HTML4 and finally HTML5 with CSS3
- Legacy to HTML5: using input attributes to make easier for a user to type on phone
- Dealing with smarter phones: Viewport and Media-queries
- High DPI display: CSS pixel != Device pixel
- Device API
My slides, “WAP to HTML5: Mobile web – past, present, and future” is available in html5, not Powepoint or Keynotes so I couldn’t post it on SlideShare!
17
Quick Demo: CSS3 Fancy Avatar
![]()
Now I started using jsfiddle for code snippets so I can show the code AND the actual results on browsers.
This fancy avatar frame is created pretty easily by using CSS box-shadow inset values.
Basically, what I did is that giving a div container (with an avatar picture as a background image) an inset shadow to bottom/right, and glare to top/left. Oh and added border-radius for the rounded corners.
This works without the vendor-specific extensions on latest Firefox, Chrome, Webkit Nightly, and Opera. Safari 5 still requires -webkit extension to make the box-shadow work.
Really easy and practical!
20
Quick Demo: Webkit CSS3 Mask with SVG
I haven’t got a chance to create the apps and demos I’ve been thinking because my day job at Palm has kept me really busy. (Yeah, we’re shipping webOS 2.0 pretty soon!)
So instead of writing a new material, I decided to post the stuff I was testing around a while ago because SVG seems to be a hot topic since the HTML5 buzz!
This is an example of CSS mask with SVG. -The CSS alpha mask is introduced by Webkit.org back in 2008.
And this image at the right is a screen capture from WebKit Nightly browser. The photo I use here is a Twitter avatar photo of @sockington, masked with an SVG file (I used the vector image created by eagl0r on DeviantArt and converted it as as SVG with Adobe Illustrator) with using Webkit-only CSS 3 property, -webkit-mask.
The actual demo is here.
This works only on advanced webkit-browsers with SVG support, such as Safari 4+ and Chrome 2+ (not sure. I need to check). Android webkit browsers currently do not support SVG.
For non-supporting browsers, you should just see three rectangle pictures as fallback. Nothing should look broken.
The code is Simple
<img class="avatar" src="avatar-pic.png"/>
.avatar {
-webkit-mask-box-image: url(twitter-bird.svg);
}
I used mask-box-image instead of mask-image to make the mask stretch to fit with various image sizes and aspect ratio. mask-image repeats the mask images as patterns (also you can specify the type of repeat, and position etc. I am not going to talk about them here but you can read on the reference link below).
Reference
Surfin’ Safari (webkit.org) – CSS Masks
2
Simulating MacOS Dock-like menu with CSS3

Since my original “CSS Aqua button” written last year, I have seen more and more fan CSS3 UI mimic of MacOS components around! I think I have seen some Mac docks too, but as I remember they all use jQuery.
So I was thinking about making one only with CSS.
Initially I thought it was easy – let’s make an hovered icon larger like 200%, and make siblings in 150% of the original size using CSS sibling selector, and done! A piece of cake, huh? – Then I realized I made a mistake. The adjacent-sibling selector apply to an element which is immediately after the element in markup, not both before and after.
Oh well, so I needed to write a minimal JavaScript (so you don’t need to import a whole JS library) to add a class name to the element comes before the hovered object.
Anyway, here’s the live-demo! (Try it with the the latest Webkit Nightly or Safari 4) for the best experience!), and I’ll show you how I did-
Markup (Simplified)
Let’s create menu items as a list.
<div id="dock-container">
<div id="dock">
<ul>
<li><a href="http://android.com"><img src="images/dock-icons/android.png"/></a></li>
<li><a href="http://palm.com"><img src="images/dock-icons/palm.png"/></a></li>
<li>...
</ul>
<div class="base"></div>
</div>
</div>
The list should be displayed horizontally by setting the style to #dock li {display:inline-block}. Please see the source code from the demo for the details.
Magnify the icon with CSS transform
First, let’s define the dock icon animation with css transition.
The origin of the transform has to set to bottom, so the icon doesn’t scale from the middle of the icon. (Diagram #1).
I used only a webkit extension for this example but you can use -moz and -o extensions, for Firefox and Opera respectively.
Then, set the hover state – use css transform to scale the icon image up to 200%. Also you need to add some margin otherwise the enlarged icon overlaps with neighboring icons!
#dock li img {
width: 64px;
height: 64px;
-webkit-box-reflect: below 2px
-webkit-gradient(linear, left top, left bottom, from(transparent),
color-stop(0.7, transparent), to(rgba(255,255,255,.5))); /* reflection is supported by webkit only */
-webkit-transition: all 0.3s;
-webkit-transform-origin: 50% 100%;
}
#dock li:hover img {
-webkit-transform: scale(2);
margin: 0 2em;
}
Magnify adjacent icons
#dock li:hover + li img,
#dock li.prev img {
-webkit-transform: scale(1.5);
margin: 0 1.5em;
}
To magnify the icon at the right hand side of the hovered icon (Diagram #2), all you need to do is define the scale with using a CSS adjacent-sibling selector, E + F (an F element immediately preceded by an E element).
For the icon at the left (Diagram #3), ss I mentioned earlier, there is no css to get the previous sibling, so I need to rely on JavaScript.
I used the DOM node interface, previousElementSibling to access the sibling node. previousElementSibling should be supported by Webkit, Opera and Firefox.
Basically what I am doing here is that get the mouseovered object (should be an img element), find the parent li element (the immediate parent should be an a-alement, not a li, so get a’s parent! Check the HTML code again!), find the previous sibling li, then give a classname “prev” so I can apply the style.
Don’t forget to remove the class name as mouseout, otherwise the icon stays large.
function addPrevClass (e) {
var target = e.target;
if(target.getAttribute('src')) { // check if it is img
var li = target.parentNode.parentNode;
var prevLi = li.previousElementSibling;
if(prevLi) {
prevLi.className = 'prev';
}
target.addEventListener('mouseout', function() {
prevLi.removeAttribute('class');
}, false);
}
}
if (window.addEventListener) {
document.getElementById("dock").addEventListener('mouseover', addPrevClass, false);
}
For more details with the fancy CSS3 effects (e.g. the gradient and 3D-transform to create the “base” of the dock), please see the source code of the demo page!
4
CSS3 Box-Shadow with Inset Values – The Aqua Button ReReVisited!
This is my third article on CSS3 No Image Aqua Buttons. The previous articles include:
- CSS3 Gradients: No Image Aqua Button
- CSS3 Aqua Button – Revisited for Firefox 3.6
- And this one – Read on!
Since Smashing Magazine has selected the original Aqua button demo for their article, “50 Brilliant CSS3/JavaScript Coding Techniques”, I have had so much more visitors to my blog.
This resulted quality developers leave useful comments and tips for me – thank you, Zoley for suggesting using box-shadow with the inset value, and a big thank you to Jim for actually re-writing the Aqua button with the technique!!!
So, now the CSS3 Aqua button is revised with semantic markup (no more “glare” div! Yes, I complained it by myself before!) and shorter CSS.
And this time, no CSS gradients! – use CSS box-shadow property with multiple inset values to draw layers of inner-shadows to create the visual effect.
Syntax
(-moz-)box-shadow: none | <shadow> [,<shadow>]* where <shadow> is defined as: inset? && [ <offset-x> <offset-y> <blur-radius>? <spread-radius>? && <color>? ]
Values
from Mozilla Developer Center:
inset (optional)
If not specified (default), the shadow is assumed to be a drop shadow (as if the box were raised above the content).
The presence of theinsetkeyword changes the shadow to one inside the frame (as if the content was depressed inside the box). Inset shadows are drawn above background, but below border and content.
<color> (optional)
If not specified, the color depends on the browser. In Gecko (Firefox), the value of thecolorproperty is used. Safari’s shadow is transparent and therefore useless if <color> is omitted.
<offset-x> <offset-y> (required)
This are two <length> values to set the shadow offset. <offset-x> specifies the horizontal distance. Negative values place the shadow to the left of the element. <offset-y> specifies the vertical distance. Negative values place the shadow above the element.
If both values are 0, the shadow is placed behind the element (and may generate a blur effect if <blur-radius> and/or <spread-radius> is set).
<blur-radius> (optional)
This is a third <length> value. The higher this value, the bigger the blur, so the shadow becomes bigger and lighter. If not specified, it will be 0.
<spread-radius> (optional)
This is a fourth <length> value. Positive values will cause the shadow to expand and grow bigger, negative values will cause the shadow to shrink. If not specified, it will be 0 (the shadow will be the same size as the element).
Note – The box-shadow property has been removed from W3C CSS3 Background Candidate recommendation document.
The Entire Code!
Use -moz and -webkit prefix for box-shodow to support these browsers. For Opera, there’s no need to add -o.
Also, notice there are three inset values are defined for detailed visual effects!
<input type="button" class="new-aqua" value="Login"/>
input[type=button].new-aqua {
width: 155px;
height: 35px;
background: #cde;
border: 2px solid #ccc;
border-color: #8ba2c1 #5890bf #4f93ca #768fa5;
font: 600 16px/1 Lucida Sans, Verdana, sans-serif;
color: #fff;
text-shadow: rgba(10, 10, 10, 0.5) 1px 2px 2px;
text-align: center;
vertical-align: middle;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
border-radius: 16px; -moz-border-radius: 16px; -webkit-border-radius: 16px;
box-shadow: 0 10px 16px rgba(66, 140, 240, 0.5), inset 0 -8px 12px 0 #6bf, inset 0 -8px 0 8px #48c, inset 0 -35px 15px -10px #7ad;
-moz-box-shadow: 0 10px 16px rgba(66, 140, 240, 0.5), inset 0 -8px 12px 0 #6bf, inset 0 -8px 0 8px #48c, inset 0 -35px 15px -10px #7ad;
-webkit-box-shadow: 0 10px 16px rgba(66, 140, 240, 0.5), inset 0 -8px 12px 0 #6bf, inset 0 -8px 0 8px #48c, inset 0 -35px 15px -10px #7ad;
}
.new-aqua:hover {
text-shadow: rgb(255, 255, 255) 0px 0px 5px;
}
View the live demo page! This new aqua button works on FF 3.6, Webkit 4 (the current Safari 4 doesn’t support inset box-shadow yet), Chrome 4 and Opera 10. (But fails on 10.1 on Mac).
* Edited on Feb.5 – Opera 10.1 fail and Safari4 (I noticed this works only on Webkit Nightly after published this!)
And again, a huge thanks to Jim Green for the revised CSS!
References
- Safari CSS Reference by Apple Safari Dev Center
- -moz-box-shadow by Mozilla Developer Center
- CSS3 borders, backgrounds and box-shadows by Dev.Opera
28
CSS3 Aqua Button – Revisited for Firefox 3.6
This is an update for the Aqua button tutorial. This update will add a support for Firefox 3.6. If you haven’t seen the article, please go read it before proceeding here.
On the end of November last year, Mozilla Hacks announced the support for CSS gradient in a background on upcoming Firefox 3.6 (which final version has just released recently).
As already been supported on WebKit, FF does support both linear and radial gradient, however, Mozilla has implemented differently –
Most noticeably, Mozilla separate linear and radial gradient as -moz-linear-gradient and -moz-radial-gradient, while on WebKit, the syntax goes -webkit-gradient and you specify linear or radial.
Also the specification of each value is different too.
If you want a linear gradient starting from red on top to ending at bottom in white, you need to define –
WebKit:
background: -webkit-gradient(linear, left top, right bottom, from(red), to(white)))
Firefox:
background: -moz-linear-gradient(top, red, white);
The Aqua Button Redefined
Let’s re-create the aqua button, by adding -moz prefixed gradient definitions:
The button:
.aqua{
background-color: rgba(60, 132, 198, 0.8);
border-top-color: #8ba2c1;
border-right-color: #5890bf;
border-bottom-color: #4f93ca;
border-left-color: #768fa5;
-webkit-box-shadow: rgba(66, 140, 240, 0.5) 0px 10px 16px;
-moz-box-shadow: rgba(66, 140, 240, 0.5) 0px 10px 16px;
background-image: -webkit-gradient(linear, 0% 0%, 0% 90%, from(rgba(28, 91, 155, 0.8)), to(rgba(108, 191, 255, .9)));
/* for FF 3.6 */
background-image: -moz-linear-gradient(rgba(28, 91, 155, 0.8) 0%, rgba(108, 191, 255, .9) 90%);
}
and the glare:
.button .glare {
position: absolute;
top: 0;
left: 5px;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
height: 1px;
width: 142px;
padding: 8px 0;
background-color: rgba(255, 255, 255, 0.25);
background-image: -webkit-gradient(linear, 0% 0%, 0% 95%, from(rgba(255, 255, 255, 0.7)), to(rgba(255, 255, 255, 0)));
/* for FF 3.6 */
background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 95%);
}
This is the actual html page. Open it on Firefox 3.6 and see!
More Info on Mozilla CSS Gradients
- CSS gradients in Firefox 3.6 by HACKS.MOZILLA.ORG
- -moz-linear-gradient by Mozilla Developer Center
- -moz-radial-gradient by Mozilla Developer Center
Recent Posts
- Touchy-Feely with DOM Events: Rethinking Cross-Device User Interaction
- My Mobile HTML5 Talks Slides
- How to Enable WP8 Emulator on Mac
- HTML5 Form Validation のカスタマイズ
- HTML5 Dev Conf Slides
- HTML5 File API & XHR2 with Node.js Express
- Because I Want Mobile Web to Be A Better Platform
- Resolution in Media Queries
- HTML5: The Mobile Approach
- Creating Non-disruptive Notifications with HTML5
- Making Chupa-Chups using CSS3 Pseudo-elements
- Quick Fun: CSS3 Filter Effects
- The Day I seized The InterWeb – HTTP Status Cats
- HTML5 Form Field Validation with CSS3
- HTML5 Input Event Handlers and User-Experience
- Creating Usable Enyo UI – Buttons and Interactive Dialogs
- Thank you, Steve!
- Five CSS tricks used in Enyo JS Framework, and you can try them too!
- Open Web Camp III
- Quick Demo: CSS3 Fancy Avatar
















