terkel.jp
I am writing about my experiences as a naval navel-gazer.
2024-12-21T00:00:00Z
https://terkel.jp/
Takeru Suzuki
[email protected]
こんにちは、世界!
2008-02-29T00:00:00Z
https://terkel.jp/archives/2008/02/hello-world/
<p>もうずいぶん長いこと、このブログを手元でいじっている。あまりにたくさんの部分が未完成だけど、いいや。リリースしてしまう。話はそれからだ。</p>
<p>terkel.jp、公開。2008年2月29日、うるう年の余分に贈られた日に記す。</p>
Mac 版 Firefox 3 はデフォルトのフォントサイズが 16px に
2008-04-21T00:00:00Z
https://terkel.jp/archives/2008/04/mac-firefox-font-size-16px/
<p>4月16日に開催されたセミナー、<a href="http://cssnite.jp/ginza/vol24/">CSS Nite in Ginza, Vol.24</a> に参加してきた。リリース間近の Firefox 3 の新機能について <a href="http://www.mozilla-japan.org/">Mozilla Japan</a> のスタッフが語る、というのがテーマ。僕はといえば、実はアンケート回答者に配られた <a href="http://foxkeh.jp/blog/25/">Firefox ストラップ</a> が目当てだったりもしたわけだけど、ちょっとうれしい話も聞けた—Mac 版 Firefox のデフォルトのフォントサイズがついに 16px になるという!</p>
<p>これはおそらく日本語版のみの話だと思うけど、ほぼすべてのモダン・ブラウザがデフォルトのフォントサイズを 16px に標準化しているのに、Mac 版 Firefox だけが 14px だったのだ。ちなみになぜそうだったかとういと、旧 Mac OS において Osaka フォントの 16px が用意されていなかったからだとか。</p>
<p>今までは、CSS でフォントサイズをいわゆる「相対値」で指定し、かつ、Mac 版 Firefox でも同じサイズにしようとすると、IE 向けのハックが必要だった。たとえば、ベースとなる body 要素のフォントサイズを 10px 相当にするにはこんな感じ:</p>
<pre><code class="language-css">body {
font-size: 10px; /* for Firefox, Safari, Opera */
}
* html body {
font-size: 62.5%; /* for IE */
}
</code></pre>
<p><del datetime="2009-11-14">でも正味の話さあ、Mac 版 Firefox ってシェアなんぼよ? とか、こういう対応をしてるサイトとしてないサイトでフォントサイズばらばらじゃん! とか思ってしまうので、実際にはこんなふうに書いたことないけど。</del><br />
<ins datetime="2009-11-14">今や僕もすっかり Mac の Firefox ユーザーですごめんなさい。</ins></p>
のっちメソッド: One pixel notched corners
2008-04-26T00:00:00Z
https://terkel.jp/archives/2008/04/one-pixel-notched-corners/
<p role="note"><small>2009 年 6 月に <a href="https://terkel.jp/archives/2009/06/one-pixel-notched-corners-2/" title="のっちメソッド 2: なりゆき幅で横並び">改良版</a> を書きました。</small></p>
<hr />
<p><a href="http://www.askthecssguy.com/">Ask the CSS Guy</a> の記事 <a href="http://www.askthecssguy.com/2008/03/one_pixel_notched_corners_as_u.html">One pixel notched corners as used by Google Analytics</a> を試してみた。<a href="http://www.google.com/analytics/ja-JP/">Google Analytics</a> で使われてるような、四隅が 1px 欠けているボックスの表現を画像を用いず CSS のみでやってみよう、という話。上記記事に対する <a href="http://www.askthecssguy.com/2008/03/one_pixel_notched_corners_as_u.html#comment-7818">Simon さんて方のコメント</a> で「もっと簡単にできんじゃね?」という例があるけど、なんだか不思議なマークアップだったので、僕なりに整理してみる。</p>
<p>まず、例としてナビゲーションメニューのようなものを考えてみる。マークアップはこんな感じ:</p>
<pre><code class="language-html"><!-- HTML -->
<ul>
<li><a href="#">One</a></li>
<li><a href="#">Two</a></li>
<li><a href="#">Three</a></li>
<li><a href="#">Four</a></li>
</ul>
</code></pre>
<p>Google Analytics の場合、この <code>a</code> 要素の中身をなんと3重の <code>b</code> 要素でくるむという乱暴なマークアップらしいんだけど、ここでは上記ソースにはこれ以上手をいれない。</p>
<p>で、CSS。まず <code>li</code> 要素に 1px の上下ボーダーと 1px の左右マージンを持たせる:</p>
<pre><code class="language-css">/* CSS */
li {
border-top: 1px solid #999999;
border-bottom: 1px solid #999999;
margin: 0.5em 1px;
}
</code></pre>
<p>次に、子要素である <code>a</code> 要素をブロック化し 1px の左右ボーダーを持たせ、かつ左右のマージンを -1px にし、<code>li</code> 要素からはみ出させる:</p>
<pre><code class="language-css">/* CSS */
li a {
display: block;
border-right: 1px solid #999999;
border-left: 1px solid #999999;
margin: 0 -1px;
}
</code></pre>
<p>以上。<a href="https://terkel.jp/demo/one-pixel-notched-corners.html">完成版デモ</a> をご参照されたし。色使いなんかを工夫すれば、かなり実用的なテクニックじゃないかと思う。命名、「のっちメソッド」。</p>
「右クリック禁止」に戸惑う
2008-05-08T00:00:00Z
https://terkel.jp/archives/2008/05/oncontextmenu/
<p>クライアントから、ある画像を「右クリック禁止」にしてほしい、との依頼があった。そのとき僕が感じた気持ちをひとことで言い表すのは難しい。それはいらだちでもあり、無力感でもある。</p>
<p>僕たち Web デザイナーは「右クリック禁止」がいかにバカげたギミックかを知っている。でも、クライアントが本当に心を痛めているとしたら? 「私の描いた絵が誰かのハードディスクに保存されてしまったら…」「見ず知らずのサイトからいつの間にかリンクされてしまったら…」そう考えると夜も眠れないんだとしたら? 彼らにその要望がいかに的外れなものであるかを説くことは、はたしてベストの選択だろうか?</p>
(要素に) 名前をつけてやる
2008-05-10T00:00:00Z
https://terkel.jp/archives/2008/05/class-or-id/
<p>いわゆるヘッダやフッタなど、ページを構成する主要なブロックをマークアップする際、<code>div</code> 要素に <code>id</code> 属性で名前をつけることが多い。<code><div id="header"></code> とか。なぜ <code>class</code> ではなく <code>id</code> なのか? その理由としておそらく最も多いのが、「ページ内で唯一のものだから」。HTML を解説した本やなんかを読むと、「複数出現する (またはその可能性のある) 要素は <code>class</code> で、唯一の要素は <code>id</code> で」なんて書いてあることがよくある。</p>
<p>僕も長いことそうしてたんだけど、どうも違うんじゃないか、と最近は考えてる。今しっくりくるのは、「<code>id</code> 属性は唯一の要素に名前をつけるためのものではなく、要素に一意の (unique) 名前をつけるためのもの」って考え方。つまり、その要素がドキュメントにいくつ出現するかってことじゃなくて、他の要素と識別されるべき要素かどうか。</p>
<p>実際のマークアップ手順としては、まず要素の「役割」や「種別」、「所属」のようなものをもとに <code>class</code> 属性を付与。で、もし「一意の名前」が必要であれば <code>id</code> 属性も付与、って感じ。</p>
<p>そのため、<code>class</code> 属性の値はいわゆる「文脈的」というか「構造的」というか、その要素の役割が理解されやすいキーワードであるべきなのに対し、<code>id</code> 属性の値はあくまで「識別子」なので、ほかとかぶりさえしなければどんな意味不明の文字列でも一向にかまわないはずだ。とはいえ、<code>id</code> 属性を持つ要素はすなわち URI を持つことになるわけで、そのへんは意識して名前を考えたほうがいいかなとも思う。</p>
Google サイトマップを Movable Type で生成
2008-05-10T00:00:00Z
https://terkel.jp/archives/2008/05/google-sitemaps/
<p><a href="http://www.google.com/webmasters/tools/">Google ウェブマスター ツール</a> を利用すると、Google にサイトマップを送信することができる。そうすることで、君のページを Google に見つけてもらいやすくなるわけだ。このサイトマップは Google の指定する XML 形式で記述する必要があるんだけど、ここでは、そのサイトマップを Movable Type のテンプレートを使って自動生成してみる。こんな感じ:</p>
<pre><code class="language-html"><?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.google.com/schemas/sitemap/0.84">
<url>
<loc><mt:BlogURL encode_xml="1" /></loc>
<priority>1.0</priority>
</url>
<mt:Entries lastn="9999">
<url>
<loc><mt:EntryPermalink encode_xml="1" /></loc>
<lastmod><mt:EntryModifiedDate format="%Y-%m-%d" /></lastmod>
</url>
</mt:Entries>
<mt:Pages>
<url>
<loc><mt:PagePermalink encode_xml="1" /></loc>
<lastmod><mt:PageModifiedDate format="%Y-%m-%d" /></lastmod>
</url>
</mt:Pages>
</urlset>
</code></pre>
<p><code>mt:Entries</code> はブログ記事、<code>mt:Pages</code> は Web ページのデータをそれぞれ生成。このテンプレートを一度保存してしまえば、常に最新のサイトマップを Google に提供し続けることができる。</p>
Movable Type 4.12 にアップグレード
2008-06-21T00:00:00Z
https://terkel.jp/archives/2008/06/movable-type-412/
<p><a href="http://www.sixapart.jp/movabletype/news/2008/06/20-1415.html">Movable Type 4 のセキュリティアップデート</a> に伴うテスト。</p>
再起動
2008-08-27T00:00:00Z
https://terkel.jp/archives/2008/08/reboot/
<p>このサイトを 2008 年 2 月に公開してはや半年。なのに記事数はなんとたった 7!</p>
<p>再起動が必要、というわけでデザインを一新した。特に CSS でちょっとした発見もあったので、そこらへんは近日中に記事にする。ともあれ、terkel.jp、リニューアル。2008 年、夏。</p>
戦争は終わった
2008-09-04T00:00:00Z
https://terkel.jp/archives/2008/09/war-is-over/
<p><a href="http://www.google.com/chrome">Google Chrome</a> の出現によって、Web デザイナーはまたひとつ面倒な仕事を増やすことになったのか?</p>
<p>否。Google Chrome は Safari と同じレンダリングエンジン <a href="http://webkit.org/" title="The WebKit Open Source Project">WebKit</a> をベースにしている。Safari のテストを通過したサイトならほとんど問題なく表示されるだろう。もしあなたのサイトが Chrome で意図どおりに表示されないというのなら、そのバグは Safari でずいぶん長いこと放置されていたことになるかもしれない。</p>
<p>Google Chrome の出現によって、Mozilla Firefox は時代遅れの恐竜と成り果てるのか?</p>
<p>否。Mozilla Labs が発表した <a href="http://labs.mozilla.com/2008/08/introducing-ubiquity/">Ubiquity</a> をチェックしてほしい。この始まったばかりの試みがどう発展していくのか、考えるだけでワクワクしてこないだろうか。Mozilla のアプローチはもちろん Google とは違う。そして幸運なことに、僕らはそのどちらも楽しむことができる。</p>
<p>では、Google Chrome の出現は新たなブラウザ戦争を引き起こすのか?</p>
<p>否! 少なくとも僕の眼には誰も戦争をしているようには見えない。Chrome の機能美や Ubiquity の可能性に刺激を受けたクリエイターが、また新たな何かを生み出す。それはフェアな競争だ。自らが生き残るために誰かを陥れる必要なんかない。ただ、楽しめばいい。</p>
ときには真珠のように
2008-09-13T00:00:00Z
https://terkel.jp/archives/2008/09/sometimes-like-a-pearl/
<p>「Web デザイナーがあらゆる閲覧環境でのタイポグラフィをコントロールしようなんておこがましいとは思わんかね…」</p>
CSS ハックをフォーマット
2008-09-26T00:00:00Z
https://terkel.jp/archives/2008/09/formatting-css-hacks/
<p>いわゆる「スターハック」に代表されるセレクタレベルの CSS ハックについて、ソースコードの整形を工夫してみる。</p>
<pre><code class="language-css">body {
font-size: 10px;
}
* html body {
font-size: 62.5%;
}
*:first-child+html body {
font-size: 62.5%;
}
</code></pre>
<p>この書き方、ハック部分が目立つのでメンテナンス性に優れてはいるものの、本来は必要ないはずの余分な記述が妙に偉そうにに居座ってる感じが、なんかイヤ。というわけで、こんなのはどうだろう:</p>
<pre><code class="language-css">body {
font-size: 10px;
} * html body {
font-size: 62.5%;
} *:first-child+html body {
font-size: 62.5%;
}
</code></pre>
<p>改行とインデントをいじっただけなんだけど、視覚的にはひとつの規則集合のなかで宣言を追加してるようなイメージ。ハックのたたずまいがやや遠慮がちになるというか。微妙か?</p>
さよなら
2008-10-01T00:00:00Z
https://terkel.jp/archives/2008/10/goodbye/
<p>この 9 月いっぱいをもって、2 年間勤めた会社を辞めました。次の仕事はまだ決まっておらず、これから求職活動が始まります。</p>
<p>今でこそいっぱしの Web ディヴェロッパーみたいな顔をしている私ですが、実は Web 業界での仕事はこの会社がはじめてでした。つまり実務経験ゼロの素人として拾ってもらったわけで、それだけでも御の字。おかげ様でこの業界でなんとかやっていけそうな自信も得られました。</p>
<p>なんだかんだと愚痴ってたくせに、いざ別れるとなるとみんながイイ奴に思えて困るよ、実際。ありがとう、さよなら!</p>
mt:SetVars
2008-10-07T00:00:00Z
https://terkel.jp/archives/2008/10/mtsetvars/
<p>Movable Type 4.1 で追加されてたらしいけど、今日までその存在に気がつかなかったのがこの <a href="http://www.movabletype.jp/documentation/appendices/tags/setvars.html" title="MTSetVars | テンプレートタグリファレンス"><code>mt:SetVars</code></a> タグ。これ、<code>mt:SetVar</code> や <code>mt:SetVarBlock</code> で個別に設定していた変数をいっぺんにまとめて書くことができるもの。例えば、</p>
<pre><code class="language-html"><mt:SetVarBlock name="title">
<mt:BlogName encode_html="1" />
</mt:SetVarBlock>
<mt:SetVar name="main_index" value="1" />
<mt:SetVar name="index_template" value="1" />
</code></pre>
<p>…と書いていたところを、<code>mt:SetVars</code> を使えば以下のとおり代替できる:</p>
<pre><code class="language-html"><mt:SetVars>
title=<mt:BlogName encode_html="1" />
main_index=1
index_template=1
</mt:SetVars>
</code></pre>
<p>これはわかりやすくて良い。</p>
768 グリッド・システム
2008-11-30T00:00:00Z
https://terkel.jp/archives/2008/11/768-grid-system/
<p><a href="http://www.cameronmoll.com/archives/2006/12/gridding_the_960/">Gridding the 960 ~ Authentic Boredom</a> や <a href="http://960.gs/">960 Grid System</a> などに触発されて、幅 960 px のグリッド・システムについて考えてみた。</p>
<p>まず、なぜ 960 px なのか? この数字が導き出される大きな理由は 2 つ。まず前提として幅 1,024 px 以上のモニタを想定する。そこからスクロールバーやブラウザ自体のボーダーなどを差し引くと、考えられる「有効内寸」は幅 1,000 px 未満。ではなぜ 980 でも 950 でもなく 960 px なのかといえば、960 が「割り切りやすい」数字だからだ。</p>
<blockquote cite="http://960.gs/" lang="en">
<p>960 is divisible by 2, 3, 4, 5, 6, 8, 10, 12, 15, 16, 20, 24, 30, 32, 40, 48, 60, 64, 80, 96, 120, 160, 192, 240, 320 and 480. This makes it a highly flexible base number to work with.</p>
<footer>— <cite>960 Grid System</cite></footer>
</blockquote>
<p class="Credit"><small>960 Grid System</small></p>
<p>…と前述の 960 Grid System にあるとおり、960 という数字は実に多くの整数で割ることができ、つまりはカラムのバリエーションが作りやすいのである。</p>
<p>でもちょっと待った。2008 年現在、デスクトップでもラップトップでも、幅 1,024 px をサポートしないモニタはごくごく少数だが、「新たな例外」というべきデバイスがいくつか存在している。例えば <a href="http://www.nintendo.co.jp/wii/features/internet/" title="インターネットチャンネル - Wii">Wii のインターネットチャンネル</a> や、<a href="http://eeepc.asus.com/jp/" title="ASUS | Eee PC">Eee PC</a> に代表される Netbook の多くは 800 px 幅だ。それにもし 1,024 px 幅でも、ブラウザのサイドバーを表示させていたり、そもそもウィンドウを縮小していたりすれば、やはり表示可能領域はせばまる。</p>
<p>というわけで、「幅 1,024 px を基準としつつ、サブカラムを除くメインカラムは 800 px に収める」てなアプローチが現実的になってくる。そこで「960 グリッド・システム」に加え、「768 グリッド・システム」を提案したい。800 px 幅のブラウザで縦スクロールバーがある場合を考慮にいれつつ、960 同様に割り切りやすい数字を求めるとこの 768 にいきつくのだ。</p>
<p>以下は、この 768 px をそれぞれ 12 と 16 のカラムに切ったグリッド図で、960 px 幅にも対応。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/grid-768px-12col-t.png" />
<figcaption>768 Grid System in 12 Columns</figcaption>
</figure>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/grid-768px-16col-t.png" />
<figcaption>768 Grid System in 16 Columns</figcaption>
</figure>
この数値文字参照がすごい! 2008 年版
2008-12-15T00:00:00Z
https://terkel.jp/archives/2008/12/ncr-2008/
<p>早いもので今年ももうこの季節である。文字実体参照に比べて覚えづらい数値文字参照、その中でも使用頻度の高いものにスポットを当てる「この数値文字参照がすごい!」の 2008 年版をお届けする。</p>
<h2>第 1 位: <strong>〜</strong> (<code>&#12316;</code>)</h2>
<p>満場一致。文句なしでぶっちぎりの首位に立ったのはご存知「波ダッシュ」。その <a href="http://ja.wikipedia.org/wiki/%E6%B3%A2%E3%83%80%E3%83%83%E3%82%B7%E3%83%A5" title="波ダッシュ - Wikipedia">ややこしい背景</a> を考えれば HTML での表記は可能な限り避けて他の表現で代替したいところ。たとえば英語圏では「いつからいつまで」「どこからどこまで」の「から」は en ダッシュ (–) を使うことが多いみたい (ソース: <a href="http://en.wikipedia.org/wiki/Dash#En_dash">Dash - Wikipedia, the free encyclopedia</a>) なのでそうしてみたり。</p>
<p>とはいえやむを得ずニョロニョロするしかない場合も多い。そんなときはあわてずこの数値文字参照を。その結果、まわりから「なんか汚くね?」と軽く却下されても、来年こそは負けずにきっちり話を通したい。そんな気持ちの読者も少なくないはずだ。</p>
<h2>第 2 位: <strong>※</strong> (<code>&#8251;</code>)</h2>
<p>まさにダークホース。並みいる猛者たちを抑え堂々の第 2 位に輝いたのは「米印」。知る人ぞ知る通好みな存在と思われがちながら、エディタによって化けることも多く、なかなかあなどれない実力の持ち主。* (アスタリスク) での代替を勧めたいところだが…</p>
<h2>第 3 位: <strong>'</strong> (<code>&#39;</code>)</h2>
<p>2 ケタとあなどることなかれ。「アポストロフィ」がヴェテランの意地を見せた。<code>&apos;</code> が HTML では使用できないことは広く知られており、2009 年もまだまだ現役での活躍が期待できそうだ。</p>
<h2>編集後記</h2>
<p>さて「この数値文字参照がすごい!」、通称「この文字」の 2008 年版、いかがだっただろうか。賢明なる読者諸兄ならお気づきのとおり、いつまでたっても波ダッシュを覚えられない自分のための記事だったわけだが。第 2 位で早くも息切れするあたり… また来年お会いしましょう! 良いお年を!</p>
WordPress 2.7 “Coltrane”
2008-12-15T00:00:00Z
https://terkel.jp/archives/2008/12/wordpress-27-coltrane/
<p><a href="http://ja.wordpress.org/" title="WordPress | 日本語">WordPress</a> の新しいヴァージョン、その名も「<a href="http://ja.wordpress.org/2008/12/11/coltrane/" title="WordPress | 日本語 » WordPress 2.7 “コルトレーン”">コルトレーン</a>」がリリースされたそうな。この tarkel.jp は <a href="http://www.movabletype.jp/" title="MovableType.jp">Movable Type</a> で構築しているのだけれど、WP は以前から気になっていて、いよいよ乗り換えを検討しようかと考えている。今回のリリースで特に惹かれたのがここ:</p>
<blockquote cite="http://ja.wordpress.org/2008/12/11/coltrane/">
<p>最後になりますが、重要なことをお知らせします。このバージョンは手動で WordPress をアップグレードする最後のバージョンになるかもしれません (訳注: 日本語版を完全にアップグレードするには、現時点では自動アップグレードは使えません)。皆さんが自分や友達のブログをアップグレードするのにどれだけうんざりしているかを聞いて、最新版が公開されたら自動的に通知する機能とビルドインアップグレード機能を組み込みました。これで、準備ができたらクリック一つで自動的にファイルをダウンロードし、インストールし、アップグレードすることができるようになりました。</p>
</blockquote>
<p class="Credit"><small>WordPress | 日本語 » WordPress 2.7 “コルトレーン”</small></p>
<p>そうなのよ! つい先日も MT の <a href="http://www.movabletype.jp/blog/_movable_type_423.html" title="[重要] セキュリティアップデート Movable Type 4.23 の提供を開始 | MovableType.jp">セキュリティアップデート</a> を実施したばかりなんだけど、もうね、かったるくって。上記のフィーチャーが日本語版にもきっちり実装されれば、かなりグッド。</p>
<p>それにこの「コルトレーン」てネーミング。大きく出たな、というか、かなりの自信作なんでしょう、きっと。この年末にでもいじってみるかも。</p>
jQuery のセレクタ機能を拡張する
2008-12-16T00:00:00Z
https://terkel.jp/archives/2008/12/extending-jquerys-selector-capabilities/
<p><a href="http://jquery.com/" title="jQuery: The Write Less, Do More, JavaScript Library">jQuery</a> の魅力のひとつは豊富な <a href="http://docs.jquery.com/Selectors" title="API/1.2/Selectors - jQuery JavaScript Library">セレクタ機能</a> だけど、それをさらに拡張することもできる。その簡単な方法を紹介してくれている記事をみつけた。</p>
<ul>
<li><a href="http://james.padolsey.com/javascript/extending-jquerys-selector-capabilities/">Extending jQuery’s selector capabilities - James Padolsey</a></li>
</ul>
<p>たとえばインライン要素を取得するセレクタ機能は以下のように書けば作れちゃう。</p>
<pre><code class="language-javascript">$.extend($.expr[':'],{
inline: function(a) {
return $(a).css('display') === 'inline';
}
});
</code></pre>
<p>これで、以降は <code>:inline</code> でインライン要素を取得できる。じゃあついでにブロックレベル要素を取得する機能も追加。</p>
<pre><code class="language-javascript">$.extend($.expr[':'],{
inline: function(a) {
return $(a).css('display') === 'inline';
},
block: function(a) {
return $(a).css('display') === 'block';
}
});
</code></pre>
<p>素晴らしい!</p>
jQuery で外部サイトへのリンクをコントロール
2008-12-20T00:00:00Z
https://terkel.jp/archives/2008/12/control-external-links-with-jquery/
<p>外部のサイトへのリンクについて、例えばそのことを示すアイコンを付けたり、あるいは別ウィンドウで開いたり、といった扱いをすることはよくある。そんな場合、<a href="http://jquery.com/" title="jQuery: The Write Less, Do More, JavaScript Library">jQuery</a> があれば以下のような JavaScript でそのコントロールが簡単に。</p>
<p>まず最初に <a href="https://terkel.jp/archives/2008/12/extending-jquerys-selector-capabilities/" title="jQuery のセレクタ機能を拡張する - terkel.jp">jQuery のセレクタ機能を拡張</a> しておく。ここでは要素が <code>href</code> 属性を持ち、かつその属性値 (リンク先) のホスト名 (ドメイン名) が今いるページのホスト名と異なる場合に <code>:external</code> セレクタで捕まえられるように拡張。</p>
<pre><code class="language-javascript">$.extend($.expr[':'],{
external: function(a,i,m) {
if(!a.href) {
return false;
}
return a.hostname && a.hostname !== window.location.hostname;
}
});
</code></pre>
<p>この拡張セレクタを利用して、該当する <code>a</code> 要素に <code>class</code> 属性を付与してみる。</p>
<pre><code class="language-javascript">$(function(){
$('a:external').addClass('external');
});
</code></pre>
<p>つまりマークアップは一切いじる必要がないってとこがミソ。あとは CSS で背景画像を表示させるなりどうぞお好きに! ちなみに別ウィンドウで開く仕様にするならこう:</p>
<pre><code class="language-javascript">$(function(){
$('a:external').addClass('external').click(function(){
window.open(this.href);
return false;
});
});
</code></pre>
No Line on the Horizon: U2
2008-12-20T00:00:00Z
https://terkel.jp/archives/2008/12/no-line-on-the-horizon-u2/
<blockquote cite="http://www.u2.com/news/index.php?mode=full&news_id=2279" lang="en">
<p>No Line On The Horizon, the new studio album from U2, will be released on Monday 2nd March 2009.</p>
</blockquote>
<p class="Credit"><small>U2.com | Official News</small></p>
<p>U2 の 12 作目のスタジオ・アルバム “No Line on the Horizon” が 2009 年 3 月にリリースされる。“All That You Can’t Leave Behid”、“How to Dismantle an Atomic Bomb” と近年の 2 作が充実していたこと、イーノ、ラノワ、そしてリリィホワイトという鉄板の製作陣であること、などを考えると不安要素があまりない。周囲からの評価やギグの動員なども落ち着いているというか安定期に入ったというか、なのでちょっとしたどんでん返しを期待する気持ちもあるというか。</p>
Electric Arguments: The Fireman
2008-12-27T00:00:00Z
https://terkel.jp/archives/2008/12/electric-arguments-the-fireman/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/fireman-electric-arguments.jpg" />
</figure>
<p><a href="http://www.thefiremanmusic.com/">ザ・ファイアーマン</a> のサード・アルバム、『<a href="http://www.amazon.co.jp/o/ASIN/B001HSQBBG/terkel-22" title="Amazon.co.jp: エレクトリック・アーギュメンツ: ザ・ファイアーマン: 音楽">エレクトリック・アーギュメンツ</a>』がいい。かなりいい。</p>
<p>ザ・ファイアーマンといえば、<a href="http://www.paulmccartney.com/">ポール・マッカートニー</a> がキリング・ジョークの <a href="http://www.youth.me.uk/">ユース</a> とはじめたユニット。活動は不定期で、1993 年と 1998 年にアルバムを発表している。サウンドはアンビエントというかエクスペリメンタルというか、僕らが知るポールの音楽とは違う、実験的なものだった。まあ周囲の捉え方としては、ポールのソロ・キャリアの合間のちょっとした息抜きでしょ、みたいな感じで、実際、今までの 2 枚のアルバムはポールのファンでさえ扱いに困ってきまりの悪い愛想笑いを浮かべるしかないような微妙な作品で、ほぼ無かったことになってた。それが…</p>
<figure>
<iframe width="560" height="315" src="https://www.youtube.com/embed/0wQmHhlZlfg" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen=""></iframe>
</figure>
<p>ごらんの有様だよ。早い話がこれ、ユースとの共同プロデュースによるポールの新作だよな。ポールお得意の一人多重録音が中心、しかも全編ヴォーカル入り。リラックスしつつも緊張感があって、ラフなようでいて繊細な音作り。楽曲の質も高い。それに今回はベースもいいね。ポールをシンガーやソングライターとしてよりもまずベース・プレイヤーとして認識している僕としては嬉しい。</p>
<p>それにしてもこの 66 歳、ここへきてのやりたい放題ぶりは目に余る。ナイジェル・ゴドリッチと組んでみたり、古巣を離れて新レーベルに移籍してみたり、余興と見せかけてガチ新譜を出してみたり…まだやるか、と。</p>
Best of 2008: 映画
2008-12-30T00:00:00Z
https://terkel.jp/archives/2008/12/best-of-2008-films/
<p>そもそも観た本数が少なすぎのためショボいリストになっちゃったけど、2009 年はもっと観よう、という決意とともにざっくりと振り返ってみる。</p>
<ol>
<li><a href="http://www.amazon.co.jp/o/ASIN/B001AQYQ1M/terkel-22" title="Amazon.co.jp: ダークナイト 特別版 [DVD]: クリストファー・ノーラン, クリスチャン・ベール, マイケル・ケイン, ヒース・レジャー, ゲーリー・オールドマン, アーロン・エッカート: DVD">ダークナイト</a></li>
<li><a href="http://www.amazon.co.jp/o/ASIN/B0021D5ETQ/terkel-22">崖の上のポニョ</a></li>
<li><a href="http://www.amazon.co.jp/o/ASIN/B001AQYQ1C/terkel-22" title="Amazon.co.jp: スピード・レーサー 特別版 (2枚組) [DVD]: ウォシャウスキー兄弟, エミール・ハーシュ, クリスティーナ・リッチ, ジョン・グッドマン, スーザン・サランドン, マシュー・フォックス, 真田広之, Rain(ピ): DVD">スピード・レーサー</a></li>
<li><a href="http://www.amazon.co.jp/o/ASIN/B001BNIKVQ/terkel-22" title="Amazon.co.jp: ゼア・ウィル・ビー・ブラッド [DVD]: ポール・トーマス・アンダーソン, ダニエル・デイ=ルイス, ポール・ダノ, ケヴィン・J・オコナー, キアラン・ハインズ, ディロン・フレイジャー: DVD">ゼア・ウィル・ビー・ブラッド</a></li>
</ol>
<p>さすがにベタすぎるだろう、このラインナップは。ていうかこれ、今年観た新作ほぼすべてか。</p>
<p>『ダークナイト』はまあ皆さん文句ないでしょう。劇場で観たときも良かったけど、DVD でディテイルをチェックするのも楽しい。もちろん最大の魅力はヒース・レジャーの「口元」!</p>
<p>『ポニョ』は子供に観せちゃいけない問題作だと思う。例えば『<a href="http://www.amazon.co.jp/o/ASIN/B00005NJLP/terkel-22" title="Amazon.co.jp: となりのトトロ [DVD]: 日高のり子, 坂本千夏, 糸井重里, 島本須美, 高本均, 雨笠利幸, 宮崎駿: DVD">となりのトトロ</a>』なんかでは、「こちら側とあちら側の境界線」のようなものが暗黙のうちにきっちりと描かれていた。本作ではそのあたりがじつにあいまいというか、そもそも境界線が溶けてなくなってしまっているというか、観ていると足元がぐらつくような不安をかき立てられるんだ。また観たいような、もう観たくないような。</p>
<p>『スピード・レーサー』は DVD で観ちゃったことが悔やまれる。これは劇場で観なきゃいけなかった! クリスティーナ・リッチ、かわいい。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/there-will-be-blood.jpg" />
</figure>
<p>『ゼア・ウィル・ビー・ブラッド』は主演のダニエル・デイ=ルイスと音楽のジョニー・グリーンウッドの映画だよな。『<a href="http://www.amazon.co.jp/o/ASIN/B00005HSDV/terkel-22" title="Amazon.co.jp: マグノリア コレクターズ・エディション [DVD]: ポール・トーマス・アンダーソン, ジェレミー・ブラックマン, トム・クルーズ, ジュリアン・ムーア: DVD">マグノリア</a>』で見せてくれたような、アクの強い俳優たちの鬼気迫る演技をそれ以上のテンションで強引にまとめ上げ、混沌としたストーリーの果てにわけのわからない救いのようなものまでぶち込む、みたいな PTA 節を期待するとハズす。デイ=ルイスを中心とした人間ドラマを執拗かつ容赦なく追いかける、という作品。とはいえ力強く美しい作品であることは間違いない。</p>
<p>2009 年はできれば毎月 1 回は劇場に足を運びたいなー。DVD も迷ったらとりあえず買え、の姿勢で臨みたい。</p>
Best of 2008: 音楽
2008-12-30T00:00:00Z
https://terkel.jp/archives/2008/12/best-of-2008-music/
<p><a href="https://terkel.jp/archives/2008/12/best-of-2008-films/" title="Best of 2008: 映画 - terkel.jp">映画篇</a> もそうだったけど、そもそも新作を聴いてない! みずからに猛省を促したい。</p>
<ol>
<li><a href="http://www.amazon.co.jp/o/ASIN/B001F6QIOA/terkel-22" title="Amazon.co.jp: ブラック アイス: AC/DC: 音楽">Black Ice: AC/DC</a></li>
<li><a href="http://www.amazon.co.jp/o/ASIN/B0013EUA0W/terkel-22" title="Amazon.co.jp: カラフル・ライフ: ケイジャン・ダンス・パーティ: 音楽">The Colourful Life: Cajun Dance Party</a></li>
<li><a href="http://www.amazon.co.jp/o/ASIN/B001HSQBBG/terkel-22" title="Amazon.co.jp: エレクトリック・アーギュメンツ: ザ・ファイアーマン: 音楽">Electric Arguments: The Fireman</a></li>
<li><a href="http://www.amazon.co.jp/o/ASIN/B0014465JQ/terkel-22" title="Amazon.co.jp: ダイアモンド・フー・ハ: スーパーグラス: 音楽">Diamond Hoo Ha: Supergrass</a></li>
<li><a href="http://www.amazon.co.jp/o/ASIN/B00104CIXW/terkel-22" title="Amazon.co.jp: Fantastic OT9: 奥田民生: 音楽">Fantastic OT9: 奥田民生</a></li>
</ol>
<p>やはり今年はなんと言っても AC/DC。これが本当に素晴らしい作品で笑った。楽曲のクオリティ、ヴォーカルのパワー、ギターのキレが 80 年代に戻っちゃってるもん。AC/DC はどれから聴いたらいいんスか? というキッズはまず “<a href="http://www.amazon.co.jp/o/ASIN/B001F6QIJK/terkel-22" title="Amazon.co.jp: バック・イン・ブラック: AC/DC: 音楽">Back in Black</a>” と “<a href="http://www.amazon.co.jp/o/ASIN/B001F6QIL8/terkel-22" title="Amazon.co.jp: レーザーズ・エッジ: AC/DC: 音楽">The Razors Edge</a>” とコレを押さえろ。まさに「最後の傑作」と呼ぶにふさわしい、見事なまでの集大成。あまりに美しい白鳥の歌。</p>
<p>ケイジャン・ダンス・パーティなんかも聴いてるよ、とか言ってリストに入れちゃうあたりのセンスがもうね、おっさんです。いやでもこのアルバムは良かったよ。巧みなソングライティングやヴォーカルのカリスマも魅力だけど、特にジョニー・マーやジョン・スクワイアらの系譜に連なるギターが素晴らしい。</p>
<p>ザ・ファイアーマンは <a href="https://terkel.jp/archives/2008/12/electric-arguments-the-fireman/" title="Electric Arguments: The Fireman - terkel.jp">別の記事</a> で書いたとおり、予想外の当たり。ちなみに <a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?id=295673979&s=143462">iTunes Store</a> だとボーナス・トラック入りでしかも安いです。</p>
<p>スーパーグラスは世紀の大傑作 “<a href="http://www.amazon.co.jp/o/ASIN/B000A7TFEK/terkel-22" title="Amazon.co.jp: ロード・トゥ・ルーアン: スーパーグラス: 音楽">Road to Rouen</a>” に続く待望の新作! とおおいに盛り上がったわけだが、んー、なんか少し昔に戻っちゃった感じが残念かなー。前作のアコースティック路線をどう発展させてくれるかに期待してたんだけど。AC/DC じゃないんだから、まだまだ新しい音を聴かせてほしい、このバンドには。もちろん良い曲はあるけどね。</p>
<p>タミオは冒頭のギターの鳴りがやばい。この最初の瞬間を聴きたくて何度もリピートしたアルバム。</p>
さよなら、2008 年!
2008-12-31T00:00:00Z
https://terkel.jp/archives/2008/12/goodbye-2008/
<ul>
<li>このブログを始めた。</li>
<li>タバコをやめた。</li>
<li>MacBook を買った。</li>
<li>転職した。</li>
</ul>
<p>今年、俺はなにをしてきただろう。思いつくままにリストアップしてみて、それぞれが互いに繋がっていることに気づく。あるいは俺はひとつの小さな決心をしただけで、その結果、いくつかの出来事が起こったと言うべきか。俺はいつかこの年を、ひとつの決心といくつかの変化があった年として思い出すのかもしれない。</p>
<p>さよなら、2008 年!</p>
Pop Life: Life Without Buildings
2009-01-11T00:00:00Z
https://terkel.jp/archives/2009/01/pop-life-life-without-buildings/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/homesleephome2.jpg" />
</figure>
<p><a href="http://www.myspace.com/lifewithoutbuildingsuk" title="MySpace.com - Life Without Buildings">ライフ・ウィズアウト・ビルディングス</a> がプリンスの ‘Pop Life’ をカヴァーしてる音源を発見! モノはイタリーのレーベル <a href="http://www.homesleepmusic.com/">Homesleep</a> から 2001 年に出たコンピ盤 “<a href="http://www.amazon.co.jp/o/ASIN/B00006BC7G/terkel-22" title="Amazon.co.jp: Homesleephome.2: Cover Songs: Various Artists: 音楽">HomesleepHome 2: Cover Songs</a>” に収録されている。</p>
<p>内容はかなりストレートなカヴァーで、メロディから構成までほぼ原曲のまんま。これが意外なほどはまってて、まるで違和感がない。ほんとにこの曲が好きなんだろうなー、と好感の持てる仕上がり。ファンとしてはギターの空間系処理やバッキング・ヴォーカルの多重録音が新鮮で、なんだかうれしくなってしまった。</p>
<p>LWB というバンドについてはいずれ稿を改めてきっちり書きたいと思ってるんだけど、とりあえず情報共有まで。</p>
JavaScript と CSS を使った「このページを印刷」リンク
2009-01-13T00:00:00Z
https://terkel.jp/archives/2009/01/print-this-page-link-using-javascript-and-css/
<p>クリックするとブラウザの印刷ダイアログが立ち上がる、いわゆる「このページを印刷」リンク。マークアップはだいたいこんな感じになると思う:</p>
<pre><code class="language-html"><p class="print">
<a href="#" onclick="window.print(); return false;">このページを印刷</a>
</p>
</code></pre>
<p>でもこれ、JavaScript が無効の場合はどうなるだろう? そう、何も起こらない無意味なリンクになっちゃうよね。そこで、JavaScript と CSS を使ってひと工夫してみよう。</p>
<p>まずは JavaScript。例によって <a href="http://jquery.com/">jQuery</a> を読み込んだ上で、こんな風なスクリプトを記述:</p>
<pre><code class="language-javascript">$(function(){
$('body').addClass('js-enabled');
});
</code></pre>
<p>もちろんクラス名はなんでもよくて、<code>body</code> 要素になんらかの <code>class</code> 属性を付与できれば OK。つまり、JavaScript が有効であることの証しとして「しるし」をつけておくわけ。</p>
<p>そして最後に CSS:</p>
<pre><code class="language-css">p.print {
display: none;
}
.js-enabled p.print {
display: block;
}
</code></pre>
<p>すごく簡単なトリックなんだけど、要素をいったんまるごと消しといて、<code>js-enabled</code> クラスがある場合—つまり JavaScript が有効の場合のみ表示させるってわけ。この CSS を書き換えれば、たとえば今回のシチュエイションとは逆に、JavaScript が無効の場合にだけメッセージを見せる、なんてのも簡単。<a href="https://terkel.jp/demo/print-this-page-link-using-javascript-and-css.html">完成版デモ</a> を用意したのでチェックしてみて。</p>
<p>それに、このシンプルな JavaScript の有効判定はいろいろと応用ができそうだよね。だからもし「このページを印刷」リンクがなかったとしても、スクリプトを書くときはとりあえず <code>body</code> 要素に「しるし」をつけておく、ってのは悪いアイディアじゃないんじゃないかな。</p>
スクロールで背景画像が変化する (ように見える) トリック
2009-01-14T00:00:00Z
https://terkel.jp/archives/2009/01/scrolling-trick-with-background-images/
<p>CSS を使ったエフェクトで久々に楽しいのを発見! 説明するのが難しいので、下記ページのサンプルを (IE 6 以外のモダン・ブラウザで) チェックしてみてほしい。</p>
<ul>
<li><a href="http://www.askthecssguy.com/2009/01/mike_asks_the_css_guy_about_a.html">Mike asks the CSS Guy about a scrolling trick with background images (Ask the CSS Guy)</a></li>
</ul>
<p>これは思いつかなかったなー。垂直方向に並んだ要素にそれぞれ背景画像を用意して、<a href="http://www.w3.org/TR/CSS21/colors.html#propdef-background-attachment" title="Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification"><code>background-attachment</code></a> プロパティに <code>fixed</code> を指定、同じ位置に重ねるのがミソ。前述のとおり IE 6 には対応していないので、適宜ハックなどで対応を。</p>
jQuery 1.3、リリース!
2009-01-15T00:00:00Z
https://terkel.jp/archives/2009/01/jquery-1-3-released/
<p><a href="http://jquery.com/" title="jQuery: The Write Less, Do More, JavaScript Library">jQuery</a> の最新メイジャー・アップデイト、<a href="http://docs.jquery.com/Release:jQuery_1.3" title="Release:jQuery 1.3 - jQuery JavaScript Library">jQuery 1.3</a> がいよいよリリースされました! <a href="http://docs.jquery.com/Events/live" title="Events/live - jQuery JavaScript Library"><code>.live()</code></a> とか <a href="http://docs.jquery.com/Events/die" title="Events/die - jQuery JavaScript Library"><code>.die()</code></a> とか新しい要素もあるけど、全体的にかなり速くなったっぽいとこが売りっぽい。CSS セレクタ・エンジン <a href="http://sizzlejs.com/" title="Sizzle JavaScript Selector Library">Sizzle</a> の搭載や各種リライトが奏功している模様。ベンチマークを見てみると、セレクタの書き方の最適化メソッドもやや変わってきそう。ともあれ、明日は仕事そっちのけでチェックする構えです。</p>
<p>そうだ、書き忘れてた。お誕生日おめでとう、jQuery!</p>
スペースの幅
2009-02-09T00:00:00Z
https://terkel.jp/archives/2009/02/width-of-space/
<p>いわゆる「半角スペース」の幅って <code>font-size</code> の値に対してだいたいどのくらいの割合なの? ってのを調べる必要があったので、よく使う代表的な欧文フォントについてまとめてみた。どうやって調べたかというと、</p>
<pre><code class="language-html"><p><span>&nbsp;</span></p>
</code></pre>
<p>こんな感じのマークアップに、</p>
<pre><code class="language-css">p {
font-family: "Arial";
font-size: 1000px;
}
p span {
background-color: red;
}
</code></pre>
<p>というスタイルシートを当てる。ブラウザで表示させてみて、赤いスペースの幅を測って <code>font-size</code> の値で割れば、そのファミリーのスペース幅の相対値がおおよそ算出できるはず。</p>
<p>じゃあまずは Windows XP での結果から。</p>
<figure id="table-1">
<table>
<thead>
<tr>
<th>Font Family</th><th>Width of Space (em)</th>
</tr>
</thead>
<tbody>
<tr>
<th>Arial</th><td>0.278</td>
</tr>
<tr>
<th>Verdana</th><td>0.352</td>
</tr>
<tr>
<th>Georgia</th><td>0.241</td>
</tr>
<tr>
<th>Courier New</th><td>0.6</td>
</tr>
</tbody>
</table>
<figcaption>表1:Windows XP + Firefox 3.0</figcaption>
</figure>
<p>なんとなく直感的に 0.5 em あたりじゃね? と思っていたので、こうしてきっちり数字を出してみると面白い。とくに Georgia の細さとか。</p>
<p>次、Mac。僕が CSS を書くときに上記 Windows フォントとよく一緒に組み合わせるフォントをチョイスしてみた。</p>
<figure id="table-2">
<table>
<thead>
<tr>
<th>Font Family</th><th>Width of Space (em)</th>
</tr>
</thead>
<tbody>
<tr>
<th>Helvetica / Helvetica Neue</th><td>0.278</td>
</tr>
<tr>
<th>Lucida Grande</th><td>0.316</td>
</tr>
<tr>
<th>Hoefler Text</th><td>0.25</td>
</tr>
<tr>
<th>Monaco</th><td>0.6</td>
</tr>
</tbody>
</table>
<figcaption>表2:Mac OS X + Firefox 3.0</figcaption>
</figure>
<p>やっぱり似たフォントはスペースの幅も近い。なんか妙に安心した。</p>
<p>ひょっとすると同じ OS でもブラウザによってレンダリングが異なる可能性はあると思うけど、Windows XP の Firefox 3.0 と IE 7.0 でまったく同じ数値だったので、まあどのブラウザでもほぼ一緒だと思われる。</p>
jQuery と CSS を使った Apple 風パンくず
2009-02-14T00:00:00Z
https://terkel.jp/archives/2009/02/apple-like-breadcrumbs-using-jquery-and-css/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/apple-like-breadcrumbs.png" />
<figcaption>Fig 1: 「jQuery と CSS を使った Apple 風パンくず」完成図</figcaption>
</figure>
<p>パンくず (Breadcrumbs) ってその必要性に疑問を感じることの多い要素の筆頭だと思う。この案件で要るか、これ? みたいな。そんなわけだからあまり力を入れて作ったことがなかったんだけど、<a href="http://veerle.duoh.com/">Veerle’s blog</a> のパンくず作成チュートリアル <a href="http://veerle.duoh.com/blog/comments/simple_scalable_css_based_breadcrumbs/">Simple scalable CSS based breadcrumbs</a> を読んで、必要かどうかはとりあえず置いといて、どうせ置くならお洒落な方がいい、っていうか俺もクールなパンくず作る! と盛り上がってしまい、作ってみた。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/breadcrumbs-apple.png" />
<figcaption>Fig 2: Apple のパンくず。影響力大</figcaption>
</figure>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/breadcrumbs-delicious.png" />
<figcaption>Fig 3: Delicious のタグのリスト。妙に好き</figcaption>
</figure>
<p>目論んだイメージとしては <a href="http://www.apple.com/jp/">Apple</a> 風のルックスに <a href="http://delicious.com/">Delicious</a> のチェーン状に繋がったタグのリスト的なロールオーバー効果をプラスした感じ。もちろん、カスタマイズの余地を十分に残しつつ、できる限りシンプルなコードを目指した。</p>
<h2>1. マークアップ</h2>
<p>パンくずをどうマークアップするか、というのはよく議論される話題。ちなみに前述の Veerle’s blog では <code>ul</code>、Apple は <code>ol</code> だ。でも俺に言わせりゃんなもん <code>p</code> に決まってんだろ、である。パンくずってのはあくまでも「迷子にならないための道しるべ」であるべきだと思うから、なんというかこう「1 本につながった感じ」が欲しいんだよね。リスト形式だと 1 つ 1 つのパンくずが独立しちゃってる気がして、どうにも違和感を感じるというか。そういった意味では <code>ol</code> ってのはまあアリかなと思うけど、でも実際のところ横一列に並べる以外の見せ方ってなかなか考えづらいわけで、そうするとやっぱ <code>p</code> じゃね、てのが僕の考え方だけどどうだろう。</p>
<p>まあとにかく、ここではパンくず全体を <code>p</code> 要素でマークアップする。各リンク間を「>」 (<code>&gt;</code>) で区切って、「今ココ」は <code>em</code> で示す:</p>
<pre><code class="language-html"><p class="crumbs">
<a href="#">Home</a><span> &gt;
</span><a href="#">Archives</a><span> &gt;
</span><a href="#">2009</a><span> &gt;
</span><em>You Are Here!</em>
</p>
</code></pre>
<p>「>」はコントロールしやすくするため <code>span</code> で囲んでおく。このとき前後の要素との間にスペースを入れないように。マークアップは以上。次、スタイルシートいきます。</p>
<h2>2. スタイルシート</h2>
<pre><code class="language-css">p.crumbs {
font-family: "Lucida Grande", "Verdana", sans-serif;
font-size: 68.75%;
line-height: 3.0;
font-weight: bold;
background-color: #e0e0e0;
overflow: hidden;
}
</code></pre>
<p>まずは <code>p</code> を整形。<code>line-height</code> は Apple っぽくやや大きめに。だいたい 3 前後ぐらいがサマになると思う。<code>overflow</code> につては後述。次は <code>a</code> と <code>em</code> をまとめて指定:</p>
<pre><code class="language-css">p.crumbs a,
p.crumbs em {
padding: 1.0em 2.0em 1.0em 1.0em;
color: #404040;
background-color: #e0e0e0;
text-decoration: none;
font-style: normal;
}
p.crumbs a:hover {
color: #ffffff;
background-color: #808080;
}
</code></pre>
<p>まず <code>padding</code> を設定して領域を広げる。もし <code>p</code> の <code>line-height</code> を <code>3</code> にしたなら、<code>a</code> の上下 <code>padding</code> はそれぞれだいたい <code>1em</code>。もし上下に少しはみ出しても前述のとおり <code>p</code> の <code>overflow</code> を指定しとけば OK。また右だけ少し多めに取るのもポイント。</p>
<p>背景色は <code>p</code> と同じに。<code>a:hover</code> のデザインはここでは Delicious を意識しつつかなりざっくりとした反転パターンを採用したけど、実際はもう少し抑え気味のほうがおしゃれかな。</p>
<p>さて次はいよいよこのデザインのキモ、「>」部分にギミックを仕込む:</p>
<pre><code class="language-css">p.crumbs span {
padding: 1.0em 0;
margin-left: -1.5em;
color: #e0e0e0;
background: url(img/crumbs.png) no-repeat 100% 50%;
}
</code></pre>
<p>まず上下の <code>padding</code> に <code>a</code> と同じ値を指定。<code>margin-left</code> にマイナス値を指定し、直前の <code>a</code> 要素の上に重ねる。値の大きさはフォントによって調整が必要かも。また前景色を <code>a</code> の背景色と同じにして見えなくする。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/apple-like-breadcrumbs-bg1.png" />
<figcaption>Fig 4</figcaption>
</figure>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/apple-like-breadcrumbs-bg2.png" />
<figcaption>Fig 5</figcaption>
</figure>
<p>背景画像は、Fig 4 のように右向きの三角部分を透過させ、かつその境い目の部分にラインを入れたものを用意。文字サイズに対応すべくやや大きめに。GIF でもいいんだけど、IE6 への対応は別途考えるとして、ここはぜひ半透明のアルファチャネル PNG でいってみよう。ついでに Fig 5 のようなロールオーバー用も作っておく。</p>
<p>さて、ここまでのソースをブラウザで見てみると、ぱっと見たところは出来上がったけども、リンクにマウスの乗せると Fig 6 のようにイマイチな結果になるはずだ。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/breadcrumbs-unfinished.png" />
<figcaption>Fig 6: もう一息</figcaption>
</figure>
<p>ここで要求される挙動はどんなものだろうか? <code>a</code> が <code>:hover</code> 状態になったときに「直前の <code>span</code> の背景画像」と「直後の <code>span</code> の前景色」が変更できればいいよね。はい、<a href="http://jquery.com/">jQuery</a> の出番です。</p>
<h2>3. スクリプト</h2>
<pre><code class="language-html"><script type="text/javascript" src="js/jquery.js"></script>
</code></pre>
<p>HTML/XHTML の <code>head</code> で jQuery を読み込み、さらに以下のような JavaScript を加える:</p>
<pre><code class="language-javascript">$(function() {
$('p.crumbs a').hover(function() {
$(this).prev('span').addClass('prev');
$(this).next('span').addClass('next');
}, function() {
$('span.prev').removeClass('prev');
$('span.next').removeClass('next');
});
});
</code></pre>
<p><a href="http://docs.jquery.com/Events/hover" title="Events/hover - jQuery JavaScript Library"><code>hover()</code></a> イベントはその要素にマウスが乗ったときと外れたときに実行する関数を定義する。ここでは <code>a</code> にマウスが乗ったときに、<a href="http://docs.jquery.com/Traversing/prev" title="Traversing/prev - jQuery JavaScript Library"><code>prev()</code></a> でその直前の、<a href="http://docs.jquery.com/Traversing/next" title="Traversing/next - jQuery JavaScript Library"><code>next()</code></a> で直後の <code>span</code> を取得、それぞれに <code>class</code> を付与し、マウスが外れれば削除する、という関数。今回のマークアップ例でいうと、たとえば「2009」ってリンクにマウスが乗っている間、ソースは JavaScript エンジンによってこういうふうに生成されていることになる:</p>
<pre><code class="language-html"><p class="crumbs">
<a href="#">Home</a><span> &gt;
</span><a href="#">Archives</a><span class="prev"> &gt;
</span><a href="#">2009</a><span class="next"> &gt;
</span><em>You Are Here!</em>
</p>
</code></pre>
<p>あとはこの新たに生成された <code>class</code> のためのスタイルを書けばいい。</p>
<h2>4. 再びスタイルシート</h2>
<pre><code class="language-css">p.crumbs span.prev {
background-image: url(img/crumbs-h.png);
}
p.crumbs span.next {
color: #808080;
}
</code></pre>
<p>はい、出来上がり! <a href="https://terkel.jp/demo/apple-like-breadcrumbs.html" title="Demo: jQuery と CSS を使った Apple 風パンくず - terkel.jp">完成版のデモ</a> をどうぞ。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/apple-like-breadcrumbs.png" />
</figure>
<p>最後に背景画像について補足が 2 つ。まず、前もって読み込みを行っていないので最初にマウスを乗せたときに「ちらつき」が発生する。なんか対策したいところ。例えば <code>p</code> 要素あたりに持たせてしまっても良いかも:</p>
<pre><code class="language-css">p.crumbs {
...
background: #e0e0e0 url(img/crumbs-h.png) no-repeat -9999px -9999px;
...
}
</code></pre>
<p>もうひとつ、IE6 がアルファチャネル PNG に対応していない件について。<a href="https://terkel.jp/demo/apple-like-breadcrumbs.html" title="Demo: jQuery と CSS を使った Apple 風パンくず - terkel.jp">デモ</a> では CSS のハックで IE6 のみに代替の透過 GIF をあてがってるけど、もちろん適当な JavaScript ライブラリかなんかを使っても良い。というかその方がキレイだし。ハッピィ・ヴァレンタイン!</p>
お誕生日おめでとう、World Wide Web!
2009-03-13T00:00:00Z
https://terkel.jp/archives/2009/03/happy-birthday-world-wide-web/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/www20.png" />
</figure>
<p>20 年前の今日、世界を永遠に変える出来事が起こった—</p>
<blockquote cite="http://www.kanzaki.com/works/2001/pub/ua-history.html">
<p>1989 年 3 月、ティム・バーナーズ=リーは <a href="http://www.w3.org/History/1989/proposal.html" title="The original proposal of the WWW, HTMLized">Information Management: A Proposal</a> と題するペーパーを <abbr title="Conseil Européen pour la Recherche Nucléaire">CERN</abbr> の関係者に配布した。ウェブの歴史の第一歩が、静かに踏み出されたのだ。この提案を目に見える形にするためのハイパーテキスト処理プログラム、すなわち最初のウェブ・ブラウザは、翌 1990 年のクリスマスまでには完成する。</p>
</blockquote>
<p class="Credit"><small>(<a href="http://www.kanzaki.com/works/2001/pub/ua-history.html">ウェブ ブラウザ小史 2001 - The Web KANZAKI</a>)</small></p>
<p>20 年後の自分がこんなにも夢中になるものが生まれたというのに、当時まだ高校生だった僕はこの小さな大事件をまるで知らなかったよ。お誕生日おめでとう、World Wide Web!</p>
チェック/ペケ
2009-03-28T00:00:00Z
https://terkel.jp/archives/2009/03/tick-and-x/
<p>HTML/XHTML で <a href="http://ja.wikipedia.org/wiki/%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%83%9E%E3%83%BC%E3%82%AF" title="チェックマーク - Wikipedia">チェックマーク</a> (<a href="http://en.wikipedia.org/wiki/Tick_(checkmark)" title="Tick (checkmark) - Wikipedia, the free encyclopedia">Tick</a>) や <a href="http://ja.wikipedia.org/wiki/%C3%97" title="× - Wikipedia">ペケ</a> (<a href="http://en.wikipedia.org/wiki/X_mark" title="X mark - Wikipedia, the free encyclopedia">X mark</a>) を表示させるには以下の文字参照が使える。</p>
<figure>
<table>
<thead>
<tr><th></th><th>数値文字参照</th><th>名称</th></tr>
</thead>
<tbody>
<tr><th><span>✓</span></th><td><code>&#10003;</code></td><td>CHECK MARK (tick)</td></tr>
<tr><th><span>✔</span></th><td><code>&#10004;</code></td><td>HEAVY CHECK MARK (bold tick)</td></tr>
<tr><th><span>✗</span></th><td><code>&#10007;</code></td><td>BALLOT X (cross)</td></tr>
<tr><th><span>✘</span></th><td><code>&#10008;</code></td><td>HEAVY BALLOT X (bold cross)</td></tr>
</tbody>
</table>
</figure>
<p>しかし IE6 では文字化けすることが多いようなので、CSS で Unicode フォントを指定するといいみたい。</p>
<pre><code class="language-html"><!-- HTML/XHTML -->
... <span class="unicode">&#10004;</span> ...
</code></pre>
<pre><code class="language-css">/* CSS */
.unicode {
font-family: "Arial Unicode MS", "Microsoft Sans Serif", sans-serif;
}
</code></pre>
インライン要素に背景画像を指定する
2009-03-29T00:00:00Z
https://terkel.jp/archives/2009/03/inline-elements-with-background-image/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/inline-elements-with-bg-s.png" />
<figcaption>Fig 1: インライン要素に背景画像を指定</figcaption>
</figure>
<p>CSS でインライン要素に背景画像を指定する場合、IE6 と IE7 では致命的なバグがあるので注意。たとえば Fig 1 のように、パラグラフ中のハイパーリンクにアイコンを表示させたいとする。となると CSS はこんな感じになるだろう:</p>
<pre><code class="language-css">a.pdf {
padding-left: 20px;
background: url(/img/pdf.png) no-repeat 0 50%;
}
a.external {
padding-right: 20px;
background: url(/img/external.png) no-repeat 100% 50%;
}
</code></pre>
<p>すべてのモダン・ブラウザで Fig 1 のようなレンダリング結果が得られるが、背景画像を指定したインライン要素が改行して複数行にわたる場合、IE6/7 は Fig 2 のようにしくじる。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/inline-elements-with-bg-f.png" />
<figcaption>Fig 2: IE6/7 では改行を含むインライン要素で背景画像の表示位置がずれてしまう</figcaption>
</figure>
<p>この回避策が <a href="http://blog.cgfm.jp/garyu/archives/142">IE対策: 改行される可能性のあるインライン要素に背景画像を指定しない。- 我流天性 - がらくた屋</a> で紹介されている。パディングと背景画像を該当のインライン要素には指定せず、かわりにその内側に仕込んだ空の <code>span</code> 要素に持たせるメソッドだ。</p>
<pre><code class="language-html">... <a href="..." class="pdf"><span>&nbsp;</span>テキスト</a> ...
</code></pre>
<pre><code class="language-css">a.pdf span {
padding-left: 20px;
margin-right: -0.3em;
background: url(/img/pdf.png) no-repeat 0 50%;
}
</code></pre>
<p>空の <code>span</code> といっても、上記のように <code>&nbsp;</code> を入れないとうまくいかない。ちなみに負のマージンはこの余分な <code>&nbsp;</code> を相殺するためのもの。</p>
<p>これで IE6/7 でも Fig 1 のようにレンダリングされる。とはいえこんな無駄なマークアップをいちいち書くのはちょっとうんざりだし、そもそも IE6/7 以外のモダン・ブラウザには不要だし。というわけで、もう少し冴えたやり方を考えてみた。</p>
<p>まず、例によって <a href="http://jquery.com/" title="jQuery: The Write Less, Do More, JavaScript Library">jQuery</a> の力を借りる:</p>
<pre><code class="language-html"><script type="text/javascript" src="/js/jquery.js"></script>
</code></pre>
<p>次に、JavaScript ファイルに以下のプラグインを用意:</p>
<pre><code class="language-javascript">$.fn.extend({
inlineBgFix: function() {
if ($.browser.msie && $.browser.version < 8.0) {
$(this)
.addClass('inline-bg-fix')
.prepend('<span class="bg-l">&nbsp;</span>')
.append('<span class="bg-r">&nbsp;</span>');
}
}
});
</code></pre>
<p>あとは必要に応じて上記の <code>inlineBgFix()</code> メソッドを呼び出す。例えば <code>pdf</code> という <code>class</code> を持つ <code>a</code> 要素に背景画像を適用するなら:</p>
<pre><code class="language-javascript">$(function() {
$('a.pdf').inlineBgFix();
});
</code></pre>
<p>この結果、バージョン 8 未満の IE では以下のマークアップが生成される:</p>
<pre><code class="language-html"><a href="..." class="pdf inline-bg-fix">
<span class="bg-l">テキスト<span class="bg-r">
</a>
</code></pre>
<p>そして CSS。まず IE6/7 用の記述から。「本来の」要素に指定されるパディングと背景画像を打ち消し、余分に挿入されたスペースを相殺しておく。なお <a href="https://terkel.jp/archives/2009/02/width-of-space/" title="スペースの幅 - terkel.jp">スペースの幅はフォントによって異なる</a> ので調整のこと:</p>
<pre><code class="language-css">.inline-bg-fix {
padding: 0 !important;
background: none !important;
}
.inline-bg-fix .bg-l {
margin-right: -0.3em;
}
.inline-bg-fix .bg-r {
margin-left: -0.3em;
}
</code></pre>
<p>最後に、パディングと背景画像をまっとうなブラウザ用と IE6/7 用と一緒に指定。以下は要素の左側に配置する場合の例:</p>
<pre><code class="language-css">a.pdf,
a.pdf .bg-l {
padding-left: 20px;
background: url(/img/pdf.png) no-repeat 0 50%;
}
</code></pre>
<p>面倒だけど、とりあえずはこれでうまくいく。IE8 では修正されているのがせめてもの救い。</p>
link か @import か
2009-04-10T00:00:00Z
https://terkel.jp/archives/2009/04/link-or-import/
<blockquote cite="http://www.stevesouders.com/blog/2009/04/09/dont-use-import/" lang="en">
<p>In Chapter 5 of High Performance Web Sites, I briefly mention that @import has a negative impact on web page performance. I dug into this deeper for my talk at <a href="http://www.web2expo.com/webexsf2009/public/schedule/detail/5889" title="Even Faster Web Sites: Web 2.0 Expo San Francisco 2009 - Co-produced by TechWeb & O'Reilly Conferences, March 31 - April 03, 2009, San Francisco, CA">Web 2.0 Expo</a>, creating several test pages and HTTP waterfall charts, all shown below. The bottomline is: use LINK instead of @import if you want stylesheets to download in parallel resulting in a faster page.</p>
</blockquote>
<p class="Credit"><small><a href="http://www.stevesouders.com/blog/2009/04/09/dont-use-import/">High Performance Web Sites :: don’t use @import</a></small></p>
<p>『<a href="http://www.amazon.co.jp/o/ASIN/487311361X/terkel-22">ハイパフォーマンス Web サイト — 高速サイトを実現する 14 のルール</a>』の著者、<a href="http://stevesouders.com/" title="Steve Souders - High Performance Web Sites">Steve Souders</a> 氏のブログより。HTML ドキュメントに CSS ファイルをインクルードする際、<code>link</code> 要素と @import ルールをどう組み合わせるのが速いか、という話。上記の引用もとでは様々なパターンでのパフォーマンス実験の結果が紹介されている。ものすごくざっくりとまとめちゃうと、@import よか <code>link</code> のが速いよ、が結論。</p>
<p>CSS ファイルをどう分割するかってのはけっこう悩むもの。たとえば、この宣言は <code>layout.css</code> と <code>modules.css</code> のどちらに書くべきか、とか、そもそもどこまで細かく分割すべきか、とか。その結果、あの宣言ってどこに書いたっけ、とか。でもインクルードの方法でパフォーマンスに違いが出るってのは意識したことなかったなー、と反省。</p>
<p>ていうかパフォーマンスを考えるなら、<code>link</code> か @import かっていうより、まずは CSS ファイルの数を減らすことが先だよな。あとは保守性との兼ね合いで、どこまで分割するかを決めればいい。</p>
<p>つまり、CSS ファイルは可能な限り分割せず、かつ @import ではなく <code>link</code> でインクルードすべし、と。そうすれば分割についての悩みも減るうえ、サイトのパフォーマンスも向上する、はず。</p>
小学校 8 年生
2009-04-11T00:00:00Z
https://terkel.jp/archives/2009/04/8th-grade-of-primary-school/
<p>僕たちは高校 3 年生と小学校 6 年生を同じ教室に集めて、同じ教科書を使って授業をしている。まずみんなに教科書どおりの説明をするけど、当然ながら小学生の子たちは正しく理解できない。僕たちは彼らの机まで行き、説明してやらなければならない。「あのね、ここはわかりやすく言うとね…」</p>
<pre><code class="language-css">body {
font-size: 10px;
}
* html body {
font-size: 62.5%;
}
</code></pre>
<p>この見慣れた光景に高校生たちは心底うんざりしている。彼らは早く次のページに進み、授業を終わらせたい。その気持ちはふたとおりの教え方をしなきゃいけない僕たちも同じ。でも机の半数以上を占領している小学生を無視するのはなかなか難しいんだ。</p>
<p>しかしついに、この小学生のうちの何人かが卒業することになった。これで少しはましな授業ができると思った。ところが。</p>
<pre><code class="language-css">body {
font-size: 10px;
}
* html body {
font-size: 62.5%;
}
*:first-child+html body {
font-size: 62.5%;
}
</code></pre>
<p>小学校 6 年生のうち半数は留年。残り半数も卒業ではなく、なんと小学校 7 年生という新しい学年を作って進級してしまった。この新 7 年生は 6 年生に比べればまだ理解力はあるけど、でもやっぱり小学生だから、高校生と同じ授業を受けるのは難しかった。つまり僕たちは 7 年生のための新しい教え方を考案しなきゃならなかった。</p>
<p>この時点で、勘のいい教師はうすうす感づいていたのかもしれない。そしてあるいは新たな授業法を模索しはじめたのだろう。でも僕は楽天家だった。あの子たちもいずれは卒業していくから、それまでの辛抱。そう考えていた。</p>
<p>そして、春。別れの季節。小学校 6 年生と 7 年生の何人かは残念ながら留年が決まっていたけど、それは予想できたことだった。でも何人かは今度こそ卒業してくれるだろう。そう、僕は楽天家だった。</p>
<pre><code class="language-css">body {
font-size: 10px;
}
* html body {
font-size: 62.5%;
}
*:first-child+html body {
font-size: 62.5%;
}
?!*@last-childくぁwせdrftgyふじこbody {
font-size: 62.5%;
}
</code></pre>
<p>最後の教え方はでたらめなので、誰にも理解できません、念のため。でもでたらめを教えたくもなる。まさかの小学校 8 年生。悪夢以外のなにものでもない。にぶい僕でもついに気づく。彼らは卒業するつもりなどないのだ。おそらく彼らのうち何人かは何食わぬ顔で 9 年生に進級し、何人かは 6 年生のまま。いずれにせよ教室に居座り続けるだろう。</p>
<p>これでは永遠に授業が終わらない。こんな効率の悪いことを続けていては僕たちのからだが持たないし、授業をしっかり理解してくれている高校生の子たちにも申し訳ない。そう、ついに新しい段階に進むべきときが来たのだ。</p>
<pre><code class="language-html"><head>
...
<link rel="stylesheet" type="text/css" href="common.css" />
<!--[if IE]>
<link rel="stylesheet" type="text/css" href="ie.css" />
<![endif]-->
...
</head>
</code></pre>
<pre><code class="language-css">/* common.css */
body {
font-size: 10px;
}
</code></pre>
<pre><code class="language-css">/* ie.css */
body {
font-size: 62.5%;
}
</code></pre>
<p>これが、現時点で僕がベストと考えるアプローチ。</p>
<p>小学生のために授業を中断するのはもうやめだ。彼らが理解できようとできなかろうと、まずはきっちりと教科書どおりに授業を終わらせる。高校生はここで帰ってよし。そして放課後、授業についてこられない小学生を集めて居残りの補習。ちなみにこの補習用の資料は学年別にそれぞれ用意することも可能だけど、きりがないのでほどほどにしておく。</p>
<p>時間と労力を割かなければいけないことに変わりはないけど、本来の授業と明確に分離することの意味は小さくない。とりあえず、高校生を無駄に拘束せずに済むだけでも大きな前進だ。</p>
空がまた暗くなる
2009-05-03T00:00:00Z
https://terkel.jp/archives/2009/05/rip-kiyoshiro-imawano/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/baby-a-go-go.jpg" />
</figure>
<p>RCサクセションの最後のアルバム『<a href="http://www.amazon.co.jp/o/ASIN/B000BDJ6CO/terkel-22" title="Amazon.co.jp: Baby a Go Go: RCサクセション: 音楽">Baby a Go Go</a>』がリリースされたのは1990年、僕が高校生のときだった。当時やっていたバンドのドラマーから借りて聴いたんだったと思う。そのときはかなり気に入ったんだけど、ここ十数年はまったく聴いていなかった。すっかり忘れていたというか。それが先日、友人と飲んでいてこのアルバムの話になり、懐かしさから久々に購入して聴いてみることにしたのだ。</p>
<p>そして僕はそこに収められた「空がまた暗くなる」に戦慄することになる。高校生のときはまるでわからなかった。こんなにも恐ろしい歌を、僕はほかに知らない。</p>
<blockquote>
<p>おとなだろ 勇気をだせよ<br />
おとなだろ 知ってるはずさ<br />
悲しいときも 涙なんか<br />
誰にも 見せられない<br />
<br />
おとなだろ 勇気をだせよ<br />
おとなだろ 笑っていても<br />
暗く曇った この空を<br />
かくすことなどできない<br />
<br />
ああ 子供の頃のように<br />
さあ 勇気を出すのさ<br />
きっと 道に迷わずに<br />
君の家にたどりつけるさ<br />
<br />
おとなだろ 勇気をだせよ<br />
おとなだろ 知ってることが<br />
誰にも言えないことばかりじゃ<br />
空がまた 暗くなる</p>
</blockquote>
<p class="Credit"><small>(RCサクセション「空がまた暗くなる」)</small></p>
<p>空は暗く曇っている。僕たちにはなすすべもない。ただただ泣きじゃくる者がいる。笑ってやり過ごそうとする者もいる。しかし空が明るさを取り戻すことはないし、もはやそのことを隠すこともできない。どこへも行こうとしない黒い雲はいよいよ厚くたれこめてゆく。</p>
<p>僕たちは道に迷っている。もうおとなになったはずなのに、家へ帰れなくなってしまっている。そして家にたどりつくために今、おとなである僕たちに子供のような勇気が求められている。そんな子供じみたものを手放すのと引き換えに、僕たちはおとなになったはずなのに。</p>
<p>彼は知っている。僕たちがこの暗い空におびえて泣いていること、すべてを笑ってごまかそうとしていること、勇気を失って道に迷っていること、そして、後ろめたい思いを胸に抱えたままでいること。</p>
<p>しかし彼は何も教えてくれない。彼は僕たちに泣くことも笑うことも禁じ、困難な矛盾を強い、誰にも知られていなかったはずの秘密を暴き、そして暗い空の下に僕たちを放り出したままどこかへ行ってしまう。どうすればこの空が再び明るくなるのか、その答えはついに示されない。ただ、このままではこの空がまた暗くなるばかりだと、彼はそう告げるのみだ。</p>
<p>僕たちはこんなにも恐ろしい歌を書く詩人を永遠に失ってしまったのだ。<a href="http://www.kiyoshiro.co.jp/" title="地味変">忌野清志郎</a>の冥福を祈る。</p>
僕が HTML 4.01 を選ぶ理由
2009-05-05T00:00:00Z
https://terkel.jp/archives/2009/05/why-i-choose-html-401/
<p>このサイトの文書型を XHTML 1.0 から HTML 4.01 に変更しました。</p>
<p>その理由を説明するために、まずはそもそも XHTML だった理由から振り返ってみます。結論から言ってしまえば、まあその、「とりあえず」、ですね。僕が Web デザインの勉強を始めたのが 2006 年初頭で、そのときに参考書として選んだのが 2005 年 7 月に初版が発行された『<a href="http://www.amazon.co.jp/gp/product/4798010928?ie=UTF8&tag=terkel-22&linkCode=as2&camp=247&creative=7399&creativeASIN=4798010928">Web 標準の教科書 — XHTML と CSSでつくる “正しい” Web サイト</a>』。なんとなく雰囲気が伝わるといいんですけど、いわゆる「Web 標準の時代」とでも言うべき時代に僕はこの世界に入ったわけです。当時の空気としては「これからは HTML よか XHTML ですよ」という流れがほとんど不可逆的なものとして捉えられていたと思います。以来 3 年間、僕は個人でも仕事でもいくつものドキュメントをマークアップしてきましたが、「これからは XHTML」っていう考えに大した疑問も抱かずに、「とりあえず XHTML」でやってきたわけです。</p>
<p>でもそろそろ時代が「これからは XHTML」ってのとはちょっと違うとこに来てるなー、とのん気な僕がようやく感じ始めたのがこの春。HTML 5 が盛り上がりを見せる反面、XHTML 2.0 はどうも「来ない」っぽいと。例えば <a href="http://www.aneventapart.com/" title="An Event Apart: The Design Conference For People Who Make Web Sites">An Event Apart</a> や <a href="http://www.apple.com/jp/safari/" title="アップル - Safari - Safari 4の登場です。 - 目の前にひろがる新しいウェブの世界。">Safari 4</a> なんかのサイトが HTML 5 で書かれているの見て、「あ、もう始まってるんだ…」と思ったりとか。<a href="http://web.g.hatena.ne.jp/vantguarde/20090417/1239977465" title="「くたばれ『Web標準』」って何よ? - vantguarde - web:g">「くたばれ『Web標準』」って何よ?</a> や <a href="http://mezzoblue.com/archives/2009/04/20/switched/" title="mezzoblue § Switched">Dave Shae が HTML にスイッチすることを表明した記事</a> とかも刺激になりました。</p>
<p>だったら一気に HTML 5 で、というチョイスももちろんあったわけです。特にこのサイトのように Web のフロントエンド技術を話題にするようなサイトならその意義もおおいにあるでしょう。でもやっぱりまだそこまではちょっと、というのが本音です。独立したページでいろいろ実験するとかはやっていきたいですけど。</p>
<p>となると、すでに XHTML で構築しちゃったんだから、HTML 5 が固まるのを待ってリブートすれば? というのもまたひとつの選択肢でしょう。実際、僕も仕事で運用している XHTML サイトをいちいち HTML に書き換えるなんてことは提案しないでしょうし。僕がこのサイトを HTML 4.01 に書き換えたのは、もちろん HTML 5 に備えてではあるんですが、それよか大きいのが、今まで感じていたジレンマを解消できると思ったからです。</p>
<p>XHTML を書くことには常にジレンマがつきまといます。XML 宣言のジレンマ—ほんとは書くべきなんだろうけど、書くと IE で面倒なことになるからとりあえず省略—とか、メディアタイプのジレンマ—ほんとは application/xhtml+xml が推奨されてるらしいけど、やっぱり IE で上手くいかないのでとりあえず text/html—とか。もちろん、ここらへんのジレンマをちゃんと受け止めるというか、例えば IE の Quirks モードにきっちりつきあったり、コンテント・ネゴシエーションしたりってアプローチもあります。ありますが、じゃあそこまでして XHTML でありたいか、つまり XML でなければならいないかというと、少なくとも現時点でのこのサイトはその必要がまるでないわけです。僕が今まで仕事で書いてきた XHTML もそう。</p>
<p>もうひとつ、XHTML を選ぶ理由としてよく言われる、XHTML の「X」の部分、つまり拡張性について。これってけっこうクセモノというか、上手いとこ突くなあというか、ひっかかりやすい罠というか、なんかそんな風に感じてます。というのも、XHTML って HTML が書ければほとんど書けちゃう—つまり学習コストが低い。コストがほとんど変わらないの加えて「なんならオプションでいろいろと追加できますよ」とか言われれば、そりゃ「じゃあ、とりあえずこっちにしとこうか」とかなりません? なりますよね? だって、必要がなければ使わなくたっていいわけだから。でもさ、その拡張性があとから必要になったこと、ありますか? 少なくとも僕はこの 3 年間で一度もなかった。MathML? XSLT? んー、とりあえず、今はいいや。でしょ?</p>
<p>これってレンタルヴィデオ屋の会員証にクレジットカード機能がついてるみたいなもんでしょ、言ってみれば。会費は変わらず、今までどおりヴィデオは借りられて、しかもお買い物もできちゃう、みたいな。ただヴィデオを借りるばかりでクレジットカードを使わないでいると、この機能の存在自体を忘れがちだけど、でもこの余分のおかげでカード会社との契約書とかの煩雑な手続きが発生するし、ひょっとするとなんらかのトラブルが起こる可能性だってあるわけで。やっぱタダじゃ済まないというか。じゃあもう面倒だからこの際ハッキリさせようと。俺はただヴィデオが借りたいだけなんだと。もしクレジットカードが必要になったら、そんときは改めてお願いするわ、と。</p>
<p>まあだいたいこんなことを考えて、XHTML から HTML への切り替えに踏み切った次第です。やってみて、「マークアップはまず文書型の選択から」という当たり前すぎることを再認識できたのがすごく大きな収穫。いかに今までなにも考えずにマークアップしてきたか、ということです。だからこれから、やっぱ XHTML 1.1 で、とか、ためしに HTML 5 にしてみる、とかいう発想を持てるようになったと思う。まあ当面このサイトでは、HTML 5 に備えた HTML 4.01 の設計、みたいなのを模索してみたいと思います。</p>
jQuery Counter Plugin
2009-06-08T00:00:00Z
https://terkel.jp/archives/2009/06/jquery-counter-plugin/
<p>CSS 2.1 の <a href="http://www.w3.org/TR/CSS2/generate.html#counters">Counter 構文</a> や CSS 3 の <a href="http://www.w3.org/TR/css3-lists/" title="CSS3 module: Lists">Lists モジュール</a> のような、任意の要素に色んなタイプの連番を自動的にふる jQuery プラグイン、<a href="https://terkel.jp/js/jquery.counter.js">jQuery Counter Plugin</a> を書いた。<code>ol</code> 要素ほか順列リストのマーカー部分を柔軟にコントロールしたい、というのが主な目的だけど、個人的な裏テーマは JavaScript の配列と正規表現の勉強。</p>
<h2>Demo</h2>
<ul>
<li><a href="https://terkel.jp/demo/jquery-counter-plugin.html">Demo: jQuery Counter Plugin</a></li>
</ul>
<h2>Download</h2>
<ul>
<li><a href="https://terkel.jp/js/jquery.counter.js">jQuery Counter Plugin</a></li>
</ul>
<h2>Usage</h2>
<p>例えば以下のようなごく普通の <code>ol</code> 要素に適用する場合。</p>
<pre><code class="language-html"><ol>
<li>List Item</li>
<li>List Item</li>
<li>List Item</li>
</ol>
</code></pre>
<p>プラグインを <a href="http://jquery.com/">jQuery</a> と一緒に読み込んで、<code>setCounter()</code> で呼び出す:</p>
<pre><code class="language-html"><script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="jquery.counter.js"></script>
<script type="text/javascript">
$(function() {
$('ol').setCounter();
});
</script>
</code></pre>
<p>その結果、以下のように <code>li</code> 要素の子要素としてマーカーが生成される。同時に <code>display</code> プロパティの値が <code>list-item</code> である場合はデフォルトのマーカーが非表示に:</p>
<pre><code class="language-css"><ol style="list-style-type: none;">
<li><span class="marker"><span class="marker-body">1</span>. </span>List Item</li>
<li><span class="marker"><span class="marker-body">2</span>. </span>List Item</li>
<li><span class="marker"><span class="marker-body">3</span>. </span>List Item</li>
</ol>
</code></pre>
<p>これだけだと普通の <code>ol</code> と変わらないようにも見えるけど、マーカー部分を装飾できたり、<code>display</code> プロパティでインライン化してもマーカーが消えなかったりとか、CSS で柔軟なコントロールが可能になるのは地味に便利、と自負。</p>
<p>そのほか、オプションを指定すれば <code>list-style-type: cjk-heavenly-stem</code> とか <code>content: "[" counter(section, upper-roman) "] ";</code> 的なことも可能。</p>
<h2>Options</h2>
<p>オプションはオブジェクトで指定。</p>
<pre><code class="language-javascript">$(function() {
$('dl').setCounter({
selector: 'dt',
start: 8,
markerType: 'あ',
markerLeft: '(',
markerRight: ') '
});
});
</script>
</code></pre>
<dl>
<dt><code>selector</code></dt>
<dd>番号をふる子要素。この値を jQuery の <a href="http://docs.jquery.com/Traversing/children" title="Traversing/children - jQuery JavaScript Library"><code>children()</code></a> に渡すので、指定できるのは直接の子要素のみ。デフォルトでは空白なので、<code>ol</code> なら <code>li</code> に番号がふられる。たとえば <code>dl</code> 要素のうち <code>dt</code> 要素にだけ番号を付与したい場合なら、<code>$('dl').setCounter({ selector: 'dt' });</code> となる。</dd>
<dt><code>start</code></dt>
<dd>開始する番号。デフォルトは <code>1</code>。</dd>
<dt><code>markerType</code></dt>
<dd>CSS の <a href="http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-type" title="Generated content, automatic numbering, and lists"><code>list-style-type</code></a> にあたる部分で、デフォルトではアラビア数字 (1, 2, 3…)。以下のキーワードを指定できる。</dd>
<dd>
<table>
<thead>
<tr><th>値</th><th>出力例</th><th>説明</th></tr>
</thead>
<tbody>
<tr><th><code>01</code></th><td>01, 02, 03 … 09, 10, 11 …</td><td>アラビア数字の 0 詰め (2 桁)。</td></tr>
<tr><th><code>001</code></th><td>001, 002, 003 … 099, 100, 101 …</td><td>アラビア数字の 0 詰め (3 桁)。</td></tr>
<tr><th><code>0001</code></th><td>0001, 0002, 0003 … 0999, 1000, 1001 …</td><td>アラビア数字の 0 詰め (4 桁)。</td></tr>
<tr><th><code>a</code></th><td>a, b, c … x, y, z</td><td>ラテン文字 (小文字)。</td></tr>
<tr><th><code>A</code></th><td>A, B, C … X, Y, Z</td><td>ラテン文字 (大文字)。</td></tr>
<tr><th><code>i</code></th><td>i, ii, iii … ix, x, xi …</td><td><a href="http://ja.wikipedia.org/wiki/%E3%83%AD%E3%83%BC%E3%83%9E%E6%95%B0%E5%AD%97" title="ローマ数字 - Wikipedia">ローマ数字</a> (小文字)。3999 まで。</td></tr>
<tr><th><code>I</code></th><td>I, II, III … IX, X, XI …</td><td>ローマ数字 (大文字)。3999 まで。</td></tr>
<tr><th><code>A</code></th><td>A, B, C … X, Y, Z</td><td>ラテン文字 (大文字)。</td></tr>
<tr><th><code>あ</code></th><td>あ、い、う … わ、を、ん</td><td>平仮名のあいうえお。</td></tr>
<tr><th><code>ア</code></th><td>ア、イ、ウ … ワ、ヲ、ン</td><td>片仮名のアイウエオ。</td></tr>
<tr><th><code>い</code></th><td>い、ろ、は … せ、す、ん</td><td>平仮名のいろは。</td></tr>
<tr><th><code>イ</code></th><td>イ、ロ、ハ … セ、ス、ン</td><td>片仮名のイロハ。</td></tr>
<tr><th><code>子</code></th><td>子、丑、寅 … 酉、戌、亥</td><td><a href="http://ja.wikipedia.org/wiki/%E5%8D%81%E4%BA%8C%E6%94%AF" title="十二支 - Wikipedia">十二支</a>。全 12 文字。</td></tr>
<tr><th><code>甲</code></th><td>甲、乙、丙 … 辛、壬、癸</td><td><a href="http://ja.wikipedia.org/wiki/%E5%8D%81%E5%B9%B2" title="十干 - Wikipedia">十干</a>。全 10 文字。</td></tr>
<tr><th><code>一</code></th><td>一、二、三 … 九、十、十一 …</td><td><a href="http://ja.wikipedia.org/wiki/%E6%BC%A2%E6%95%B0%E5%AD%97" title="漢数字 - Wikipedia">漢数字</a>。9999 まで。</td></tr>
<tr><th><code>壱</code></th><td>壱、弐、参 … 玖、壱拾、壱拾壱 …</td><td>漢数字 (<a href="http://ja.wikipedia.org/wiki/%E5%A4%A7%E5%AD%97_(%E6%95%B0%E5%AD%97)" title="大字 (数字) - Wikipedia">大字</a>)。9999 まで。</td></tr>
<tr><th><code>〇</code></th><td>一、二、三 … 九、一〇、一一 …</td><td>漢数字 (<a href="http://ja.wikipedia.org/wiki/%E4%BD%8D%E5%8F%96%E3%82%8A%E8%A8%98%E6%95%B0%E6%B3%95" title="位取り記数法 - Wikipedia">位取り記数法</a>)。9999 まで。</td></tr>
</tbody>
</table>
</dd>
<dt><code>markerLeft</code></dt>
<dd>マーカーの左側に記号などを挿入できる。デフォルトではからっぽ。たとえば <code>{markerType: '壱', markerLeft: '其の'}</code> で「其の壱、其の弐、其の参 …」など。</dd>
<dt><code>markerRight</code></dt>
<dd>同じくマーカーの右側に挿入する記号。デフォルトは <code>'. '</code> で、<code>ol</code> 要素のよくある感じになる。</dd>
</dl>
<h2>ToDo</h2>
<p>漢数字やローマ数字の位の計算で挫折しかけたけど、なんとか思っていたものができたのでとりあえずは満足。でもまだまだ改良の余地があるはずなので、課題をいくつかリストアップしておく。</p>
<ul>
<li><code>switch</code> 文と if 文の使い分け方がスマートじゃない気が。とくに 0 詰めのあたりとか、妙にうざい。</li>
<li>jQuery プラグインでありながらあまり jQuery っぽくない気が。なにかものすごく便利なメソッドを忘れてるような。</li>
<li>漢数字の 10000 以上に対応すべきか? 桁の計算式が面倒くさそうってのもあるけど、「那由他」とか「不可思議」とか中二っぽくてちょっと…</li>
<li>デモ作るのって難しいなー…</li>
</ul>
非置換要素の幅を明示せずにフロート
2009-06-28T00:00:00Z
https://terkel.jp/archives/2009/06/floating-nonreplaced-elements-without-explicit-width/
<p>CSS で非置換要素 (<code>img</code> とか <code>object</code>とかフォームのコントロール系とか以外、ってことね) に <code>float</code> プロパティを指定する場合、同時に幅を具体的な数値で明示しなければならない、とよく言われる。さもなければ幅が 0 として扱われちゃうよと。</p>
<p>でもその仕様は <a href="http://www.w3.org/TR/2008/REC-CSS2-20080411/" title="Cascading Style Sheets, level 2">CSS 2</a> での話で、<a href="http://www.w3.org/TR/CSS21/" title="Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification">CSS 2.1</a> にそのような記述はない。そのかわり、幅を明示せずに非置換要素をフロートした場合、その幅は内容に合わせて縮む (shrink-to-fit) とされている。</p>
<blockquote cite="http://www.w3.org/TR/CSS21/visudet.html#float-width" lang="en">
<p>If ‘margin-left’, or ‘margin-right’ are computed as ‘auto’, their used value is ‘0’.</p>
<p>If ‘width’ is computed as ‘auto’, the used value is the “shrink-to-fit” width.</p>
<p>Calculation of the shrink-to-fit width is similar to calculating the width of a table cell using the automatic table layout algorithm. Roughly: calculate the preferred width by formatting the content without breaking lines other than where explicit line breaks occur, and also calculate the preferred <em>minimum</em> width, e.g., by trying all possible line breaks. CSS 2.1 does not define the exact algorithm. Thirdly, find the <em>available width</em>: in this case, this is the width of the containing block minus the used values of ‘margin-left’, ‘border-left-width’, ‘padding-left’, ‘padding-right’, ‘border-right-width’, ‘margin-right’, and the widths of any relevant scroll bars.</p>
<p>Then the shrink-to-fit width is: min(max(preferred minimum width, available width), preferred width).</p>
</blockquote>
<p class="Credit"><small>(<a href="http://www.w3.org/TR/CSS21/visudet.html#float-width">Visual formatting model details: 10.3.5 Floating, non-replaced elements</a>)</small></p>
<p>幅を指定しないということはすなわち、<code>width</code> プロパティに初期値である <code>auto</code> が指定されていることになる。通常フローのブロックレベル要素で <code>width</code> が <code>auto</code> の場合、その幅は親要素内でいっぱいまで広がるけど、フロートした要素の場合は shrink-to-fit という方法で幅が算出されることになる、と。この shrink-to-fit というのはテーブルのセルと同じような挙動で、内容に応じて可能な限り小さく縮むというもの。</p>
<p>この柔軟なアルゴリズムはかなり使える。例えば横に並べたナビゲーション項目を画像ではなくテキストで作りたい場合とか。でもこの shrink-to-fit アルゴリズム、あまり多く紹介されていない気がする。僕もフロートするなら幅の指定も必須、とついこないだまで考えていたし。</p>
<ul>
<li><a href="http://bakera.jp/ebi/topic/472">width: auto のフロート | 水無月ばけらのえび日記</a></li>
<li><a href="http://gyauza.egoism.jp/clip/archives/2007/04/float-css-width-auto/">floatされた要素の幅はどのように決まるのか | Takazudo Clipping*</a></li>
</ul>
<p>やはり非置換要素のフロートというとマルチカラム・レイアウトに利用されることが多いから、自然と幅を明示することになるからかな。あと、どうも古いブラウザでバグがあるらしい。</p>
<ul>
<li><a href="http://norisfactory.com/stylesheetlab/000006.php">スタイルシートをめぐる冒険: floatと一緒にwidthも指定しないと回り込まない</a></li>
</ul>
<p>でも少なくとも IE 6 を含むモダン・ブラウザではサポートされていて、幅が 0 と解釈されることはない。</p>
<p>ちなみにこの shrink-to-fit って言い回し、<a href="http://www.levi.com/">Levi’s</a> の 501 からきてるのだろうか?</p>
のっちメソッド 2: なりゆき幅で横並び
2009-06-28T00:00:00Z
https://terkel.jp/archives/2009/06/one-pixel-notched-corners-2/
<p>以前に書いた <a href="https://terkel.jp/archives/2008/04/one-pixel-notched-corners/">のっちメソッド: One pixel notched corners</a> の改良版。まずはスクリーン・ショットを。</p>
<figure>
<img decoding="async" alt="「のっちメソッド」のスクリーン・ショット。ボックスの角が 1 px 欠けている表現" src="https://terkel.jp/img/one-pixel-notched-corners-2.png" />
</figure>
<p>Gmail の「ラベル」なんかでも使われている、ボックスの四隅が 1 px 欠けた疑似角丸的な表現。これを CSS のみで実現するテクニックが「のっちメソッド」なわけだが、幅が固定のボックスにしか適用できなかった。そこで上図のように内容に応じて縮む「なりゆき幅」を実現するのが今日のお題。</p>
<p>まずはマークアップ。それぞれのボックスはブロックかインラインかを問わず二重の要素でラップされている必要がある。例えばこんな感じ:</p>
<pre><code class="language-html"><ul>
<li><a href="#">HTML/XHTML</a></li>
<li><a href="#">CSS</a></li>
<li><a href="#">JavaScript</a></li>
<ul>
</code></pre>
<p>CSS では、まず <code>float</code> プロパティで親要素 (この例では <code>li</code>) を横並びにし、上下のボーダーと左右のマージンとを設定する:</p>
<pre><code class="language-css">li {
float: left;
boder: solid #008080;
boder-width: 1px 0;
margin: 0 2px;
}
</code></pre>
<p>次に内側の要素 (この場合は <code>a</code>) もフロートさせ、パディングと左右のボーダーを指定。そして四隅を欠けさせるためのキモ、左右に -1px のマージンを指定して親要素からはみ出させる。なおここで <code>position: relative</code> も指定しないと IE 6 で意図どおりにはみ出してくれないので注意。</p>
<pre><code class="language-css">li a {
float: left;
padding: 0 0.5em;
boder: solid #008080;
boder-width: 0 1px;
margin: 0 -1px;
position: relative; /* for IE 6 */
}
</code></pre>
<p>以上。<a href="https://terkel.jp/demo/one-pixel-notched-corners-2.html">完成版のデモ</a> をどうぞ。タブやページ送りなどのナビゲーションなんかに使えるんじゃないだろうか。</p>
<p>幅を明示せずにフロートさせることで、幅がなりゆきで算出される <a href="https://terkel.jp/archives/2009/06/floating-nonreplaced-elements-without-explicit-width/" title="非置換要素の幅を明示せずにフロート - terkel.jp">shrink-to-fit アルゴリズム</a> が適用されるわけだけど、今回の例ではフロートのもうひとつの特性も利用している。それは「フロートした要素はその要素タイプにかかわらずブロック・ボックスを生成する」という挙動。これ、あまり知られていないというか、そう言われてみればそうか、という挙動じゃないかな。以下は <a href="http://meyerweb.com/">Eric Meyer</a> の “<a href="http://www.amazon.co.jp/o/ASIN/0596515057/terkel-22">CSS: Pocket Reference</a>” からの引用:</p>
<blockquote cite="urn:ISBN:978-0-596-51505-8" lang="en">
<p>A floated element will generate a block-level box no matter what kind of element it may be. Floated nonreplaced elements should be given an explicit width, as they otherwise tend to become as narrow as possible.</p>
</blockquote>
<p class="Credit"><small>(Eric A. Meyer, CSS: Pocket Reference)</small></p>
<p>フロートってテクニックは CSS を習得する過程で最初につまづくとこだと思うんだけど、実は習得したのちにちゃんと振り返る機会があまりないものなのかもしれない。なにしろ習得過程で思いどおりにいかない場面にいやってほど直面してさんざん試行錯誤しているので、いったん習得した (と思えた) らもう考えたくない、ってのはありそうな話。でも以外と挙動を理解してないんだなー、と最近は感じる。まだまだ応用の余地がありそうな気がするんだよね、フロートって。</p>
青いスウェードの靴
2009-07-07T00:00:00Z
https://terkel.jp/archives/2009/07/blue-suede-shoes/
<blockquote cite="http://en.wikipedia.org/wiki/Blue_Suede_Shoes">
<p>俺の家に火をつけてもいい<br />
俺の車を盗んでもいい<br />
俺の酒を残らず飲んでしまってもいい<br />
<br />
お前が何をしようと勝手だが<br />
俺の青いスウェードの靴だけは踏むな</p>
</blockquote>
<p class="Credit"><small>(カール・パーキンス「ブルー・スエード・シューズ」)</small></p>
<p>この星に生まれて良かったよ。こんなに大切なことをたったの 2 分間で教えてもらえる。</p>
YouTube が IE6 にサヨナラ
2009-07-16T00:00:00Z
https://terkel.jp/archives/2009/07/youtube-say-goodbye-to-ie6/
<figure>
<img decoding="async" alt="Internet Explorer 6 で YouTube をブラウズしたところ" src="https://terkel.jp/img/youtube-ie6.jpg" />
</figure>
<p>良いニュース! <a href="http://www.youtube.com/">YouTube</a> が IE6 のサポートをまもなく打ち切るという。現在 IE6 で同サイトを訪れると、<strong>インターネットをより楽しんでいただくためには、最新のブラウザにアップグレードしてください。</strong> YouTube での Internet Explorer 6 のサポートはまもなく終了します。今すぐアップグレードしてください。というメッセージとともに <a href="http://mozilla.jp/firefox/">Firefox 3.5</a>、<a href="http://www.google.com/chrome/">Google Chrome</a>、そして <a href="http://www.microsoft.com/japan/windows/internet-explorer/default.aspx">IE8</a> のダウンロードを促すリンクが表示される。</p>
<ul>
<li><a href="http://jp.techcrunch.com/archives/20090714youtube-will-be-next-to-kiss-ie6-support-goodbye/">YouTube、Digg に続いて IE6 のサポートを打ち切りか? - TechCrunch Japan</a></li>
<li><a href="http://slashdot.jp/it/09/07/15/0624224.shtml">YouTube、IE6 サポートを段階的に廃止 - スラッシュドット・ジャパン</a></li>
</ul>
<p>YouTube という人気サイトがこのような決断をし、かつそのことを大きくアピールしてくれたことの意義はとても大きい。なぜならこのアピールは「ブラウザってなに?」という人たちにも有効なのだから。彼らにとって Web ブラウザは PC にあらかじめ備わるひとつの「機能」にすぎず、乗り換えるもなにも今のところインターネットが使えていれば問題はないのである (ソースはうちの妻)。だから Firefox や Chrome がいかに安全で快適なブラウザであるかを 100 万回アピールしても、「YouTube が観られなくなるよ」のひと言には勝てない。これは IE6 の死をかなり後押ししてくれるはずだ。ここでほかの人気サイトが便乗してくれることを期待してやまない。</p>
<p>それにしても、「IE6 のシェアが下落」とか「IE6 をサポートしない宣言」とかいう話題が出たときに必ず聞こえてくる、「でも日本ではまだダメだよね」とかいう声っていったいなんなんだろう? そんな根拠のないあきらめをどこかの誰かが語るのを聞くうちはまだいい。最悪なのはその声が自分の頭の中で聞こえたときだ。</p>
<p>しかし時代は変わる。今回の YouTube のメッセージは IE6 ユーザにブラウザのアップデイトを促すだけじゃない。僕たちのような Web のフロントエンドで日々もがいているディヴェロッパを勇気づけてもくれる。YouTube に (つまりは Google に) 拍手。</p>
横並びにしたリスト項目の区切り
2009-07-20T00:00:00Z
https://terkel.jp/archives/2009/07/horizontal-list-with-separators/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/ueki.png" />
</figure>
<p>こんなふうに、横並びにしたリスト項目の間に区切りを表示させたいときにどうするか? すべての項目に区切りを表示させてしまうと区切りがひとつ多くなってしまうので、なんらかの工夫が必要になってくるわけです。</p>
<pre><code class="language-html"><ul>
<li><a href="/">Home</a></li>
<li><a href="/archives/">Archives</a></li>
<li><a href="/portfolio/">Portfolio</a></li>
<li><a href="/about/">About</a></li>
</ul>
</code></pre>
<p>上記のようなマークアップを例に、CSS でリスト項目を <code>float: left;</code> または <code>display: inline;</code> で横に並べ、各項目の左側にボーダーまたは背景画像で区切りを配置する場合を考えてみます。</p>
<p>おそらくもっともスマートなのは、いったんすべての項目に区切りを指定し、<code>:first-child</code> 疑似クラスを使って先頭の項目だけ指定を上書き、というやり方。しかし <code>:first-child</code> 疑似クラスは IE6 で使えないので、<code>:first-child</code> に相当するクラスを手動で、または jQuery などを利用して自動で付与する、というのがありそうなアプローチです。</p>
<p>それでももちろんいいんですが、各項目の左マージンに区切りの幅と同じ大きさのマイナス値を指定し、親要素の <code>overflow</code> プロパティに <code>hidden</code> を指定することでも実現できます。</p>
<pre><code class="language-css">ul {
position: relative;
overflow: hidden;
padding: 0;
margin: 0;
list-style: none;
}
ul li {
float: left;
padding: 0 0 0 4px;
margin: 0 5px 0 -1px;
border-left: 1px solid #808080;
}
</code></pre>
<p>もしリスト全体を右揃えにするなら、<code>ul</code> に幅を指定せず <code>float: right;</code> でいけます。</p>
<p>難点は中央揃えが難しいこと。<code>ul</code> を二重の <code>div</code> でくるんだりすればおそらくなんとかなると思いますが、そこまでいくとちょっとね。</p>
自由
2009-08-15T00:00:00Z
https://terkel.jp/archives/2009/08/freedom/
<blockquote cite="http://www.u2.com/discography/lyrics/lyric/song/85/">
<p>自由には香りがある<br />
生まれたての赤ん坊の頭のてっぺんのような</p>
</blockquote>
<p class="Credit"><small>(ボノ「ミラクル・ドラッグ」)</small></p>
要素を非表示化するスタイル
2009-08-16T00:00:00Z
https://terkel.jp/archives/2009/08/nostyle-noscreen-noprint/
<p>HTML にはスクリプトが有効である場合は表示されない <code>noscript</code> 要素というのがあるけど、同様に「スタイルシートが有効の場合」や「印刷した場合」など、状況に応じて要素を非表示化するスタイルを書いてモジュール化しておくと便利。</p>
<pre><code class="language-css">/* スタイルシートが有効の場合は非表示 */
.nostyle { display: none; }
/* スクリーンメディアでは非表示 */
@media screen {
.noscreen { diaply: none; }
}
/* 印刷では非表示 */
@media print {
.noprint { diaply: none; }
}
</code></pre>
<pre><code class="language-html"><p class="nostyle">このパラグラフはスタイルシートが有効である場合には表示されません。</p>
<p class="noscreen">このパラグラフはスクリーンメディアでは表示されません。</p>
<p class="noprint">このパラグラフは印刷時には表示されません。</p>
</code></pre>
09-09-09
2009-09-09T00:00:00Z
https://terkel.jp/archives/2009/09/09-09-09/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/09-09-09.jpg" />
</figure>
<p>ついにこの日がやって来た。2009 年 9 月 9 日、水曜日。<a href="http://www.thebeatles.com/" title="The Beatles">ザ・ビートルズ</a> のオリジナル・カタログが、80 年代の CD 化以来はじめてのデジタル・リマスタリングを施されて、新たに生まれ変わる。</p>
<p>この祝いの日に、どのアルバムが良いとか悪いとか、このバンドがいかに偉大だったかとか、そんな話はしたくない。こうして自分のブログにアートワークを並べられる、そのことだけで幸せ。</p>
みんなで IA: CSS Nite LP, Disk 7
2009-09-15T00:00:00Z
https://terkel.jp/archives/2009/09/css-nite-lp-disk-7-ia-special/
<p>「情報アーキテクチャ (Information Architecture)」をテーマにしたセミナー、<a href="http://lp7.cssnite.jp/">CSS Nite LP, Disk 7: IA スペシャル</a> に参加してきました。6 時間にも及ぶ長丁場でしたが、どのセッションもかなり濃い内容で、有意義なイヴェントだったと思います。</p>
<p>情報アーキテクチャとは何かを僕なりにごく乱暴に要約すると、「情報をわかりやすく伝えるための設計」といったところでしょうか。ユーザが何を求めているかを分析すること、コンテンツを把握し適切に分類すること、ナビゲーションを構造化すること…。そう、つまり、Web サイトを作る人ならだれもが考えていることだし、また考えるべきことだと言えます。</p>
<p>情報アーキテクチャは、扱っているものが「情報」という、ともすればどこまでも抽象的になってしまうようなものなので、とっつきにくいというか、とっかかりがつかみにくいものに感じがちです。しかし、みんながそれぞれの立場から「どうすればより伝わるのか」ということを考え、そしてそのアイディアを共有する、そういったごくシンプルなことが情報アーキテクチャの基本なのだと思います。グラフィック・デザイナーならレイアウトや色彩設計から、フロントエンド技術者ならコードから発想するでしょう。それが情報アーキテクチャの出発点です。</p>
<p>そして情報アーキテクチャのとくに重要にして難しい点が、「いかにして共有するか」という点だと思います。せっかくの設計もメンバー間できちんと共有されなければ意味がありません。そのためのドキュメント形式の選択も悩むところです。しかしそもそもがはっきとしたカタチのないものですから、情報アーキテクチャ作業の成果物としてのドキュメントはプロジェクトによってその姿を変えるはずです。同様に、だれがどれだけ情報アーキテクチャに携わるのかもプロジェクトごとに違ってきます。プロジェクト・マネージャーが中心になってドキュメントに落とし込むのが適切な場合もあれば、メンバー全員で議論した結果をイメージで描き起こすのが早い、という場合もあるでしょう。そうしてベストな方法を探りながら進めるしかないのではないでしょうか。</p>
<p>Web サイト作りに携わるすべてのひとが、それぞれのアプローチで「わかりやすさ」を考え、共有し、そしてゴールを目指す。そんな本来当たり前であるはずの仕事のあり方を本当に実現するために、情報アーキテクチャという古くて新しい手法についてしっかり考えていきたい、そう感じさせるセミナーでした。</p>
Rubbergard Record
2009-10-04T00:00:00Z
https://terkel.jp/archives/2009/10/rubbergard-record/
<p>製作のお手伝いをしていた、神田神保町のレコード・ショップ <a href="http://www.rubbergard.jp/">Rubbergard Record</a> (ラバーガード・レコード) のサイトが、本日めでたく公開されました。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/rubbergard.jpg" />
</figure>
<p>Rubbergard はソウル、ジャズ、ブラジル音楽、ロックなどの廃盤ヴァイナルと CD を中心に扱う、いわゆる「中古レコード屋」で、昨年の夏から営業しています。ほとんどひとりでやってる小さな店なんですが、店長みずから買い付けるアイテムのクオリティがとにかくハンパないです。いつ行っても聴いたことのないようなブツが出てくるような、音楽好きなら行って損はないと断言できる、充実の品揃えを誇ります。</p>
<p>ここの店長とは 15 年来の付き合いなのですが、彼ほどの音楽バカにはお目にかかったことがないです。彼の最大の強みは、お客さんの話をちょっと聞けば、今までどういう聴き方をしてきたかとか、今はどんなものを聴きたいのか、といったことを敏感に察知する能力。で、「こんなのあるけど、どう?」とさりげなくサジェスト。とはいっても「一見さんお断り」な雰囲気はまるでないので、気軽に立ち寄って音楽の話をするだけでも楽しめると思うし、ついつい長居してしまうこと請け合いの、居心地のいい店なんです。</p>
<p>サイトとしては、当初の予定では EC サイトとしてオープンする予定だったのですが、諸般の事情からとりあえずブログとして公開。<a href="http://studio-fun.net/">studio-fun.net</a> の kan さんに <a href="http://ja.wordpress.org/">WordPress</a> での構築をお願いしました。僕はいつものフロントエンド開発のみならず、久々にヴィジュアル・デザインまで担当しています。<a href="http://www.alistapart.com/">A List Apart</a> をかなりパクってしまいましたが。ていうか縦長のロゴを配置する方法をほかに思いつかなかった。</p>
<p>あまつさえプロジェクト・マネージメントなんていう慣れない仕事も受け持ってしまったせいで、スケジュールがかなりグダグダになってしまいました。古くからの友人だってことで店長からはかなり大目にみてもらってますが、申し訳ない思いでいっぱいです。やっぱ餅は餅屋というか。</p>
<p>とにかく Rubbergard Record、良いお店なので、よろしくお願いします!</p>
HootSuite で鉄道の運行状況を知る
2009-10-08T00:00:00Z
https://terkel.jp/archives/2009/10/hootsuite-transit/
<p>悪天候でダイヤが乱れた場合など、鉄道の運行状況をリアルタイムで知りたいときには、Web ベースの Twitter クライアント <a href="http://hootsuite.com/">HootSuite</a> が便利だ。</p>
<ol>
<li>適当な名前で新しいタブを作る。</li>
<li>検索ボックスから利用する路線名で検索。</li>
<li>検索結果を Save as Column ボタンで保存。</li>
<li>利用する路線のぶんだけ 2 と 3 を繰り返す。</li>
</ol>
<p>こうしてよく使う路線を登録しておけば、あと必要なときにそのタブを開くだけ。iPhone やモバイル版クライアントを使っている皆さんのつぶやきから、リアルタイムな運行状況を知ることができる。「山手線、運転再開の車内アナウンスなう」とか。</p>
フロントエンド Web 開発のためのローカル・ブックマーク
2009-10-23T00:00:00Z
https://terkel.jp/archives/2009/10/local-bookmarks-for-frontend-web-development/
<p>最近はブックマークといえばページ単位で <a href="http://delicious.com/">Delicious</a> に登録する場合がほとんどだけど、リファレンス系のサイトやオンライン・ツールなど、仕事中にちょくちょく使うものはやはりブラウザにブックマークしておくのが便利。というわけで、「フロントエンド Web 開発」とか言うとなんか大げさだけど、とにかく僕が仕事場の Firefox に保存している「そっち方面」のブックマークを、整理しつつさらしてみる。</p>
<ul>
<li><a href="http://www.w3.org/" title="World Wide Web Consortium (W3C)">W3C</a>
<ul>
<li><a href="http://www.w3.org/standards/techs/html" title="HTML Current Status - W3C">HTML</a>
<ul>
<li><a href="http://www.w3.org/TR/html5/" title="HTML 5">HTML 5</a></li>
<li><a href="http://www.w3.org/TR/html401/" title="HTML 4.01 Specification">HTML 4.01</a></li>
<li><a href="http://www.w3.org/TR/xhtml1/" title="XHTML 1.0: The Extensible HyperText Markup Language (Second Edition)">XHTML 1.0</a></li>
</ul>
</li>
<li><a href="http://www.w3.org/standards/techs/css" title="CSS Current Status - W3C">CSS</a>
<ul>
<li><a href="http://www.w3.org/Style/CSS/current-work">CSS: Current Work</a></li>
<li><a href="http://www.w3.org/TR/CSS21/" title="Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification">CSS 2.1</a></li>
<li><a href="http://www.w3.org/TR/2008/REC-CSS2-20080411/" title="Cascading Style Sheets, level 2">CSS 2</a></li>
<li><a href="http://www.w3.org/TR/CSS1/" title="Cascading Style Sheets, level 1">CSS 1</a></li>
</ul>
</li>
</ul>
</li>
<li>HTML
<ul>
<li><a href="http://www.kanzaki.com/docs/htminfo.html">ごく簡単な HTML の説明</a> (The Web KANZAKI)</li>
<li><a href="http://bakera.jp/ref/html">ばけらの HTML リファレンス (未完成)</a> (bakera.jp)</li>
<li><a href="http://microformats.org/wiki/ja" title="Microformats Wiki にようこそ! · Microformats Wiki">Microformats</a></li>
</ul>
</li>
<li>CSS
<ul>
<li><a href="http://www.quirksmode.org/css/contents.html">CSS - Contents and compatibility</a> (QuirksMode)</li>
</ul>
</li>
<li>JavaScript
<ul>
<li><a href="http://jquery.com/" title="jQuery: The Write Less, Do More, JavaScript Library">jQuery</a>
<ul>
<li><a href="http://semooh.jp/jquery/">jQuery 日本語リファレンス</a></li>
</ul>
</li>
</ul>
</li>
<li>タイポグラフィ
<ul>
<li><a href="http://www.typetester.org/" title="Typetester – Compare fonts for the screen">Typetester</a></li>
<li><a href="http://www.tg.rim.or.jp/~hexane/ach/hfw/">Hints of fonts on the web</a> (Academic HTML)</li>
</ul>
</li>
<li>画像
<ul>
<li><a href="http://www.gracepointafterfive.com/punypng/" title="punypng - PNG Compression and Image Optimization - Gracepoint After Five">punypng</a></li>
</ul>
</li>
<li>ブログ
<ul>
<li><a href="http://wpdocs.sourceforge.jp/">WordPress Codex 日本語版</a></li>
<li><a href="http://www.movabletype.jp/">MovableType.jp</a></li>
</ul>
</li>
<li>Web マスター
<ul>
<li><a href="http://www.google.com/analytics/">Gogle Analytics</a></li>
<li><a href="http://www.google.com/webmasters/">Google Webmaster Central</a></li>
<li><a href="http://siteexplorer.search.yahoo.co.jp/">サイトエクスプローラー - Yahoo! 検索</a></li>
<li><a href="http://www.bing.com/webmaster">Webmaster Center - Bing</a></li>
</ul>
</li>
<li><a href="http://mozilla.jp/firefox/">Firefox</a>
<ul>
<li><a href="https://addons.mozilla.org/ja/firefox/">Add-ons for Firefox</a></li>
<li><code>resource://gre/res/html.css</code></li>
<li><code>resource://gre/res/forms.css</code></li>
<li><code>resource://gre/res/quirk.css</code></li>
<li><code>resource://gre/res/viewsource.css</code></li>
</ul>
</li>
</ul>
<p>ひとつだけ補足。Firefox の項の <code>resource://</code> ではじまるパスを Firefox のロケーションバーに入力すると、ブラウザのデフォルト CSS を確認できる。ちょくちょく見るようなものではないけど、いわゆるリセット CSS 的なものを書くときなんかには参考になるので、ブックマークしておくと便利。</p>
The Stone Roses: 20th Anniversary
2009-10-28T00:00:00Z
https://terkel.jp/archives/2009/10/the-stone-roses-20th-anniversary/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/stone-roses-20th/special-edition.jpg" />
</figure>
<p><a href="http://www.thestoneroses20.com/">ザ・ストーン・ローゼズ</a>のファースト・アルバム“The Stone Roses”が発表されて今年で20年が経つ。これを記念して、同アルバムの新装盤がリリースされた。このアルバムはこれまでも何度かリイシューされてきたが、今回は<a href="http://www.ianbrown.co.uk/">イアン・ブラウン</a>とプロデューサーのジョン・レッキーが直々にリマスタリング作業にあたっており、20周年の名にふさわしい決定版と言えるだろう。</p>
<p>新しいサウンドは全体的にボトムが強化された印象。レニとマニという強力なリズム隊を擁するバンドだっただけに、この方向性は正しい。音像をクリアにしすぎず、あくまで本来の雰囲気を損なわないよう配慮している点も評価したい。</p>
<p>またアルバム本編がリマスタリングされるとともに、アルバム未収録のシングル曲や初出のデモ音源などもあわせてリリースされる。しかしながら商品のエディションが複数あり、どのエディションにどのマテリアルが収録されているのかなどが少々わかりづらい。そこで本稿ではこれらのエディション、およびそこに収められたマテリアルについて検証してみたい。</p>
<h2>エディションの比較</h2>
<p>まず8月にリリースされた輸入盤が3エディション。さらに日本ではそれらのどれとも違う独自編集の2エディションがリリースされており、以下の計5つのエディションが存在する。</p>
<dl>
<dt><a href="http://www.amazon.co.jp/o/ASIN/B0027CSKQU/terkel-22" title="Amazon.co.jp: The Stone Roses: The Stone Roses: 音楽">Collector’s Edition</a></dt>
<dd>いわゆる全部入りエディション。LPサイズの大型ボックスは90年代初頭のボックスセット・ブームを思い起こさせる。5,000セットのみの限定品。今回リリースされるすべての音源のみならず、タイトルどおりまさにコレクター向けの「おまけ」をふんだんに盛り込んでる。後述する音源や映像以外の主なコンテンツは以下のとおり。
<ul>
<li>金箔・エンボス加工、シリアル・ナンバー入りのボックス</li>
<li>180グラムの重量盤ヴァイナル3枚(音源としてはすべてほかのエディションでも聴けるものだが、“The Extras”のヴァイナルはこれでしか手に入らない)</li>
<li>48ページのブックレット</li>
<li>6枚のシングルのアートワーク</li>
</ul>
</dd>
<dt><a href="http://www.amazon.co.jp/o/ASIN/B0027CSKR4/terkel-22">Legacy Edition</a></dt>
<dd>2 CD + DVDの計3枚組。スリップケース入りのブック型パッケージ。日本盤も『レガシー・エディション』のタイトルだが収録内容は異なるので注意。</dd>
<dt><a href="http://www.amazon.co.jp/o/ASIN/B0027CSKRE/terkel-22">Special Edition</a></dt>
<dd>オリジナル・アルバムのみの、いわゆる通常盤。ただ、ほかのエディションのアルバム本編とは違い、このエディションのみボーナス・トラック‘Fools Gold [Full Length]’を追加収録した全12曲構成。</dd>
<dt><a href="http://www.amazon.co.jp/o/ASIN/B002IUBH52/terkel-22">レガシー・エディション〈リミテッド〉</a></dt>
<dd>日本盤の2エディションはともに『レガシー・エディション』のタイトルだが、こちらは〈リミテッド〉と銘打たれた限定盤で、CD 3枚組。「三方背スリーブケース仕様」「オリジナル・アルバム紙ジャケット復刻」などの惹句があるが、はっきり言って出来はかなりしょぼく、ただの紙製パッケージの域を出るものではない。しかしそこはどうでもよくて、重要なのは内容が上記の輸入盤3エディションのどれとも違う日本独自編集である点。今回リリースされる音源のほぼすべてを網羅している。</dd>
<dt><a href="http://www.amazon.co.jp/o/ASIN/B002IUBH5C/terkel-22">レガシー・エディション</a></dt>
<dd>日本における通常仕様盤で、CD 2枚組。〈リミテッド〉同様に日本独自編集で、同エディションから“The Lost Demos”をオミットした構成。</dd>
</dl>
<p>各エディションに収められたマテリアルをまとめると以下のとおり。</p>
<figure>
<table summary="“The Stone Roses”の各エディションに含まれるマテリアルの比較。横軸にエディション名、縦軸にマテリアル名">
<thead>
<tr>
<th></th>
<th>Collector’s<br />Edition</th>
<th>Legacy<br />Edition</th>
<th>Special<br />Edition</th>
<th>レガシー・<br />エディション<br />〈リミテッド〉</th>
<th>レガシー・<br />エディション</th>
</tr>
</thead>
<tbody>
<tr>
<th>The Stone Roses</th>
<td>✔</td>
<td>✔</td>
<td>✔</td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<th>The Extras</th>
<td>✔</td>
<td></td>
<td></td>
<td>✔</td>
<td>✔</td>
</tr>
<tr>
<th>The Lost Demos</th>
<td>✔</td>
<td>✔</td>
<td></td>
<td>✔</td>
<td></td>
</tr>
<tr>
<th>DVD</th>
<td>✔</td>
<td>✔</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th>Lemon USB</th>
<td>✔</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</figure>
<h2>マテリアルの詳細</h2>
<p>ではディスクごとに各マテリアルを検証していこう。なお、筆者は『レガシー・エディション〈リミテッド〉』しか入手していないため、そこに含まれないDVDやUSBについての情報はウェブで収集したものであることをお断りしておく。</p>
<h3>The Stone Roses</h3>
<p>デジタル・リマスターされたアルバムの本編。今までこのアルバムには収録曲の違ういくつかのヴァージョンが存在するが、ここではUKオリジナル・リリースに準じている(“Special Edition”のみボーナス・トラックとして‘Fools Gold’を収録)。</p>
<ol>
<li>I Wanna Be Adored</li>
<li>She Bangs the Drums</li>
<li>Waterfall</li>
<li>Don’t Stop</li>
<li>Bye Bye Badman</li>
<li>Elizabeth My Dear</li>
<li>(Song for My) Sugar Spun Sister</li>
<li>Made of Stone</li>
<li>Shoot You Down</li>
<li>This Is the One</li>
<li>I Am the Resurrection</li>
</ol>
<h3>The Extras</h3>
<p>シングルのみに収録された曲をデジタル・リマスターを施して収めたディスク。彼らの場合、‘Fools Gold’、‘What the World Is Waiting For’、そして‘One Love’などの重要な曲がアルバム未収録であることや、シングルB面にも聴き逃せない佳曲が多いことから、これらをコンパイルするのみならず、きっちりリマスターしたことの意義は大きい。</p>
<ol>
<li>Elephant Stone [12″ Version]</li>
<li>Full Fathom Five</li>
<li>The Hardest Thing</li>
<li>Going Down</li>
<li>Guernica</li>
<li>Mersey Paradise</li>
<li>Standing Here</li>
<li>Simone</li>
<li>Fools Gold [Full Length]</li>
<li>What the World Is Waiting For</li>
<li>One Love [Full Length]</li>
<li>Something’s Burning [Full Length]</li>
<li>Where Angels Play</li>
</ol>
<p>7″と12″など複数のヴァージョンが存在する曲の場合、すべてフル・レングスの12″ヴァージョンを採用(ヴァージョン違いについての詳細は後述)。‘Full Fathom Five’は“Elephnt Stone”の12″ヴァイナルに収録されていたヴァージョンで、今回が初めてのCD化。なお以下の楽曲は今回のリマスターにあたってわずかに手が加えられている。</p>
<dl>
<dt>Standing Here</dt><dt>
</dt><dd>イントロのギターの最初の部分がほんの一瞬だけ拡張された。</dd>
<dt>Where Angels Play</dt>
<dd>イントロにハイハットのカウントが追加された。蛇足としか思えない、意図不明の改変。</dd>
</dl>
<h3>The Lost Demos</h3>
<p>デモ音源集。売りである未発表曲‘Pearl Bastard’は、悪い曲ではないが、かなり地味。‘Going Down’路線というか、ゆったりしたテンポでいかにもシングルB面的な雰囲気。ほかの曲も、完成版とアレンジが大幅に異なるなどといったことはなく、いまいち聴きどころにとぼしい。つまりアルバムのレコーディングに入る時点で楽曲やアレンジがかなり練られていたということになるわけだが。</p>
<ol>
<li>I Wanna Be Adored</li>
<li>She Bangs the Drums</li>
<li>Waterfall</li>
<li>Bye Bye Badman</li>
<li>(Song for My) Sugar Spun Sister</li>
<li>Shoot You Down</li>
<li>This Is the One</li>
<li>I Am the Resurrection</li>
<li>Elephant Stone</li>
<li>Going Down</li>
<li>Mersey Paradise</li>
<li>Where Angels Play</li>
<li>Something’s Burning</li>
<li>One Love</li>
<li>Pearl Bastard</li>
</ol>
<h3>DVD</h3>
<p>1989年のBlackpoolにおけるギグと、6本のプロモ・ヴィデオを収録。内容は『<a href="http://www.amazon.co.jp/o/ASIN/B0002IJNEO/terkel-22">ザ・ストーン・ローゼズDVD</a>』のディスク1と同様と思われる。</p>
<h3>Lemon USB</h3>
<p>“Collecor’s Edition”にのみ付属の、レモン型USBメモリ。今回リリースされた全音源とプロモ・ヴィデオ6本に加え、ここでしか手に入らない以下のマテリアルを収録。</p>
<ul>
<li>未発表の「逆回転」トラック5曲</li>
<li>‘Fools Gold’レコーディング時に撮影されたホーム・ヴィデオ映像</li>
<li>ケータイ着信音</li>
<li>デスクトップ壁紙</li>
<li>48ページのデジタル・ブックレット</li>
</ul>
<p>上記のうち、「逆回転」は英国のiTunes Storeで販売されているシングル5種に分散されて収録のものと同一と思われる。</p>
<ul>
<li><a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?id=321906733&s=143444" title="iTunes Store (UK)">Elephant Stone - Single</a></li>
<li><a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?id=321134992&s=143444" title="iTunes Store (UK)">Made of Stone - EP</a></li>
<li><a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?id=322326589&s=143444" title="iTunes Store (UK)">She Bangs the Drums - EP</a></li>
<li><a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?id=322412072&s=143444" title="iTunes Store (UK)">Fools Gold - EP</a></li>
<li><a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?id=322799195&s=143444" title="iTunes Store (UK)">One Love - EP</a></li>
</ul>
<p>また「ホーム・ヴィデオ」は以下で観られるものと同一とのこと。</p>
<ul>
<li><a href="http://www.guardian.co.uk/music/video/2009/aug/03/stone-roses-fools-gold">The Stone Roses during the recording of Fools Gold | Music | guardian.co.uk</a></li>
</ul>
<h2>どのエディションを買うべきか?</h2>
<p>結論から言うと、日本盤『レガシー・エディション』の通常盤(CD 2枚組)をすすめる。</p>
<p>『レガシー・エディション〈リミテッド〉』は、“The Lost Demos”を含む点と紙ジャケである点がアドヴァンテージだが、デモ音源は地味、紙ジャケは出来がしょぼいことから、あまりおすすめはできない。最大のポイントは未発表曲の‘Pearl Bastard’を含む点なので、この曲が欲しいかどうかが決め手になるだろう。</p>
<p>今回リリースされるすべてのマテリアルを手に入れようとするなら“Collecor’s Edition”一択になってしまうが、同エディションでしか聴けない音源は、「楽曲」とは呼び難い5曲の「逆回転」トラックのみ。あとは「モノ」としての価値に重きを置くかどうかだろう。</p>
<p>アルバム本編にデモ音源とDVDを加えた輸入盤の“Legcy Edition”はもっとも中途半端な内容と言わざるを得ない。デモ音源の出来は前述のとおり、映像もほかのソースから入手可能であることから却下。</p>
<p>シンプルにアルバムのみの“Special Edition”という手もあるが、‘Elephant Stone’、‘What the World Is Waiting For’、‘One Love’などの代表曲が聴けないのはありえないのでやはり却下。</p>
<p>というわけで、日本盤『レガシー・エディション』の通常盤こそもっとも賢い選択と断言する。この日本独自仕様を採用したSony Music Japanの英断はおおいに評価されていい。また、もし「音源」をひととおり揃えたいなら『レガシー・エディション〈リミテッド〉』、余程の思い入れと予算と収納スペースがあるならば記念品として“Collecor’s Edition”、といったところだろう。</p>
<h2>オルタネイト・ヴァージョン</h2>
<p>このほか、今回リリースされたどのエディションにも収録されていないヴァージョンもいくつかあるので整理してみる。以下に挙げたほかにもリミクスなど別ヴァージョンが数多く存在するが、バンドがSilvertone Recordsを離れた1991年春以降にリリースされたもののほとんどは、メンバーが関与していないものと見なし、一部の例外を除いてここでは取り上げない。</p>
<dl>
<dt>Elephant Stone [7″ Version]</dt>
<dd>今回“The Extra”に収録されている同曲は12″ヴァージョン。この7″ヴァージョンはイントロがドラム・ソロではなく歪んだギターのフレーズから始まるなど、全体的にリズム・トラックより上モノを前面にフィーチャーしたギター・バンドっぽい出来。“The Complete Stone Roses”のほか、かつてアルバムの米国盤や再発盤にも収録されていたので入手は容易。</dd>
<dt>Full Fathom Five</dt>
<dd>前述のとおり、この曲はCDと12″ヴァイナルでヴァージョンが異なる。CDヴァージョンは現在“The Complete Stone Roses”に収録。</dd>
<dt>She Bangs the Drums [Single Version]</dt>
<dd>アルバムからのシングル・カット。イントロのハイハットがカットされているほか、とくにコーラスでのバッキング・ヴォーカルやギターのミックスがアルバム・ヴァージョンと異なる。かつては日本独自企画盤『<a href="http://www.amazon.co.jp/o/ASIN/B00004VPOO/terkel-22">ホワット・ザ・ワールド・イズ・ウェイティング・フォー</a>』にも収録されていたが、現在は“The Complete Stone Roses”で入手可能。</dd>
<dt>Fools Gold [7″ Version]</dt>
<dd>シングル“Fools Gold/What the Worid Is Waiting For”に収録の、イントロとアウトロをエディットした短縮版。“The Complete Stone Roses”と、今回の20th Anniversaryに合わせてリリースされたシングルCD“<a href="http://www.amazon.co.jp/o/ASIN/B002EP8UJW/terkel-22">Fools Gold</a>”で聴くことができる。</dd>
<dt>One Love [7″ Version]</dt>
<dd>同曲の英国盤7″ヴァイナルと、日本および米国盤シングルCDに収録された短縮版。現在は“The Complete Stone Roses”と“The Very Best of The Stone Roses”で入手可能。</dd>
<dt>Something’s Burning [7″ Version]</dt>
<dd>“One Love”の7″ヴァイナルに収録の短縮版。CDでは“The Complete Stone Roses”にのみ収録。</dd>
<dt><a href="http://www.amazon.co.jp/o/ASIN/B00004WRX4/terkel-22">Sally Cinnamon [Live at the Hacienda]</a></dt>
<dd>シングル“I Wanna Be Adored”に収録のライヴ・ヴァージョン。バンドがすでにレーベルを移籍している1991年9月のリリースであるため、おそらく本作を世に出すことについてメンバーは関与していなかったと思われる。今回の20周年盤をはじめどのコンピレーションにも収録されておらず、シングルCDか12″ヴァイナルでしか聴くことができない。</dd>
</dl>
<p>このとおり、今回の 20 周年リリースで手に入らない音源のほとんどは“<a href="http://www.amazon.co.jp/o/ASIN/B000007456/terkel-22">The Complete Stone Roses</a>”で聴くことができるが、唯一の例外が‘Sally Cinnamon’のライヴ・ヴァージョン。しかし困ったことに、このヴァージョンの内容がじつに素晴らしいのだ。</p>
<p>最初のヴァースはジョン・スクワイアのギターとマニのベースを中心に王道ギター・バンド然とした展開を見せるものの、イアン・ブラウンの神懸かり的にド下手なヴォーカルによってすべてがバラバラと崩れ落ちそうになる。しかしなんとか最初のコーラスにたどり着いたあと、怒濤の如くセカンド・ヴァースに突入してからは、レニのカミナリのようなドラムがすべてを支配するバンドの必勝パターン。ヴォーカルは曲が進むにつれ調子を取り戻すどころかもはや修復不可能な域に達するが、しかし音程がはずれればはずれるほど歓喜の涙があふれそうになるというこのマジック!</p>
<p>……という、「これを聴いて何も感じない人とは友達になれません」クラスのものなので、なんとか探して聴いてみてください。</p>
Movable Type から WordPress へ
2009-11-15T00:00:00Z
https://terkel.jp/archives/2009/11/from-movable-type-to-wordpress/
<p>このサイトのパブリッシング・プラットフォームを <a href="http://www.sixapart.jp/movabletype/">Movable Type</a> から <a href="http://ja.wordpress.org/">WordPress</a> へ変更した。以下、いくつか覚え書きを。</p>
<h2>パーマリンクの移行</h2>
<p>すでにある記事のパーマリンクをそのまま持ってくる方法はいくつかあるようだけど、以下で紹介されている「MT で WP 形式のデータを書き出す」という方法を採用。下書きの記事は消えちゃうけど、パーマリンクのほかコメントとタグはすべてそのままスムーズにいけた。</p>
<ul>
<li><a href="http://netscrander.com/archives/mt_to_wp.php">Movable Type から WordPress に固定リンク込みで完璧に移行する方法 - ネットスクランダー</a></li>
</ul>
<h2>プラグイン</h2>
<p>プラグインは、デフォルトで入ってたものやよく紹介されてる定番らしきもののほか、いくつか探してインストールした。</p>
<dl>
<dt><a href="http://wordpress.org/extend/plugins/disable-wpautop/" title="WordPress › Disable WPAUTOP « WordPress Plugins">Disable WPAUTOP</a></dt>
<dd>編集画面で改行時に <code>p</code> 要素のタグが自動的に挿入される機能を無効化。旧サイトから持ってきたデータがおかしなマークアップに修正されていたので。</dd>
<dt><a href="http://www.feelwct.jp/staffblog/2008/02/wordpress.html" title="日本語版WordPressの曜日・月表記を英語にする方法 スタッフブログ 香川県 ホームページ制作会社 WEB CONSULTING FEEL">EnglishDate</a></dt>
<dd>投稿日時を英語表記にするプラグイン。はじめは、<code>/wp-content/languages</code> にある <code>ja.po</code> ファイルを <a href="http://www.poedit.net/">Poedit</a> で編集して、生成される <code>ja.mo</code> をサーバにアップロード、ってことをやってたんだけど、このやり方だとアップデートのときにもとに戻ってしまうので、プラグインで対応することに。</dd>
<dt><a href="http://www.kilroyjames.co.uk/2009/09/xth/" title="XTH – the XHTML to HTML converter for wordpress | Kilroy James">XTH</a></dt>
<dd>デフォルトでは <abbr title="Extensible HyperText Markup Language">XHTML</abbr> 1.0 で出力されるコードを、妥当な <abbr title="HyperText Markup Language">HTML</abbr> 4.01 に変換してくれるプラグイン。</dd>
</dl>
<h2>リデザイン</h2>
<p>ついでと言ってはなんだけど、一部をリデザインしてみた。まずコメント投稿フォーム。</p>
<figure>
<img decoding="async" alt="コメント投稿フォーム" src="https://terkel.jp/img/from-mt-to-wp-01.png" />
</figure>
<p>フォームのコントロール類は、デフォルトのスタイルからあまりにかけ離れるとフォームとして認識してもらえない可能性があるので、どこまでいじるべきか難しいところ。そこをあえて大胆な見せ方をしてみようかと思い、いろいろデザイン案を作ってたんだけど、結局は思い直してかなり無難にまとめた。「フォームらしさ」の演出になればいいなという期待を込めて、入力フィールドとボタンに <code>border-radius</code> を軽く適用。Firefox と Safari と Chrome ではうっすらと角丸になっているはず。ちなみに以下のように属性セレクタや疑似クラスなどを遠慮なく使っているため、IE6 ではプレーンなスタイルのまま。</p>
<pre><code class="language-css">input[type="text"],
textarea {
border: 2px solid silver;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
}
input[type="text"]:hover,
textarea:hover {
border-color: gray;
}
input[type="text"]:focus,
textarea:focus {
border-color: #0080ff;
}
input[type="submit"] {
border: 0;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
background: gray;
color: white;
}
input[type="submit"]:hover {
background: black;
}
input[type="submit"]:active {
background: #0080ff;
}
</code></pre>
<p>もうひとつはページ下部に並べた、フィードとソーシャル系 Web サービスへのリンク。</p>
<figure>
<img decoding="async" alt="ソーシャル系 Web サービスのリスト" src="https://terkel.jp/img/from-mt-to-wp-02.png" />
</figure>
<p>はじめはプレーンなリストに Favicon を表示するようなのを考えてたんだけど、ちょっとひねってこんな感じにしてみた。各サイトのロゴやなんかから拾ったキー・カラーを背景色に指定してるわけだけど、これだけでそれぞれのサイトの雰囲気が感じられるのが面白くて、けっこう気に入ってる。CSS では属性セレクタを使って、リンク先のドメインを前方一致で指定。とは言え自分のサイトなので、アカウント ID まで含む完全な URI を書いちゃってもいいんだけど。例によって IE6 では無効なので、デフォルトの背景色も忘れずに。</p>
<pre><code class="language-css">#elsewhere a {
background: #0080ff;
color: white;
}
#elsewhere a[href^="http://twitter.com/"] {
background: #33ccff;
}
#elsewhere a[href^="http://delicious.com/"] {
background: #3274d0;
}
#elsewhere a[href^="http://www.last.fm/"] {
background: #d51007;
}
#elsewhere a[href^="http://mixi.jp/"] {
background: #ff9900;
}
#elsewhere a:hover {
background: black;
}
</code></pre>
<p>ちょっと前だと、こういった属性セレクタを利用したスタイルを IE6 でも実現すべく jQuery のプラグインを書いたりしてたけど、もうぼちぼちその手のアプローチは必要ないかなと感じるようになってきた。</p>
Menlo と Mac の等幅フォント
2009-11-23T00:00:00Z
https://terkel.jp/archives/2009/11/menlo-and-monospaced-fonts-in-mac/
<p role="note">
<small>2010-05-17 更新: Opera 10.5 ではイタリックとボールドともに有効ですが、ボールドの太り方がやや弱いようです。</small>
<br />
<small>2009-12-21 更新: Firefox でイタリックまたはボールドを指定すると Menlo でレンダリングされない問題は修正されています。Opera ではイタリックとボールドは無効ですが、Menlo のレギュラーでレンダリングされるようになっています。</small>
</p>
<hr />
<figure>
<img decoding="async" alt="Menlo のスクリーンショット" src="https://terkel.jp/img/menlo-font-book.png" />
</figure>
<p>Mac の Snow Leopard には新しい等幅 (固定幅) フォント <strong>Menlo</strong> がインストールされている。なかなか美しいのでさっそく CSS で使ってみようと思ったんだけど、どうも挙動がおかしいので検証してみた。</p>
<p>まずはじめに以下の CSS を試してみる:</p>
<pre><code class="language-css">code {
font-family: "Menlo", "Courier", monospace;
}
</code></pre>
<p>そのレンダリング結果はこのとおり:</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/menlo-safari.png" />
<figcaption>Safari 4.0</figcaption>
</figure>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/menlo-firefox.png" />
<figcaption>Firefox 3.5</figcaption>
</figure>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/menlo-opera.png" />
<figcaption>Opera 10</figcaption>
</figure>
<p>意図どおりレンダリングされたのは Safari だけだった。Firefox ではレギュラーのみ Menlo で、イタリックまたはボールドでは第 2 候補の Courier が適用されている。Opera では第 2 候補どころかブラウザのデフォルトになってしまう (この場合はヒラギノ。イタリックになっていないのはヒラギノがイタリックを持っていないためと思われる) 。</p>
<p>そこで以下のように <code>@font-face</code> ルールをからめると、Firefox でもボールドとイタリックで表示させることができる:</p>
<pre><code class="language-css">@font-face {
font-family: "Menlo";
src: local("Menlo Regular");
}
code {
font-family: "Menlo", "Courier", monospace;
}
</code></pre>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/menlo-firefox-2.png" />
<figcaption>Firefox 3.5</figcaption>
</figure>
<p>しかしこの場合、Safri と比べると微妙に字形が異なる。これはおそらく、用意されている「本当の」イタリックやボールドではなく、<code>@font-face</code> で指定している Menlo Regular をブラウザのレンダリングで擬似的にボールドやイタリックに見せているのだと思われる。そのためレギュラーとボールドで字幅が異なり、「等幅」とは呼び難いものになってしまう。</p>
<p>しかも Opera ではやはり無効。<code>@font-face</code> の記述をいろいろと試してみたけど、どうやら <code>Menlo</code> というキーワードが出たとたんに挙動がおかしくなるらしい、ってとこまでしかわからなかった。ていうか <code>@font-face</code> ってほとんど初めて書いたので自信なし。</p>
<p>というわけで、そもそも等幅でレンダリングされないというのは無視できないので、少なくとも今のところ CSS で Menlo を指定するのは危険だ。<a href="http://www.adobe.com/jp/support/kb/ts/236/ts_236035_ja-jp.html" title="Mac OS X 10.6 で Menlo フォントを使用すると強制終了やプログラムエラーが発生する (Photoshop/Premiere Pro CS3-CS4)">Photoshop で使うとエラーが発生</a> したり、Keynote でおかしな表示になったりと、まだ未完成な製品ということなのだろうか。なかなかかっこいいフォントだと思うのでぜひ使いたいのだけど。</p>
<p>ちなみに、同じく Mac OS X の等幅フォントである <strong>Monaco</strong> でも「ボールドとイタリックが用意されていない問題」が発生する。Safari と Firefox ではブラウザが擬似的にレンダリングするため字幅がおかしくなり、Opera ではすべてレギュラーにしかならない:</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/monaco-safari.png" />
<figcaption>Safari 4.0</figcaption>
</figure>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/monaco-firefox.png" />
<figcaption>Firefox 3.5</figcaption>
</figure>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/monaco-opera.png" />
<figcaption>Opera 10</figcaption>
</figure>
<p>結論: Mac OS X 向けの等幅フォントを CSS で指定するなら <del datetime="2009-11-30">Courier</del> <a href="https://terkel.jp/archives/2009/11/courier-courier-new-and-consolas/"><ins datetime="/archives/2009/11/courier-courier-new-and-consolas/">Courier New</ins> が無難</a>。</p>
Courier、Courier New、Consolas
2009-11-30T00:00:00Z
https://terkel.jp/archives/2009/11/courier-courier-new-and-consolas/
<p><a href="https://terkel.jp/archives/2009/11/menlo-and-monospaced-fonts-in-mac/" title="Menlo と Mac の等幅フォント - terkel.jp">前回の記事</a> では CSS で Mac 向けに等幅フォントを指定する際の注意点を取り上げ、<strong>Menlo</strong> と <strong>Monaco</strong> はあまりおすすめできない、<strong>Courier</strong> が無難、と結論づけた。しかしそこでは Courier とその改訂版である <strong>Courier New</strong> について検証していなかったし、それに Windows 環境をまるで考慮していなかった。そこで今回は前回の補足として、CSS で等幅フォントを指定するベターな方法をさらにしつこく探ってみたい。</p>
<p>ではまず Courier と Courier New の Mac でのレンダリングを確認してみる。少なくとも v10.3 (Panther) 以降の Mac OS X にはどちらのフォントもあらかじめインストールされている。以下は Mac OS X v10.6 (Snow Leopard) + Safri 4.0 でのスクリーンショット:</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/courier-mac.png" />
<figcaption>Courier (Mac)</figcaption>
</figure>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/courier-new-mac.png" />
<figcaption>Courier New (Mac)</figcaption>
</figure>
<p>ともにレギュラー、イタリック、ボールド、ボールド・イタリックの 4 書体が用意されており、レンダリングに問題は見受けられない。では Windows ではどうだろうか。以下は Windows XP SP3 + IE8 でのスクリーンショット:</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/courier-win.png" />
<figcaption>Courier (Windows)</figcaption>
</figure>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/courier-new-win.png" />
<figcaption>Courier New (Windows)</figcaption>
</figure>
<p>Courier のレンダリングが Mac と大きく異なる。イタリックは極端に傾きすぎで判読しづらいうえ、とくに IE8 では一部の文字が完全につぶれてしまうし、ボールドはレギュラーと字幅が異なる (「等幅」ではなくなってしまう)。レギュラーのみを使うのでなければ、実用に堪えるものではないと思う。</p>
<p>というわけで、<a href="https://terkel.jp/archives/2009/11/menlo-and-monospaced-fonts-in-mac/" title="Menlo と Mac の等幅フォント - terkel.jp">前回</a> の検証結果「Menlo は Firefox と Opera で正しく認識されない」と「Monaco はイタリックとボールドが用意されていない」、そして今回の「Courier のイタリックとボールドは Windows で使えない」をあわせて考えると、<strong>CSS で等幅フォントを指定する際にもっとも「安全」なのは Courier New</strong>、ということになる。なんか面白味のない結論で申し訳ないけど。</p>
<pre><code class="language-css">code {
font-family: "Courier New", monospace;
}
</code></pre>
<p>なお、もし Mac と Windows での見栄えの違いにさほどこだわらないのであれば、Windows 向けに <strong>Consolas</strong> を指定するのもおすすめ。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/consolas.png" />
<figcaption>Consolas</figcaption>
</figure>
<p>Consolas は Windows Vista や Office 2007 などに同梱されるフォントだが、無償の <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=048dc840-14e1-467d-8dca-19d2a8fd7485&DisplayLang=ja" title="ダウンロードの詳細: PowerPoint Viewer 2007">PowerPoint Viewer 2007</a> をインストールすることでも入手できる。イタリックの特徴的な字形 (i、j、k、l など) は好みの分かれるところかもしれないが、個人的にはかなり美しいと思う。とくに Courier 系に比べて横幅がスリムである点に注目してほしい。ソースコードなど、なるべく折り返さず 1 行に収めたい場合にうれしい。とはいえ Vista 以前の Windows の多くにはインストールされていないので、第 1 候補が Conslas、なければ Courier New、という指定が望ましい:</p>
<pre><code class="language-css">code {
font-family: "Consolas", "Courier New", monospace;
}
</code></pre>
<p>このほかに Windows でインストール率の高い等幅フォントとして <strong>Lucida Console</strong> があるが、Monaco などと同様にイタリックとボールドを持たないため、あまりおすすめしない。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/lucida-console.png" />
<figcaption>Luciad Console</figcaption>
</figure>
CSS のみで吹き出し
2009-12-06T00:00:00Z
https://terkel.jp/archives/2009/12/css-only-speech-bubbles/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/css-only-speech-bubles.png" />
</figure>
<p><a href="http://hail2u.net/blog/webdesign/pure-css-speech-bubble.html">hail2u.net - Weblog - Pure CSS な吹き出し</a> に触発されて、画像や JavaScript を使わずに CSS だけを使って「吹き出し」を作る方法を僕も考えてみた。</p>
<ul>
<li><a href="https://terkel.jp/demo/css-only-speech-bubbles.html">Demo: CSS のみで吹き出し</a></li>
</ul>
<p>マークアップは 2 重の要素があれば OK。ここではそれぞれ <code>bubble</code> と <code>body</code> というクラスを付与した <code>div</code> と <code>p</code> を例に説明する:</p>
<pre><code class="language-html"><div class="bubble">
<p class="body">Speech!</p>
</div>
</code></pre>
<p>CSS の最低限必要な部分のみを抜き出すと以下のとおり。これは背景が黒いボックスの下に左向きのしっぽを出す場合の例:</p>
<pre><code class="language-css">.bubble {
float: left; /* または position: absolute; */
border-left: 10px solid black;
border-bottom: 10px solid transparent;
-border-bottom-color: white; /* for IE6 */
}
.bubble .body {
float: left; /* または width を明示 */
margin-left: -20px;
background: black;
color: white;
-position: relative; /* for IE6 */
}
</code></pre>
<p>外側の <code>.bubble</code> は吹き出しの「しっぽ」部分を担当する。「ボディ」の幅は内側の要素によって決定するので、ここでは <code>width</code> を指定せず、<code>position: absolute;</code> を指定するか、左右どちらかにフロートさせる。しっぽ部分は隣接する 2 辺のボーダーの組み合わせによって作られる。このテクニックはいろんなサイトで紹介されているので詳細は省略。ただ、IE6 は <code>border-color</code> プロパティの値として <code>transparent</code> が無効なので、吹き出しがテキストや画像に重なる可能性がある場合は難しい。背景が単色なら上記のように背景色を明示してしまえばいける。</p>
<p>内側の <code>.body</code> は吹き出しのボディ部分。幅を固定する場合は <code>width</code> プロパティに値を明示し、またもしこの要素がインライン要素なら <code>display: block;</code> でブロック要素化する。テキストの量による可変幅にするなら左右どちらかにフロート。ここまでだとしっぽがボディの外側にある状態なので、マージンにマイナス値を指定して外側の要素の外側にはみ出させることにより、しっぽをボディの内側まで移動させる。</p>
<p>あとは、<code>.bubble</code> のボーダーの太さでしっぽの大きさを調整したり、<code>.body</code> に <code>border-radius</code> を指定したりして装飾する。ちなみに IE ではしっぽの角度を 45° に (つまり <code>.bubble</code> の 2 辺のボーダーの太さを同じに) しないと斜めのラインが汚くなるようなので注意。<a href="https://terkel.jp/demo/css-only-speech-bubbles.html">デモ</a> にはいくつかのパターンを用意したのでご参考にされたし。</p>
<p>さっそくこのサイトでもブログ記事のコメント数を表示するのに採用してみたけど、「0」ばかりで軽く落ち込んだ。</p>
Yet Another Related Posts Plugin
2009-12-15T00:00:00Z
https://terkel.jp/archives/2009/12/yet-another-related-posts-plugin/
<p>WordPress で関連記事をリストアップするプラグイン、<a href="http://mitcho.com/code/yarpp/">Yet Another Related Posts Plugin</a> (YARPP) を導入してみた。同様のプラグインは多数あるけど、出力結果をテンプレートで柔軟にコントロールできるところが気に入って選んだ。<a href="http://www.mattcutts.com/blog/wordpress-plugin-related-posts/" title="Best WordPress Plugin for Related Posts? - Matt Cutts: Gadgets, Google, and SEO">Google のエンジニアのお墨付き</a> ってのも魅力。</p>
<p>出力結果をカスタマイズするには、まずテンプレートを用意する必要がある。プラグインの <code>yarpp-templates</code> フォルダの中に <code>yarpp-template-example.php</code> というファイルがあるので、これを使用中のテーマのディレクトリにコピーし、適当な名前に変更した上で編集する。テンプレートの中身は <code>yarpp-template-example.php</code> を参考にすればごく簡単。ちなみにファイル名は <code>yarpp-template-</code> ではじまっていないと YARPP のテンプレートと認識されないので注意。</p>
<p>こうして用意したテンプレートをテーマのディレクトリにアップロードしたら YARPP 管理画面へ。「表示設定 (ウェブサイト用)」セクションにある「テンプレートを使って表示」にチェックを入れ、自作のテンプレートを選択する。ちなみにリストの挿入箇所をカスタマイズするには、管理画面で「自動的に関連記事を表示する」のチェックをはずし、テンプレートの任意の箇所に <code><?php related_posts() ?></code> を記述すればいい。</p>
<p>あとはフィルターや関連スコアの設定をいじって出力結果を調整。この部分はしばらく運用してみないと勘がつかめないな。</p>
Lamy safari
2009-12-20T00:00:00Z
https://terkel.jp/archives/2009/12/lamy-safari/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/lamy-safari.jpg" />
</figure>
<p>はじめて万年筆を買った。<a href="http://www.lamy.com/ger/b2c/safari/018">Lamy safari のイエロー</a>、ニブは EF。カートリッジではなくコンバータを使うことにして、インクはブルーブラックを選んだ。お店は高田馬場の <a href="http://www.chikuho.com/">竹宝商会</a>。</p>
<p>コンバータにインクを吸い上げるとき、インク壺にペンをどこまで突っ込んでよいのかわからず何度か空振りしてしまった。どうもペン軸までどっぷりつけるものらしい。</p>
<p>書き味やなんかについては、なにせはじめての万年筆なのでほかと比べてどうこうとは言えないのだけど、とりあえず今まで使ってきた 3 色ボールペンとは当然のことながらまるで違い、「ペンの先から紙にインクを流し込んでいる」ような感覚がとても新鮮。力の入れ具合で微妙な色ムラができるところや、乾くと色合いが落ち着いて「インクが紙に定着した」感じになるところも楽しい。</p>
俺の CSS リセット: 2009 冬
2009-12-26T00:00:00Z
https://terkel.jp/archives/2009/12/my-css-reset-2009-winter/
<p>各ブラウザが持つデフォルトのスタイルをいったんリセットし、のちのスタイル指定を容易にするための「CSS リセット」。どこまでリセットするかは難しいところで、俺も常に試行錯誤を続けていますが、この頃はだいたいこんなふうにしてます:</p>
<pre><code class="language-css">html, body, div, h1, h2, h3, h4, h5, h6,
p, ul, ol, li, dl, dt, dd, address, hr,
pre, blockquote, ins, del, form, fieldset, legend,
table, caption, thead, tfoot, tbody, tr, th, td {
padding: 0;
margin: 0;
}
h1, h2, h3, h4, h5, h6 {
font-size: 1em;
}
ul p, ol p, dl p, table p,
ul ul, ol ul, dl ul, table ul,
ul ol, ol ol, dl ol, table ol,
ul dl, ol dl, dl dl, table dl,
ul pre, ol pre, dl pre, table pre,
ul table, ol table, dl table, table table {
font-size: 1em;
margin: 0;
}
pre {
white-space: pre-wrap;
word-wrap: break-word;
}
img, object {
border: 0;
vertical-align: bottom;
}
sub {
line-height: 1;
vertical-align: text-bottom;
}
sup {
line-height: 1;
vertical-align: text-top;
}
q:before, q:after {
content: "";
}
fieldset {
border: 0;
}
input, button, select, optgroup, option, textarea {
background: inherit;
color: inherit;
font-family: inherit;
font-style: inherit;
font-variant: normal;
font-weight: inherit;
font-size: 1em;
letter-spacing: normal;
word-spacing: normal;
text-transform: none;
}
</code></pre>
<p>簡単に説明すると、主に以下のようなことをやっています:</p>
<ul>
<li>ブロックレベル要素の <code>padding</code> と <code>margin</code> をリセット</li>
<li>見出しの <code>font-size</code> をリセット</li>
<li>テキスト系の要素が入れ子になった場合の <code>font-size</code> と <code>margin</code> をリセット</li>
<li><code>pre</code> 要素の長いテキストを折り返す指定</li>
<li><code>sub</code> 要素と <code>sup</code> 要素の水平位置はブラウザ間の差異が大きいので調整</li>
<li>フォームのコントロールにおけるタイポグラフィの継承を調整</li>
</ul>
<p>とくにフォーム関連はどこまでいじるか悩むところですが、コントロールにおけるタイポグラフィの継承に重点を置いています。<code>background</code> プロパティを指定しているのは、これがないと Safari と Chrome で <code>input</code> 要素の <code>submit</code>/<code>reset</code>/<code>button</code> タイプや <code>select</code> 要素のタイポグラフィが継承されないため。ちょっと記述がウザいかなとは思うんですが、個人的にいつもつまずくとこなのであえてこうしてます。</p>
<p><code>br</code> 要素の <code>letter-spacing</code> プロパティとか <code>legend</code> 要素の <code>color</code> プロパティといった、かつてはよく加えていた IE6 向けの指定をなるべくけずるようにしているので、以前に比べてだいぶすっきりしてきました。</p>
Best of 2009: 音楽
2009-12-31T00:00:00Z
https://terkel.jp/archives/2009/12/best-of-2009-music/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/best-of-2009-music-beatles.jpg" />
</figure>
<p>我ながらびっくりするほど新譜を聴かない 1 年だった。その隠居っぷりは <a href="https://terkel.jp/archives/2008/12/best-of-2008-music/">昨年</a> の比ではない。そこで仕方なく、Best of というよりも、新旧問わず「<strong>今年よく聴いたものチャート</strong>」を作ってみた。そしてこのチャートがまたびっくりするほどつまらないものになってしまった。ソースは <a href="http://www.last.fm/user/terkeljp/charts" title="terkeljp’s Charts – Users at Last.fm">Last.fm</a> で、過去 12 か月の再生回数を元にしている。</p>
<h2>アーティスト</h2>
<ol>
<li><a href="http://www.thebeatles.com/">The Beatles</a></li>
<li><a href="http://www.u2.com/">U2</a></li>
<li><a href="http://www.radiohead.com/">Radiohead</a></li>
<li><a href="http://www.rollingstones.com/">The Rolling Stones</a></li>
<li>RC Succession</li>
<li><a href="http://www.xtcidearecords.co.uk/">XTC</a></li>
<li><a href="http://www.thestoneroses20.com/">The Stone Roses</a></li>
<li><a href="http://www.michaeljackson.com/">Michael Jackson</a></li>
<li>The Blue Hearts</li>
<li><a href="http://www.thepees.com/">The ピーズ</a></li>
</ol>
<p>時系列でいうと、U2 → 清志郎 → マイケル → ビートルズ。時の流れに身をまかせ。レディオヘッドやストーン・ローゼズはリイシューが出たため。ブルハとピーズは、まあそういう気分だったってことでしょう。再生回数でいうと、ビートルズが 3,000 回以上でダントツ、U2 が 800 回、以下 400 から 200 回、みたいな感じ。とにかく 9 月以降はビートルズしか聴いてない。</p>
<h2>アルバム</h2>
<ol>
<li>The Beatles - Mono Masters (<a href="http://www.amazon.co.jp/o/ASIN/B002FVPL9W/terkel-22">The Beatles in Mono</a>)</li>
<li>The Beatles - <a href="http://www.amazon.co.jp/o/ASIN/B00267L6UI/terkel-22">The Beatles</a></li>
<li>U2 - <a href="http://www.amazon.co.jp/o/ASIN/B001O5M3UK/terkel-22">No Line on the Horizon</a></li>
<li>The Beatles - <a href="http://www.amazon.co.jp/o/ASIN/B00267L6TO/terkel-22">Revolver</a></li>
<li>The Beatles - <a href="http://www.amazon.co.jp/o/ASIN/B00267L6S0/terkel-22">Please Please Me</a></li>
<li>RC Succession - <a href="http://www.amazon.co.jp/o/ASIN/B000BDJ6CO/terkel-22">Baby a Go Go</a></li>
<li>The Beatles - <a href="http://www.amazon.co.jp/o/ASIN/B00267L6SK/terkel-22">A Hard Day’s Night</a></li>
<li>The Beatles - <a href="http://www.amazon.co.jp/o/ASIN/B00267L6SA/terkel-22">With the Beatles</a></li>
<li>The Beatles - <a href="http://www.amazon.co.jp/o/ASIN/B00267L6TY/terkel-22">Sgt. Pepper’s Lonely Hearts Club Band</a></li>
<li>The Beatles - <a href="http://www.amazon.co.jp/o/ASIN/B00267L6U8/terkel-22">Magical Mystery Tour</a></li>
</ol>
<p>トラックの再生回数で集計しているため、単純にトラック数の多いビートルズの 2 枚組が上位に。1 位の『モノ・マスターズ』は『<a href="http://www.amazon.co.jp/o/ASIN/B00267L6VM/terkel-22">パスト・マスターズ</a>』のモノラル版で、バラ売りはされておらずボックス・セットにのみ収録。とにかくこのボックスをひたすら聴いてた。とくに好きなのは『ホワイト・アルバム』のディスク 1。3 位の U2 は実はあんまり好きじゃない。『ポップ』以来の失敗作、は言い過ぎだけど、ここ 2 作の充実度がハンパなかっただけに、まあディスコグラフィ的にここらでこういうのがあってもいいか、というのが僕の評価です。それよか YouTube でやったギグの生中継のが印象に残る。ちなみに Baby a Go Go は RC の最高傑作ですので。念のため。リンク先は Amazon。</p>
<h2>トラック</h2>
<ol>
<li>U2 - <a href="http://www.youtube.com/watch?v=pmJgdXkAqMU" title="YouTube - U2 - I'll Go Crazy If I Don't Go Crazy Tonight">I’ll Go Crazy If I Don’t Go Crazy Tonight</a></li>
<li>U2 - <a href="http://www.youtube.com/watch?v=7jMaRxLdjXI" title="YouTube - U2 - Get on Your Boots (Live from the Rose Bowl)">Get on Your Boots</a></li>
<li>U2 - <a href="http://www.youtube.com/watch?v=ZafL4H0Ooa8" title="YouTube - U2 - Magnificent (Live from Somerville Theatre)">Magnificent</a></li>
<li>The Beatles - I Saw Her Standing There</li>
<li>The Beatles - Love Me Do</li>
<li>The Beatles - Please Please Me</li>
<li>The Beatles - Twist and Shout</li>
<li>The Beatles - We Can’t Work It Out</li>
<li>The Beatles - All I’ve Got to Do</li>
<li>The Beatles - It Won’t Be Long</li>
</ol>
<p>U2 の I’ll Go Crazy はアルバム中もっとも U2 らしい、いわば保守的な曲。ビートルズに初期の曲が多いのは、いきなり全作品を聴かず、リリース順に自分をじらしつつ 1 枚ずつ聴くという縛りプレイをしていたため。でも『サージェント・ペパー』あたりでどうでもよくなり、結局はぐちゃっと一気に聴いた。</p>
<h2>来年の抱負</h2>
<p>年明け早々に、LCD Soundsystem とか Spoon とか Vampire Weekend とか、気になる新譜が出るのでちゃんと追いかけたいです。ていうかちゃんと働きます。</p>
Font Squirrel で始める @font-face
2009-12-31T00:00:00Z
https://terkel.jp/archives/2009/12/font-face-with-font-squirrel/
<p>書式が複雑、IE 向けの EOF ファイルを用意するのが面倒、ライセンスが英語でわからん、などの理由から CSS の <code>@font-face</code> にとっつきにくさを感じている人は少なくないと思います。そのあたりのハードルをかなり下げてくれそうなサイトが、<a href="http://www.fontsquirrel.com/">Font Squirrel</a> です。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/fontsquirrel-1.jpg" />
</figure>
<p>「商用利用可能で高品位なフォントが無料で!」というようなよくあるサイトのように見えますが、違います。このサイトの最大の特長は <strong><code>@font-face</code> を強力にサポート</strong> してくれるところにあります。</p>
<p>このサイトを利用して <code>@font-face</code> を導入するには、ファイル一式がすでに用意されている <strong>@font-face Kits</strong> をダウンロードする方法と、<strong>@font-face Generator</strong> でファイルを生成する方法があります。前者のほうがより簡単ですが、どちらの方法でも <code>@font-face</code> のわずらわしさをかなり軽減してくれることは間違いありません。それぞれの利用方法について説明していきます。</p>
<h2>@font-face Kits</h2>
<p>まず最初に、サイトの<a href="http://www.fontsquirrel.com/fontface" title="Font Squirrel | Download Hundreds of Free @font-face Fonts">@font-face Kits</a> ページへ移動します。かなりの数のフォントが並んでいますが、この中から利用したいフォントを選びます。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/fontsquirrel-2.jpg" />
</figure>
<p>お目当てのフォントが見つかったら、サムネイルをクリックして、フォントの詳細ページへ移動します。ここでは <a href="http://www.theleagueofmoveabletype.com/">The League of Movable Type</a> の <a href="http://www.fontsquirrel.com/fonts/League-Gothic">League Gothic</a> を例に話を進めます。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/fontsquirrel-3.jpg" />
</figure>
<p>データをダウンロードするには、右上に見えている Download OTF というボタンはではなく、その下の <strong>@font-face Kit</strong> というリンクをクリックします。すると <strong>Download @font-face Kit</strong> というボタンが出現するので、ZIP 形式の「キット」をダウンロードします。またこのページでは、実際にタイプしたテキストでテストしたり、ライセンスを確認したりもできます。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/fontsquirrel-4.jpg" />
</figure>
<p>ダウンロードした ZIP を解凍すると、以下のファイルが含まれています (League Gothic の場合):</p>
<ul>
<li><code>League_Gothic.eot</code></li>
<li><code>League_Gothic.otf</code></li>
<li><code>League_Gothic.svg</code></li>
<li><code>League_Gothic.woff</code></li>
<li><code>demo.html</code></li>
<li><code>stylesheet.css</code></li>
<li><code>SIL Open Font License 1.1.txt</code></li>
</ul>
<p>このうち、まずは 4 つのフォントファイルをサイトのしかるべきディレクトリに置きます。</p>
<p>最後に CSS の編集です。<code>stylesheet.css</code> には以下のように <code>@font-face</code> があらかじめ記述されています (読みやすいよう改行しています):</p>
<pre><code class="language-css">@font-face {
font-family:
'LeagueGothicRegular';
src:
url('League_Gothic.eot');
src:
local('League Gothic Regular'),
local('LeagueGothic'),
url('League_Gothic.woff') format('woff'),
url('League_Gothic.otf') format('opentype'),
url('League_Gothic.svg#LeagueGothic') format('svg');
}
</code></pre>
<p>この部分をまるごと任意の CSS ファイルにコピーし、<code>src</code> プロパティの <code>url</code> 値をフォントファイルまでのパスに書き換えます。また、フォントによっては CSS や HTML ファイルにクレジットの記載が必要な場合があるので注意してください。</p>
<p>ちなみにこの <code>@font-face</code> の書式は <a href="http://paulirish.com/">Paul Irish</a> 氏の<a href="http://paulirish.com/2009/bulletproof-font-face-implementation-syntax/">Bulletproof @font-face syntax</a> に基づいており、CSS ファイルにもその旨がクレジットされています。書式についての詳細はリンク先を参照してください。</p>
<p>以上で準備は完了です。これで <code>@font-face</code> で定義したフォントをいつでも指定できます。実際に動作しているデモを用意したので試してみてください:</p>
<ul>
<li><a href="https://terkel.jp/demo/font-squirrel-font-face-1.html">Demo #1: League Gothic</a></li>
</ul>
<p>なお、この @font-face Kit パッケージで配布されているフォントはすべて <code>@font-face</code> での利用が可能であるはずですが、ライセンスにはひととおり目を通しましょう。ライセンスは各フォントのページから参照できます。</p>
<h2>@font-face Generator</h2>
<p>このサイトのもうひとつの売りは <a href="http://www.fontsquirrel.com/fontface/generator">@font-face Generator</a> です。上記 @font-face Kit パッケージが用意されていないフォントでも、この機能を使えば簡単に「キット」を作成することができます。</p>
<p>まずはフォントを選びましょう。ここでは <a href="http://www.exljbris.nl/">exljbris Font Foundry</a> の <a href="http://www.fontsquirrel.com/fonts/Museo-Sans">Museo Sans</a> を例に解説します。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/fontsquirrel-6.jpg" />
</figure>
<p>このフォントは @font-face Kit が用意されておらず、ダウンロードできるのは OTF フォーマットのみです。では <code>@font-face</code> での利用はできないのかというとそうではなく、<a href="http://www.fontsquirrel.com/license/Museo-Sans">ライセンス</a> を読むとこのように記載されています:</p>
<blockquote cite="http://www.fontsquirrel.com/license/Museo-Sans" lang="en">
<p>You may use this font for Font-Face embedding, but only if you put a link to http://www.exljbris.nl on your page and/or put this notice /* A font by Jos Buivenga (exljbris) -> http://www.exljbris.nl */ in your CSS file as near as possible to the piece of code that declares the Font-Face embedding of this font.</p>
</blockquote>
<p>つまり、ページまたは CSS ファイルにクレジットを記載すれば <code>@font-face</code> で利用して構いませんよ、ということです。しかし IE での表示に必要な EOF フォーマットは用意されていないので、この @font-face Generator で生成する必要があります。@fonta-face Kit を利用するのに比べて手間はかかりますが、それでもとても簡単です。</p>
<p>まずは OTF フォントをダウンロードします。ページ右上の <strong>Download OTF</strong> ボタンをクリックすると、外部サイトである <a href="http://new.myfonts.com/fonts/exljbris/museo-sans/" title="Museo Sans™ font family « MyFonts">MyFonts</a> に移動します。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/fontsquirrel-7.jpg" />
</figure>
<p>この Museo Sans ファミリーのうち、価格が $0 の <a href="http://new.myfonts.com/fonts/exljbris/museo-sans/500/">Museo Sans 500</a> と <a href="http://new.myfonts.com/fonts/exljbris/museo-sans/500-italic/">Museo Sans 500 Italic</a> をカートに入れ、$0 で購入します。なおこの際ユーザ登録が必要です。お会計が終わったら ZIP 形式でデータをダウンロードします。</p>
<p>ダウンロードが完了したら再び Font Squirrel に戻り、<a href="http://www.fontsquirrel.com/fontface/generator">@font-face Generator</a> ページへ。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/fontsquirrel-5.jpg" />
</figure>
<p><strong>Add Fonts</strong> ボタンをクリックし、さきほどダウンロードした OTF ファイルをアップロードします。Museo Sans はレギュラーとイタリックの 2 書体ですが、同時に処理することが可能です。</p>
<p>次にフォームの <strong>Agreement</strong> 欄、<strong>Yes, the fonts I'm uploading are legally eligible for web embedding.</strong> にチェックを入れます。これはつまり、「私がアップロードしているフォントは <code>@font-face</code> での利用が許されています」という宣言です。しつこいようですがライセンスを必ず確認しましょう。ここにチェックを入れない限りデータはダウンロードできません。</p>
<p>そのほかいくつかオプションのチェック項目がありますが、正直に言ってよくわからない項目が多いです。とりあえずデフォルトのままダウンロードしてみて、テストの結果が思ったとおりにならなかった場合にやり直す、というのでもいいのではないでしょうか (いい加減で申し訳ないです…)。</p>
<p>最後に「キット」をダウンロードします。あとは @font-face Kit の場合と同様ですが、CSS ファイルにクレジットを入れるのを忘れないように。</p>
<ul>
<li><a href="https://terkel.jp/demo/font-squirrel-font-face-2.html">Demo #2: Museo Sans</a></li>
</ul>
<p>いまのところ和文での利用は難しいですが、欧文のみに限られる部分、たとえばナビゲーションとか見出しとか日付とかにはビシビシ使ってみてよいのではないでしょうか。とくにブログのテーマなんかを作る場合、テーマのディレクトリ内にフォントも同梱しておけば、かなりデザインの幅が広がります。</p>
<p>とは言え実際に <code>@font-face</code> を使ってみて思ったのは、選択肢が一気に増えすぎるせいで、いともたやすくまとまりのないデザインになってしまうんですね。今までの「Arial か Verdana か Georgia ぐらいしか使えねー」っていう束縛が、逆に統一感を約束してくれてもいたのかなー、と思った次第です。</p>
Happy New Year 2010
2010-01-01T00:00:00Z
https://terkel.jp/archives/2010/01/happy-new-year-2010/
<p id="happy-new-year-2010" style="
position: relative;
width: 720px;
height: 720px;
padding: 0;
margin: 30px 0 30px -176px;
border-radius: 360px;
-moz-border-radius: 360px;
-webkit-border-radius: 360px;
background-color: red;
background-image:
linear-gradient(
top,
rgba(255, 255, 255, 0.5),
rgba(255, 255, 255, 0)
);
background-image:
-moz-linear-gradient(
top,
rgba(255, 255, 255, 0.5),
rgba(255, 255, 255, 0)
);
background-image:
-webkit-gradient(
linear,
left top,
left bottom,
color-stop(0, rgba(255, 255, 255, 0.5)),
color-stop(1, rgba(255, 255, 255, 0))
);
filter:
progid:DXImageTransform.Microsoft.Gradient(
StartColorStr='#80ffffff',
EndColorStr='#00ffffff'
);
"><span style="
position: absolute;
top: 50%;
left: 0;
width: 100%;
font: 120px/1em 'League Gothic', 'Impact', sans-serif;
margin: -0.5em 0 0;
color: white;
text-align: center;
text-shadow: 0 -1px 0 maroon;
">Happy New Year 2010</span></p>
リデザイン!
2010-02-02T00:00:00Z
https://terkel.jp/archives/2010/02/redesign/
<p>約 1 年半ぶりにサイトをリデザインした。細かいところはまだいろいろといじると思うけど、とりあえずおもな変更点をまとめておきたい。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/redesign-2010-before.jpg" />
<figcaption>Before: Vesion 2.1</figcaption>
</figure>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/redesign-2010-after.jpg" />
<figcaption>After: Version 3.0</figcaption>
</figure>
<h2>レイアウト</h2>
<p>ページ全体は 768px の固定幅、左寄せ。本文部分の左側 4 分の 1 を余白にして、画像やソースコードなどをはみ出させるレイアウトを試しに採用。<a href="http://jasonsantamaria.com/">Jason Santa Maria</a> や <a href="http://www.maratz.com/blog/">maratz.com</a> あたりをパクってる。</p>
<h2>タイポグラフィ</h2>
<p>リデザインしたかった最大の理由が、ヘッダ。以前は Helvetica/Arial をかなり大きめに配置してたけど、さすがに邪魔に感じてきて、スッキリさせたかった。そこで、ロゴとグローバル・ナビゲーション、および見出しの一部に <code>@font-face</code> で <a href="http://www.theleagueofmoveabletype.com/">The League of Movable Type</a> の <a href="http://www.theleagueofmoveabletype.com/fonts/7-league-gothic">League Gothic</a> を採用。フォントファイル一式は、以前このブログでも <a href="https://terkel.jp/archives/2009/12/font-face-with-font-squirrel/">紹介</a> した <a href="http://www.fontsquirrel.com/">Font Squirrel</a> から入手した。ちなみに CSS はこんな感じ:</p>
<pre><code class="language-css">@font-face {
font-family:
"League Gothic";
src:
url("/fonts/League_Gothic.eot");
src:
local("League Gothic Regular"),
local("LeagueGothic"),
url("/fonts/League_Gothic.woff") format("woff"),
url("/fonts/League_Gothic.otf") format("opentype"),
url("/fonts/League_Gothic.svg#LeagueGothic") format("svg");
}
.page-header .logo,
.page-header .nav.global {
font-family: "League Gothic", "Arial Narrow", sans-serif;
}
</code></pre>
<p>なお、<code>@font-face</code> は読み込まれる際にスタイルの適用されていない状態が一瞬見えてしまう場合がある。この現象を FOUT (Flash of Unstyled Text) と呼ぶらしい。</p>
<ul>
<li><a href="http://paulirish.com/2009/fighting-the-font-face-fout/">Fighting the @font-face FOUT - Quicken the load time « Paul Irish</a></li>
<li><a href="http://24ways.org/2009/designing-for-the-switch">24 ways: Designing For The Switch</a></li>
</ul>
<p>対策のひとつとして、<code>@font-face</code> で指定したフォントに似ていて、かつインストール率の高いフォントをフォールバックとして指定するという手がある。そうすれば、<code>@font-face</code> フォントに切り替わったときに違和感が少ない、という考え。というわけでとりあえずここでは Arial Narrow を指定してみたけど、League Gothic と似ているとは言いがたいので、FOUT 対策としてはかなり微妙。</p>
<p>そのほかの部分は今までと変わらず Helvetica/Arial、等幅は Menlo/Consolas。和文フォントは指定せず、ブラウザの設定に依存。基本の CSS は以下の通り:</p>
<pre><code class="language-css">body {
font: 15px/1.67 "Helvetica Neue", "Helvetica", "Arial", sans-serif;
}
code, kbd, samp {
font-family: "Menlo", "Consolas", "Courier New", monospace;
}
</code></pre>
<h2>カラー</h2>
<p>今までは背景色 <code>white</code> (<code>#ffffff</code>) に前景色 <code>black</code> (#000000)、そしてリンクは <code>#0080ff</code> という、かなりざっくりした配色だったんだけど、このサイトは横幅がせまくて画像やボーダーなどが少ないこともあり、かなりまぶしく感じることがあった。そこで今回は、背景をごく薄いオフホワイトの <code>#fcfcf8</code>、前景はブラックに近いブルーの <code>#002040</code> にしてみた。イメージとしては、最近愛用の <a href="http://www.tsubamenote.co.jp/">ツバメノート</a> にブルーブラックのインクで書いた感じを狙っている。</p>
<p>そのほか、今までざっくりしていた反動で、<code>#f0f0e0</code> や <code>#e0e0c0</code> などのベージュ系、<code>#8090a0</code> のブルーグレイなど、僕にしては微妙な色も使ってるけど、微調整がめんどうなのでざっくりに戻すかも。</p>
<h2>コメント</h2>
<p>コメントフォームを廃止して、かわりに <a href="http://twitter.com/">Twitter</a> と <a href="http://b.hatena.ne.jp/">はてなブックマーク</a> での言及を収集して表示させることにした。はじめての試みなので、上手くいくかどうかやや不安。JavaScript から各種 API を利用してるんだけど、長くなるので詳しくは稿を改めて書きたい。</p>
Last.Fm Records
2010-02-04T00:00:00Z
https://terkel.jp/archives/2010/02/last-fm-records/
<p><a href="http://www.last.fm/">Last.fm</a> から、最近聴いてるアルバムや “Love” 登録した曲などのデータを取得して自分のサイトに表示する WordPress プラグイン、<a href="http://jeroensmeets.net/lastfmrecords/" title="Jeroen Smeets » Last.Fm Records">Last.Fm Records</a> を導入してみました。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/last-fm-records.jpg" />
</figure>
<p>プラグインをダウンロードして有効化すると、管理パネルの「設定」からオプションをいじれます。おもな項目は以下のとおり:</p>
<dl>
<dt>Last.fm username</dt>
<dd>Last.fm でのユーザー名。ちなみに、自分のデータのみならず「気になるあの人のお気に入りリスト」なんてのも可能。</dd>
<dt>Period</dt>
<dd>“Recent Tracks” や “Last 7 days” など、取得するデータの種類を選択。</dd>
<dt>Count</dt>
<dd>アイテムの件数。</dd>
<dt>Refresh time</dt>
<dd>Period が “Recent Tracks” の場合の更新頻度。</dd>
<dt>Off-set (from <abbr title="Greenwich Mean Time">GMT</abbr> +0)</dt>
<dd>用途不明。とりあえず日本なので +9。</dd>
<dt>Default thumb</dt>
<dd>ジャケ写がない場合のデフォルト画像。</dd>
<dt>Add stylesheet</dt>
<dd>あらかじめ用意されたスタイルを選べますが、あんまりクールじゃないので自分で書くのがおすすめ。</dd>
</dl>
<p>実際にページに表示するには、WordPress の「ウィジェット」機能を利用する手もありますが、テンプレートの中で表示させたい箇所に以下のコードを挿入しても OK です:</p>
<pre><code class="language-html"><div id="lastfmrecords"></div>
</code></pre>
<p>結果、以下のようなマークアップが生成されます:</p>
<pre><code class="language-html"><div id="lastfmrecords">
<ol>
<li style="display: inline;">
<a href="http://www.last.fm/music/Perfume/Perfume%3A+Complete+Best">
<img src="http://userserve-ak.last.fm/serve/126/41074031.jpg" id="lastfmcover0" title="Perfume: Complete Best by Perfume">
</a>
</li>
<li style="display: inline;">
<a href="http://www.last.fm/music/Perfume/GAME">
<img src="http://userserve-ak.last.fm/serve/126/29327629.png" id="lastfmcover1" title="GAME by Perfume">
</a>
</li>
<li style="display: inline;">
<a href="http://www.last.fm/music/Perfume/%E2%8A%BF">
<img src="http://userserve-ak.last.fm/serve/126/29542861.png" id="lastfmcover2" title="⊿ by Perfume">
</a>
</li>
. . .
</ol>
</div>
</code></pre>
<p>あとは CSS で整形すれば完成。<code>ol</code> で出力されるものの <code>li</code> にインラインで <code>display: inline;</code> が指定されている点に注意。例としてこのサイトでのスタイルを載せておきます:</p>
<pre><code class="language-css">#lastfmrecords ol {
overflow: hidden;
width: 100%;
padding: 5px 0 0;
margin: 0;
}
#lastfmrecords ol li {
display: block !important;
float: left;
margin: 0 2px 5px 0;
}
#lastfmrecords ol li a img {
max-width: 48px;
max-height: 48px;
padding: 1px;
border: 1px solid silver;
}
#lastfmrecords ol li a:hover img {
border-color: #002040;
}
</code></pre>
<p>ちなみに、プラグインの ZIP の中の <code>last.fm.records.js</code> は、WordPress でなくても jQuery プラグインとして使うことが可能。オプションの指定方法など、詳しくは <a href="http://jeroensmeets.net/projects/last.fm/" title="Last.Fm Records">作者のサイト</a> で解説されています。</p>
画像のマークアップを通じて Progressive Enhancement を理解する試み
2010-02-09T00:00:00Z
https://terkel.jp/archives/2010/02/understanding-progressive-enhancement/
<p><strong>Progressive Enhancement</strong> と <strong>Graceful Degradation</strong> って、ひょっとしてこういうことかな? という思いつき。</p>
<pre><code class="language-html"><img src="logo.png" alt="Google">
</code></pre>
<p>このマークアップを、「もし画像が利用<strong>できない</strong>場合はテキストで代替する」と読むのが Graceful Degradation。</p>
<p>「もし画像が利用<strong>できる</strong>場合は画像を表示する」と読むのが Progressive Enhancement。</p>
<p>わりと気に入ってるアイディアなんですが、どうでしょうか。Progressive Enhancement と Graceful Degradation について、詳しくは以下のリソースをどうぞ。</p>
<ul>
<li><a href="http://www.alistapart.com/articles/understandingprogressiveenhancement">A List Apart: Articles: Understanding Progressive Enhancement</a>
<ul>
<li>邦訳: <a href="http://www.867867.com/webstandards/29-progressiveenhancement.html">Progressive Enhancement とは? 日本語で訳してみました。 - Web 制作系 867867.com</a></li>
</ul>
</li>
<li><a href="http://standards.mitsue.co.jp/archives/001387.html">Graceful Degradation と Progressive Enhancement | Web 標準 Blog | ミツエーリンクス</a></li>
<li><a href="http://www.yasuhisa.com/could/article/progressive-enhancement-result/">Progressive Enhancement に関する調査結果: could</a></li>
</ul>
XAMPP と MAMP のバーチャルホスト設定
2010-02-24T00:00:00Z
https://terkel.jp/archives/2010/02/config-virtual-hosts-with-xampp-and-mamp/
<p><a href="http://www.apachefriends.org/jp/xampp.html">XAMPP</a> と <a href="http://www.mamp.info/en/index.html">MAMP</a> の <a href="http://httpd.apache.org/docs/2.2/vhosts/">バーチャルホスト</a> 設定について、職場が変わったりマシンを入れ替えたりするたびにいちいちググるのが面倒になったので、「とりあえずこれで動く!」という自分なりの設定を書いておく。各設定についての詳細は <a href="http://httpd.apache.org/docs/2.2/ja/">Apache のドキュメンテーション</a> などを参照のこと。</p>
<h2>XAMPP + Windows</h2>
<p><a href="http://www.apachefriends.org/jp/xampp-windows.html">XAMPP for Windows</a> を <code>C:\xampp</code> にインストールしていて、<code>E:\My Documents\Projects</code> に複数のサイトのデータを格納している場合を想定する。各種設定は <code>C:\xampp\apache\conf</code> にある <code>httpd.conf</code> を編集することで行なう。このファイルは管理するサイトが増えるたびに開くことになるので、どこかにショートカットを作っておくとあとで楽。</p>
<p>まず、プロジェクト管理ディレクトリについて、SSI ほかオプションの使用を可能にし、またローカルからのみアクセスを許可する設定をカマす。<code>httpd.conf</code> の末尾に以下を記述。</p>
<pre><code><Directory "E:/My Documents/Projects">
Options All
Order Deny,Allow
Deny from all
Allow from localhost
</Directory>
</code></pre>
<p>次に、バーチャルホストを利用できるようにするため <code>NameVirtualHost</code> を記述。そしてサイトごとに <code><VirtualHost></code> ブロックを作成し、<code>DocumentRoot</code> でサイトのルートディレクトリを、<code>ServerName</code> で適当なホスト名を指定する。先ほどの <code><Directory></code> の記述に続けて、<code>httpd.conf</code> の末尾に以下のように追記していく。</p>
<pre><code>NameVirtualHost *:80
<VirtualHost *:80>
DocumentRoot "E:/My Documents/Projects/example"
ServerName example.localhost
</VirtualHost>
<VirtualHost *:80>
DocumentRoot "E:/My Documents/Projects/example2"
ServerName example2.localhost
</VirtualHost>
...
</code></pre>
<p>ここではホスト名に <code>.localhost</code> という TLD を使ってるけど、ユニークなものであればどんな名前でも OK。</p>
<p>最後に、<code>C:\WINDOWS\system32\drivers\etc</code> にある <code>hosts</code> というファイルをテキストエディタなどで開く。<code>httpd.conf</code> で設定した <code>ServerName</code> の値ににしたがって、管理するサイトの分だけ以下のように追加していく。ちなみにこの <code>hosts</code> も <code>httpd.conf</code> と同様にショートカットを作成しておくと便利。</p>
<pre><code>127.0.0.1 localhost
127.0.0.1 example.localhost
127.0.0.1 example2.localhost
...
</code></pre>
<p>以上! XAMPP Control Panel から Apache を再起動 (いったん Stop して再度 Start) し、Web ブラウザで <code>http://example.localhost/</code> を見ればサイトを確認することができるはず。</p>
<p>ついでに、拡張子が <code>.html</code> または <code>.htm</code> のファイルも <a href="http://httpd.apache.org/docs/2.0/ja/howto/ssi.html">SSI</a> で利用できるようにしておくと便利。<code>httpd.conf</code> のどこかに <code>AddOutputFilter INCLUDES .shtml</code> という記述があるので、その行末に以下のように追記する。</p>
<pre><code>AddOutputFilter INCLUDES .shtml .html .htm
</code></pre>
<h2>MAMP + Mac OS X</h2>
<p><a href="http://www.mamp.info/en/index.html">MAMP</a> を <code>/Applications/MAMP</code> にインストールしてあり、<code>/Users/<usdername>/Projects</code> に複数のサイトのデータを格納している場合を想定する。</p>
<p>バーチャルホストの設定の前に、MAMP はポート番号が <code>8888</code> に設定されているので、これを HTTP のデフォルトである <code>80</code> に変更しておく。それには MAMP のコントロールパネルから「環境設定」を開き、「ポート」タブで「Apache と MySQL の標準ポートに設定」をクリックすればよい。このあたりは <a href="http://www.be-webdesigner.com/technotes/server/install/mamp.htm">MAMP のインストール for Mac - 独学! 未経験から Web デザイナーになる!!</a> でていねいに解説されているのでご参照されたし。</p>
<p>さて、XAMPP と同様、<code>/Application/MAMP/conf/apache</code> にある <code>httpd.conf</code> を開き編集する。どこかにエイリアスを作っておくのが吉。記述方法は XAMPP と同様で、以下のような感じで末尾に記述していく。</p>
<pre><code><Directory "/Users/<usdername>/Projects">
Options All
Order Deny,Allow
Deny from all
Allow from localhost
</Directory>
NameVirtualHost *:80
<VirtualHost *:80>
DocumentRoot "/Users/<usdername>/Projects/example"
ServerName example.localhost
</VirtualHost>
<VirtualHost *:80>
DocumentRoot "/Users/<usdername>/Projects/example2"
ServerName example2.localhost
</VirtualHost>
...
</code></pre>
<p>そして Windows と同様に <code>hosts</code> ファイルを編集。Mac の場合は <code>/private/etc</code> ディレクトリにあるので、なんらかのエディタで開いて以下のようにホストを追加する。</p>
<pre><code>127.0.0.1 localhost
...
127.0.0.1 example.localhost
127.0.0.1 example2.localhost
...
</code></pre>
<p>MAMP のコントロールパネルから Apache を再起動すれば完了!</p>
<p>なお MAMP で SSI を利用する場合、<code>httpd.conf</code> 内の関連記述が以下のようにコメントアウトされているので、</p>
<pre><code>#AddType text/html .shtml
#AddOutputFilter INCLUDES .shtml
</code></pre>
<p>まず上記 2 行の行頭にある <code>#</code> を消去し、必要に応じて <code>AddOutputFilter</code> 行の末尾に拡張子を追加する。</p>
<pre><code>AddType text/html .shtml
AddOutputFilter INCLUDES .shtml .html .htm
</code></pre>
<h2>参考</h2>
<p><a href="http://httpd.apache.org/docs/2.2/ja/">Apache HTTP サーバ バージョン 2.2 ドキュメント</a> の簡易リンク集:</p>
<ul>
<li><a href="http://httpd.apache.org/docs/2.1/ja/mod/">モジュール一覧</a>
<ul>
<li><a href="http://httpd.apache.org/docs/2.1/ja/mod/core.html">Apache コア機能</a>
<ul>
<li><a href="http://httpd.apache.org/docs/2.1/ja/mod/core.html#directory"><Directory> ディレクティブ</Directory></a></li>
<li><a href="http://httpd.apache.org/docs/2.1/ja/mod/core.html#options">Options ディレクティブ</a></li>
<li><a href="http://httpd.apache.org/docs/2.1/ja/mod/core.html#virtualhost"><VirtualHost> ディレクティブ</VirtualHost></a></li>
</ul>
</li>
</ul>
</li>
<li><a href="http://httpd.apache.org/docs/2.1/ja/sections.html">セクションの設定</a></li>
<li><a href="http://httpd.apache.org/docs/2.1/ja/vhosts/">Apache バーチャルホスト説明書</a>
<ul>
<li><a href="http://httpd.apache.org/docs/2.1/ja/vhosts/name-based.html">名前ベースのバーチャルホスト</a></li>
</ul>
</li>
<li><a href="http://httpd.apache.org/docs/2.0/ja/howto/ssi.html">Apache チュートリアル: Server Side Includes 入門</a></li>
</ul>
13 か 15
2010-03-06T00:00:00Z
https://terkel.jp/archives/2010/03/13-or-15/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/twitter-smashingmag-9999012862.png" />
</figure>
<p>先日、Twitter で <a href="http://twitter.com/smashingmag" title="Smashing Magazine (smashingmag) on Twitter">@smashongmag</a> (<a href="http://www.smashingmagazine.com/">Smashing Magazine</a> のアカウント) からこんな問いかけがありました:</p>
<blockquote cite="http://twitter.com/smashingmag/status/9999012862" lang="en">
<p>What font-size do you usually use for your body copy? (If em, convert to px): 11px, 12px, 13px? Let us know! <a href="http://twitter.com/#search?q=%23smfont" title="Twitter / Search - #smfont">#smfont</a></p>
</blockquote>
<p>「(Web ページの) 本文のフォントサイズっていつも何ピクセルにしてる?」というわけですね。この問いに対するぼくの答えは決まっていて、それは「<strong>13px か 15px</strong>」です。なぜ 12px でも 14px でもなく、13px と 15px なのか。その理由は、Windows 日本語環境の「事実上の標準」と言えるフォント、<strong>MS Pゴシック</strong> (MS PGothic) にあります。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/ms-pgothic-12px.png" />
<figcaption>Fig 2: MS Pゴシック 12px</figcaption>
</figure>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/ms-pgothic-13px.png" />
<figcaption>Fig 3: MS Pゴシック 13px</figcaption>
</figure>
<p>MS Pゴシックの 12px と 13px のスクリーンショットを並べてみました (Fig 2 と 3)。一見したところほとんど同じに思えるかもしれませんが、よく見比べるとかなり印象が違うはずです。12px だと文字と文字の間隔がかなりきっちり詰められているのに対し、13 px はやや余裕があって読みやすいと感じませんか?</p>
<p>さらによく見ると、文字ひとつひとつの大きさは同じですが、微妙に文字間隔が異なるのがわかります。つまり、MS Pゴシックは 13px の字形を持っておらず、12px の字形に文字間隔を加えることで 13px を表現しているのです。しかし結果として、その文字間隔が可読性に貢献しているわけです。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/ms-pgothic-large-12px.png" />
<figcaption>Fig 4: MS Pゴシック 12px 拡大図</figcaption>
</figure>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/ms-pgothic-large-13px.png" />
<figcaption>Fig 5: MS Pゴシック 13px 拡大図</figcaption>
</figure>
<p>もちろん、文字間隔と言っても均等に 1px ずつあけるのではなく、プロポーショナル・フォントとしてバランスが考えられています (Fig 4 と 5)。つまり、CSS で <code>font-size: 12px; letter-spacing: 1px;</code> と指定するのとはまったく違うわけです。</p>
<p>そしてこの 12px と 13px の関係と同じことが、14px と 15px の間でも起こります (Fig 6 と 7)。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/ms-pgothic-14px.png" />
<figcaption>Fig 6: MS Pゴシック 14px</figcaption>
</figure>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/ms-pgothic-15px.png" />
<figcaption>Fig 7: MS Pゴシック 15px</figcaption>
</figure>
<p>とは言え、「なんか間が抜けてるように見えてヤだ」って意見もあると思いますし、少しでもスペースを節約しなければならない場合もあると思います。しかし、いわゆる「本文」としてある程度まとまった分量のテキストの場合、このくらいの余裕がほしいと感じる人は少なくないはずです。</p>
<p>そんなわけで、<strong>日本語を中心としたコンテンツ</strong>で、<strong>ある程度の割合のユーザーがMS Pゴシックで閲覧していると想定される</strong>場合、<strong>Web ページの本文のフォントサイズは 13px か 15px がベスト</strong>、というのが僕の意見です。</p>
Opera 10.50 の CSS バグ: input 要素に border-radius
2010-04-19T00:00:00Z
https://terkel.jp/archives/2010/04/opera-10-50-css-bug-input-border-radius/
<p>Opera 10.50 では <code>border-radius</code> プロパティがサポートされましたが、<code>input</code> 要素に対して指定する場合、ちょっとしたバグがあるので注意が必要です。そのバグとは、<strong>ボーダーを消した</strong> (<code>border-width: 0;</code> または <code>border-style: none;</code> を指定した) <strong><code>input</code> 要素に <code>border-radius</code> を指定すると、<code>background-color</code> の指定が無効になる</strong>、というものです。10.51 でも修正されませんでした。</p>
<p>たとえば以下の場合、背景色の指定は反映されません。</p>
<pre><code class="language-css">input[type="submit"] {
border: 0;
border-radius: 4px;
background: #0060c0;
}
</code></pre>
<p>このバグを回避するには、<code>background-color</code> と同時に、<strong><code>background-image</code> に透過画像を指定</strong>します。</p>
<pre><code class="language-css">input[type="submit"] {
border: 0;
border-radius: 4px;
background: #0060c0 url(transparent.png);
}
</code></pre>
<p>これで背景色の指定が有効になります。この回避策は以下のサイトで紹介されていました:</p>
<ul>
<li><a href="http://blog.attrakt.se/2010/04/annoying-opera-css3-bug-input-border.html">Attrakt.se Blog: Annoying Opera CSS3 bug - INPUT border-radius</a></li>
</ul>
<p>ちなみに、<code>input</code> 要素のボーダーのどれか 1 辺以上を表示させることでも回避できます。しかしこの方法には副作用があり、<code>submit</code> タイプの場合、同じフォーム内にある <code>text</code> タイプの <code>input</code> 要素にフォーカスした際、アウトラインのようなものが表示されてしまいます (下図参照)。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/opera-border-radius.png" />
</figure>
WordPress で HTML5 を書くための準備
2010-04-21T00:00:00Z
https://terkel.jp/archives/2010/04/get-ready-for-htm5-in-wordpress/
<p>現在、このサイトを HTML5 で再構築しようと画策しています。今日はその「準備編」ということで、<a href="http://ja.wordpress.org/">WordPress</a> で HTML5 をパブリッシュするために、どのようにテンプレートをいじればよいかを考えてみました。ここでは WordPress 2.9 のデフォルトのテーマ、WordPress Default 1.6 に手を加えていきます。</p>
<h2>文書型宣言</h2>
<p><code>header.php</code> の 7 行目 (実際に出力されるのは 1 行目) あたりで以下のように文書型が宣言されています:</p>
<pre><code class="language-html"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
</code></pre>
<p>これを以下のように修正します:</p>
<pre><code class="language-html"><!DOCTYPE html>
</code></pre>
<p>HTML5 の文書型宣言では大文字か小文字かは問われませんので、<code><!DOCTYPE HTML></code> でも <code><!doctype html></code> でもでもかまいません。</p>
<h2>文字コード宣言</h2>
<p><code>header.php</code> の 11 行目あたりに以下の記述があります:</p>
<pre><code class="language-php"><meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />
</code></pre>
<p>これをこのように書き替えます:</p>
<pre><code class="language-php"><meta charset="<?php bloginfo('charset'); ?>" />
</code></pre>
<p><code><?php bloginfo('charset'); ?></code> の部分は WordPress の設定画面で指定した文字コードが出力されます。たとえば <code><meta charset="UTF-8" /></code> など。</p>
<h2>JavaScript</h2>
<p>IE が HTML5 の新しい要素タイプを認識でないという問題を解決するため、<code>header.php</code> の <code>head</code> 要素内で、CSS より先に <a href="http://code.google.com/p/html5shiv/">html5shiv</a> スクリプトを以下のようにインクルードします。</p>
<pre><code class="language-html"><!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</code></pre>
<h2>CSS</h2>
<p><code>section</code> や <code>nav</code> といった HTML5 の新しい要素タイプのうち、ブロックボックスとしてレンダリングしたいものについて CSS で明示します。これは <code>header.php</code> の <code>head</code> 要素内に <code>style</code> 要素として書いてもいいし、<code>style.css</code> などの CSS ファイルに書いてもいいです。</p>
<pre><code class="language-css">section, nav, article, aside, hgroup, header, footer, figure, figcaption {
display: block;
}
</code></pre>
<h2>まとめ</h2>
<p><code>header.php</code> のおもな変更点をまとめるとこんな感じです:</p>
<pre><code class="language-html"><!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="<?php bloginfo('charset'); ?>" />
<title> . . . <title>
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<style>
section, nav, article, aside, hgroup, header, footer, figure, figcaption {
display: block;
}
</style>
. . .
</head>
. . .
</code></pre>
<p>これで、WordPress で HTML5 を書くための最低限の準備は整いました。あとは肝心の <code>body</code> 要素内のコンテンツのマークアップですが、それはまた次回。</p>
HTML5 へ移行
2010-04-26T00:00:00Z
https://terkel.jp/archives/2010/04/switched-to-html5/
<p><a href="https://terkel.jp/archives/2010/04/get-ready-for-htm5-in-wordpress/">というわけで</a>、このサイトを HTML5 でマークアップしてみました。個別記事内のフレージング系の見直しはまだ手つかずで、まずはセクショニングまわりから固めています。納得のいかない部分もありますが、まずは公開して、これからさらに手を加えていこうと思います。</p>
<p>さて、個別記事ページの構成はこんな感じになってます:</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/switched-to-html5.png" />
</figure>
<ul>
<li><code>div.page#page</code>
<ul>
<li><code>header.page-header</code>
<ul>
<li><code>h1.logo</code></li>
<li><code>nav.global</code></li>
</ul>
</li>
<li><code>article.content</code>
<ul>
<li><code>header.content-header</code>
<ul>
<li><code>nav.paging</code></li>
<li><code>p.date</code></li>
<li><code>h1.title</code></li>
</ul>
</li>
<li><code>div.content-body</code>
<ul>
<li><code>(Content goes here)</code></li>
</ul>
</li>
<li><code>footer.content-footer</code>
<ul>
<li><code>nav.paging</code></li>
<li><code>section#tags</code></li>
<li><code>section#related-posts</code></li>
</ul>
</li>
<li><code>aside.content-aside</code>
<ul>
<li><code>section.comments</code>
<ul>
<li><code>article.comment</code></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><code>aside.sidebar</code>
<ul>
<li><code>section#search</code></li>
<li><code>section#archives-by-tag</code></li>
<li><code>section#about</code></li>
<li><code>section#elsewhere</code></li>
<li><code>section#subscribe</code></li>
<li><code>section#lastfm</code></li>
</ul>
</li>
<li><code>footer.page-footer</code>
<ul>
<li><code>p.credits</code></li>
</ul>
</li>
</ul>
</li>
</ul>
<p>ページ全体のヘッダとフッタとして <code>header</code>/<code>footer</code> を配置し、記事部分は <code>article</code> で、そして検索やタグクラウドなど、記事よりもサイト全体に関わる部分は <code>aside</code> でマークアップしています。</p>
<p>マークアップでとくに悩んでいるのは、「タグ」「関連記事」「コメント」といった記事の終わりに並ぶ要素群です。今のところ、「タグ」と「関連記事」は <code>footer</code>、「コメント」は <code>aside</code> とし、どちらも記事本体の <code>article</code> 内に置きました。しかしどうも拡大解釈気味というか、いまいちしっくりこない気もしています。</p>
<p>あと、どこまで <code>nav</code> 要素とすべきかも難しいです。とりあえず、ページのヘッダのいわゆるグローバルナビゲーションと、記事のヘッダとフッタに配置している前後の記事へのリンクを <code>nav</code> でマークアップしていますが、記事の「タグ」や「関連記事」、それにサイト内検索もナビゲーションっちゃナビゲーションだよな… という悩み方をしています。</p>
<p>そのほか、<code>role</code> 属性も入れようと思ったのですが、仕様がよくわかかっていない—というかどの仕様を読めばいいのかよくわかっていない—ので保留。<a href="http://microformats.org/wiki/ja">Microformats</a> ももう少しきっちりやりたいところです。</p>
<p>マークアップにあたって、仕様書のほか、実際に HTML5 で書かれたサイトなどをいろいろと参照しましたが、とくに <a href="http://html5doctor.com/">HTML5 Doctor</a> の記事と、ドクターたちの個人サイトのソースコードは参考になりました:</p>
<ul>
<li><a href="http://www.brucelawson.co.uk/">Bruce Lawson</a></li>
<li><a href="http://jackosborne.co.uk/">Jack Osborne</a></li>
<li><a href="http://akamike.net/">Mike Robinson</a></li>
<li><a href="http://www.tomleadbetter.co.uk/">Tom Leadbetter</a></li>
<li><a href="http://oli.jp/">Oli Studholme</a></li>
</ul>
<p>やっぱり HTML5 はまだまだ導入事例が少なく、暗中模索している人も多いのではないでしょうか。とくに個人のサイトをお持ちの皆さんはどんどんトライしてみて、意見交換が活発になるといいなと思います。</p>
<p>ツッコミ歓迎!</p>
HTML5 の dl 要素
2010-04-27T00:00:00Z
https://terkel.jp/archives/2010/04/the-dl-element-in-html5/
<p><a href="http://www.w3.org/TR/2010/WD-html5-20100304/semantics.html#the-dl-element">HTML5 の 2010 年 3 月 4 日付 W3C 草案</a> で、<strong><code>dl</code></strong> 要素は以下のように定義されています:</p>
<blockquote cite="http://www.w3.org/TR/2010/WD-html5-20100304/semantics.html#the-dl-element" lang="en">
<p>The <code>dl</code> element represents an association list consisting of zero or more name-value groups (a description list). Each group must consist of one or more names (<code>dt</code> elements) followed by one or more values (<code>dd</code> elements). Within a single <code>dl</code> element, there should not be more than one <code>dt</code> element for each name.</p>
</blockquote>
<p>HTML4 では、<code>dl</code> 要素は definition list (定義リスト) であり、term (<code>dt</code>) と description (<code>dd</code>) から構成されるとされていました (<a href="http://www.w3.org/TR/html401/struct/lists.html#h-10.3">Lists in HTML documents</a>)。それが HTML5 では「名前と値のグループからなるリスト」となっており、その例として、「定義語とその定義」や「メタデータの題目と値」などが挙げられています。</p>
<p>ちょっときびしいなと思うのが、“Within a single <code>dl</code> element, there should not be more than one <code>dt</code> element for each name.” という部分。1 つの <code>dl</code> 要素の中で、同じ内容を持つ <code>dt</code> 要素が複数存在すべきではない、とのこと。より「連想配列」的な性格を強めたということでしょうか。</p>
<p>しかしそうなってくると、以下のような <code>dl</code> の使い方は推奨されないということになりますよね…</p>
<pre><code class="language-html"><dl class="news">
<dt>2010-04-27</dt>
<dd>ブログを更新しました</dd>
<dt>2010-04-27</dt>
<dd>プレスリリースを発表しました</dd>
<dt>2010-04-01</dt>
<dd>サイトをリニューアルしました</dd>
</dl>
</code></pre>
<pre><code class="language-html"><dl class="dialog">
<dt>Costello</dt>
<dd>Look, you gotta first baseman?</dd>
<dt>Abbott</dt>
<dd>Certainly.</dd>
<dt>Costello</dt>
<dd>Who's playing first?</dd>
<dt>Abbott</dt>
. . .
</dl>
</code></pre>
<p>ひとつめの例はサイトの更新履歴、ふたつめは会話文のマークアップ例ですが、どちらも同じ内容を持つ <code>dt</code> 要素が 2 回以上出現しているので、あまりよろしくないということになります。あくまで “should not” ですが。</p>
Delicious Feeds API に URL をそのまま渡す
2010-04-30T00:00:00Z
https://terkel.jp/archives/2010/04/delicious-feeds-api-url/
<p><a href="http://delicious.com/">Delicious</a> の <a href="http://delicious.com/help/feeds">Feeds API</a> を利用するとページの被ブックマーク関連情報を取得できるが、対象ページの URL を <a href="http://ja.wikipedia.org/wiki/MD5">MD5</a> ハッシュ値で渡さなければならないという謎の掟がある。しかしデータを JSON 形式で取得する場合は、以下の方法で URL をそのまま渡すことも可能。</p>
<p>まず、そのページのブックマーク件数や使われているタグなどを取得する場合:</p>
<pre><code>http://feeds.delicious.com/v2/json/urlinfo/blogbadge?url={url}
</code></pre>
<p>個々のブックマークのユーザー名、日付、タグなどのデータは:</p>
<pre><code>http://feeds.delicious.com/v2/json/url/blogbadge?url={url}
</code></pre>
<p><a href="http://delicious.com/help/feeds">公式ドキュメント</a> には載ってないっぽいけど、どちらも <code>{url}</code> にページの URL をそのまま入れれば JSON 形式でデータが取得できる。そのほかのパラメータはドキュメントを参照のこと。以下はうちのサイトの例:</p>
<ul>
<li><a href="http://feeds.delicious.com/v2/json/urlinfo/blogbadge?url=https://terkel.jp/archives/2010/03/13-or-15/"><code>http://feeds.delicious.com/v2/json/urlinfo/blogbadge?url=https://terkel.jp/archives/2010/03/13-or-15/</code></a></li>
<li><a href="http://feeds.delicious.com/v2/json/url/blogbadge?url=https://terkel.jp/archives/2010/03/13-or-15/"><code>http://feeds.delicious.com/v2/json/url/blogbadge?url=https://terkel.jp/archives/2010/03/13-or-15/</code></a></li>
</ul>
<p>この記事を書くにあたって以下の記事を参考にしました (ありがとうございます) が、一部情報が古くなっているようなので注意:</p>
<ul>
<li><a href="http://tech.kayac.com/archive/undocumented-delicious-api.html">deliciousの本家Helpに書かれていないAPIの使いかた : tech.kayac.com - KAYAC engineers' blog</a></li>
</ul>
aside 要素とプル・クオート
2010-04-30T00:00:00Z
https://terkel.jp/archives/2010/04/the-aside-element-and-pull-quote/
<p><a href="http://www.w3.org/TR/2010/WD-html5-20100304/semantics.html#the-aside-element">HTML5 の 2010 年 3 月 4 日付 W3C 草案</a> では、<strong><code>aside</code></strong> 要素は以下のように定義されています:</p>
<blockquote cite="http://www.w3.org/TR/2010/WD-html5-20100304/semantics.html#the-aside-element" lang="en">
<p>The <code>aside</code> element represents a section of a page that consists of content that is tangentially related to the content around the <code>aside</code> element, and which could be considered separate from that content. Such sections are often represented as sidebars in printed typography.</p>
<p>The element can be used for typographical effects like <b>pull quotes</b> or sidebars, for advertising, for groups of <code>nav</code> elements, and for other content that is considered separate from the main content of the page.</p>
</blockquote>
<p>なにが難しいってこの <strong>tangentially related</strong> って部分をどう解釈するかが難しいんですが、そこは置いときます。今回ここで取り上げたいのは、上記草案のうちふたつめの段落、要素の具体的な使用例の部分。そこには、<code>aside</code> 要素は「<strong>プル・クオート</strong>や囲み記事のようなタイポグラフィ上の効果や、広告、<code>nav</code> 要素のグループ、またそのほかページの中心となる内容から切り離されていると見なせるコンテンツのために使われる」とあります。ここで気になったのが「プル・クオート」という聞き慣れない単語です。調べてみると英語版 Wikipedia に<a href="http://en.wikipedia.org/wiki/Pull_quote">記事</a>がありました:</p>
<blockquote cite="http://en.wikipedia.org/wiki/Pull_quote">
<p>A <b>pull quote</b> (also known as a <b>lift-out</b> quote or a <b>call-out</b>) is a quotation or edited excerpt from an article that is typically placed in a larger typeface on the same page, serving to lead readers into an article and to highlight a key topic. The term is principally used in journalism and publishing.</p>
</blockquote>
<p>プル・クオートとは「記事からの引用または手を入れた抜粋で、一般的には同一ページ内に大きめの書体で配置され、リード文の役割を果たし、主要な話題を目立たせるもの」であり、「おもに新聞・雑誌や出版で使われる用語」である、と。「クオート」というとほかのリソースからの引用を思い浮かべがちですがそうではなく、みずからの要約やハイライトのための抜粋ということのようです。</p>
<p>そう言われて僕がすぐに思いついたのは、雑誌のインタヴュー記事で主要な発言を抜き出して見出しのように見せるやつです。とくに数ページにわたる長い記事で、キャッチーかつ全体を要約するようなセンテンスをページの上部や段落の間などに挿入するあれ、あれをどうやらプル・クオートと呼ぶらしい。たしかに、あの部分は記事の内容を把握する助けになりますが、もしページ上に存在しなかったとしても記事そのものには影響がないので、<code>aside</code> 要素の定義にマッチしているように思いますね。</p>
<p>というわけで、<code>aside</code> 要素をどのように使うか迷ったときは、プル・クオートのような「その前後の内容に関係する (かもしれない) けれども、なくてもその前後には影響のない要素」というようなものを思い浮かべるといいかもしれません。</p>
blockquote + footer
2010-05-02T00:00:00Z
https://terkel.jp/archives/2010/05/blockquote-footer/
<p role="note">
<small>コメントでの指摘を受け、新しく記事を起こしました: <a href="https://terkel.jp/archives/2010/05/blockquote-and-cite-in-html5/">HTML5 での引用と引用元のマークアップ</a></small>
</p>
<hr />
<p><a href="http://www.w3.org/TR/2010/WD-html5-20100304/">HTML5 の 2010 年 3 月 4 日付 W3C 草案</a> で、<strong><code>footer</code></strong> 要素は以下のように定義されています:</p>
<blockquote cite="http://www.w3.org/TR/2010/WD-html5-20100304/semantics.html#the-footer-element" lang="en">
<p>The <code>footer</code> element represents a footer for its nearest ancestor <a href="http://www.w3.org/TR/2010/WD-html5-20100304/dom.html#sectioning-content">sectioning content</a> or <a href="http://www.w3.org/TR/2010/WD-html5-20100304/semantics.html#sectioning-root">sectioning root</a> element. A footer typically contains information about its section such as who wrote it, links to related documents, copyright data, and the like.</p>
</blockquote>
<p class="Credit"><small>(<a href="http://www.w3.org/TR/2010/WD-html5-20100304/semantics.html#the-footer-element">4.4.9 The footer element — HTML 5</a>)</small></p>
<p>「<code>footer</code> 要素は、直近の祖先にあたるセクショニング・コンテントまたはセクショニング・ルート要素に対するフッターを示します。フッターは一般的に、執筆者、関連文書へのリンク、著作権などといった、そのセクションについての情報を含みます」、といったところですね。たとえばおもにページの下部に入るサイトの著作権などのクレジットや、ブログ記事の執筆者や日付などをマークアップするのに使うことになると思います。</p>
<p>さて「セクショニング・コンテントまたはセクショニング・ルート要素に対するフッター」とのことですが、この「セクショニング・ルート」となる要素のひとつに <a href="http://www.w3.org/TR/2010/WD-html5-20100304/semantics.html#the-blockquote-element"><strong><code>blockquote</code></strong> 要素</a> があります。<code>blockquote</code> のフッターとなれば、引用元の情報を記述するのにうってつけではないでしょうか。というわけで、HTML5 における <code>blockquote</code> のマークアップを考えてみました:</p>
<pre><code class="language-html"><blockquote cite="http://ja.wikipedia.org/wiki/1Q84">
<p>『1Q84』(いちきゅうはちよん)は、村上春樹の長編小説。</p>
<p>2009年5月、書き下ろしとして新潮社から刊行された。2009年11月に第63回「毎日出版文化賞 文学・芸術部門」を受賞した。</p>
<footer>
出典: <cite>1Q84 - Wikipedia</cite>,
<time datetime="2010-05-02">2010 年 5 月 2 日</time>
</footer>
</blockquote>
</code></pre>
<p><code>blockquote</code> 要素内の <code>footer</code> 要素に、引用元を示す <strong><code>cite</code></strong> 要素と情報の取得日時を示す <strong><code>time</code></strong> 要素を含めています。引用元の URI は <code>blockquote</code> 要素の <code>cite</code> 属性で示していますが、たとえば以下のように jQuery を使って、<code>cite</code> 属性値の URI を抽出して <code>cite</code> 要素にリンクを設定することもできます:</p>
<pre><code class="language-javascript">$(function () {
$('blockquote[cite]').each(function () {
var pattern = /^https?\:/i;
var citeUrl = $(this).attr('cite');
var citeElm = $(this).children('footer').children('cite');
if (pattern.test(citeUrl) && citeElm) {
citeElm.wrap('<a href="' + citeUrl + '"/>');
};
});
});
</code></pre>
<p>なお、HTML5 では <code>cite</code> 要素の定義がかなりきっちりしていて、人名をマークアップをするために使われるべきではないとされています:</p>
<blockquote cite="http://www.w3.org/TR/2010/WD-html5-20100304/text-level-semantics.html#the-cite-element" lang="en">
<p>The <code>cite</code> element represents the title of a work (e.g. a book, a paper, an essay, a poem, a score, a song, a script, a film, a TV show, a game, a sculpture, a painting, a theatre production, a play, an opera, a musical, an exhibition, a legal case report, etc). This can be a work that is being quoted or referenced in detail (i.e. a citation), or it can just be a work that is mentioned in passing.</p>
<p>A person’s name is not the title of a work — even if people call that person a piece of work — and the element must therefore not be used to mark up people’s names. (In some cases, the <a href="http://www.w3.org/TR/2010/WD-html5-20100304/text-level-semantics.html#the-b-element"><code>b</code></a> element might be appropriate for names; e.g. in a gossip article where the names of famous people are keywords rendered with a different style to draw attention to them. In other cases, if an element is <em>really</em> needed, the <a href="http://www.w3.org/TR/2010/WD-html5-20100304/text-level-semantics.html#the-span-element"><code>span</code></a> element can be used.)</p>
</blockquote>
<p class="Credit"><small>(<a href="http://www.w3.org/TR/2010/WD-html5-20100304/text-level-semantics.html#the-cite-element">4.6.5 The cite element — HTML 5</a>)</small></p>
<p>よって、フッターの引用元の文言に人名などが含まれる場合、以下のようにマークアップするのが適切と思われます:</p>
<pre><code class="language-html"><blockquote>
<p>エレベーターはきわめて緩慢な速度で上昇をつづけていた。おそらくエレベーターは上昇していたのだろうと私は思う。</p>
<footer>
村上春樹『<cite>世界の終りとハードボイルド・ワンダーランド</cite>』より
</footer>
</blockquote>
</code></pre>
<p>マークアップする上で <code>blockquote</code> 要素と <code>cite</code> 要素というのはなかなか扱いの難いものだったと思います。たとえば <code>blockquote</code> 要素の中に <code>cite</code> 要素を含めるのは是か非かとか、<code>blockquote</code> 要素の外に <code>cite</code> 要素を置いた場合にどうやって両者を紐付けるかとか。</p>
<ul>
<li><a href="http://www.kanzaki.com/docs/html/htminfo14.html#S13.1">強調,引用,グループ化,画像などの要素 -- ごく簡単なHTMLの説明</a></li>
<li><a href="http://p2b.jp/200901-blockquote-cite">BLOCKQUOTE要素とCITE要素をめぐる考察</a></li>
</ul>
<p>このあたり、<code>footer</code> 要素を使うことでかなりすっきりするのではないかと思うのですが、どうでしょうか。</p>
HTML5 での引用と引用元のマークアップ
2010-05-07T00:00:00Z
https://terkel.jp/archives/2010/05/blockquote-and-cite-in-html5/
<p><a href="https://terkel.jp/archives/2010/05/blockquote-footer/">前回の記事</a> で、HTML5 における引用と引用元のマークアップについて以下のような提案をしました:</p>
<pre><code class="language-html"><blockquote>
<p>エレベーターはきわめて緩慢な速度で上昇をつづけていた。おそらくエレベーターは上昇していたのだろうと私は思う。</p>
<footer>
村上春樹『<cite>世界の終りとハードボイルド・ワンダーランド</cite>』より
</footer>
</blockquote>
</code></pre>
<p>引用元についての情報を <code>footer</code> 要素でマークアップし、かつ <code>blockquote</code> 要素の中に置くというアプローチです。かなり気に入っていたのですが、はてなブックマークでこんなコメントをいただきました (ありがとうございます):</p>
<blockquote cite="http://b.hatena.ne.jp/vantguarde/20100506#bookmark-21327203">
<p>“Content inside a blockquote must be quoted from another source” なので引用文以外の情報を含めるのはアウト。(そういう場合は<figure>を使うってのがどこかで言われてたけど、どこだったっけ…)</p>
</blockquote>
<p class="Credit"><small>(<a href="http://b.hatena.ne.jp/vantguarde/20100506#bookmark-21327203">はてなブックマーク - vantguarde - 2010年5月6日</a>)</small></p>
<p>HTML5 仕様書の <code>blockquote</code> の項にあたってみると、たしかにこうあります:</p>
<blockquote cite="http://www.w3.org/TR/2010/WD-html5-20100304/semantics.html#the-blockquote-element" lang="en">
<p>The <code>blockquote</code> element represents a section that is quoted from another source.</p>
<p>Content inside a <code>blockquote</code> must be quoted from another source, whose address, if it has one, should be cited in the <code>cite</code> attribute.</p>
</blockquote>
<p class="Credit"><small>(<a href="http://www.w3.org/TR/2010/WD-html5-20100304/semantics.html#the-blockquote-element">4.5.5 The blockquote element — HTML5 [W3C Working Draft 4 March 2010</a>)</small></p>
<p>見落としておりました。「<code>blockquote</code> の内容はほかのリソースからの引用でなければならず、引用元は <code>cite</code> 属性で言及されるべき」といったところでしょうか。<a href="http://www.w3.org/TR/html401/struct/text.html#h-9.2.2">HTML 4.01</a> ではゆるかったのが HTML5 ではきっちりしているようです。失礼いたしました…</p>
<p>というわけで、HTML5 において引用と引用元をマークアップするにはどうするのがよいか、再び考えてみました。以下、いくつかの案を挙げてみます。</p>
<h2>1. div + p</h2>
<pre><code class="language-html"><div class="quote">
<blockquote>
<p>エレベーターはきわめて緩慢な速度で上昇をつづけていた。おそらくエレベーターは上昇していたのだろうと私は思う。</p>
</blockquote>
<p class="cite">
村上春樹『<cite>世界の終りとハードボイルド・ワンダーランド</cite>』より
</p>
</div>
</code></pre>
<p>まず最初の案は、HTML5 の新しい要素タイプを使わないマークアップ。まあ、間違いではないですよね、少なくとも。でも引用と引用元の結びつきが弱いというか、セマンティックでないというか。やはりここはもう少し積極的に HTML5 の新要素を活かしたマークアップを模索したいところです。</p>
<h2>2. article + footer</h2>
<pre><code class="language-html"><article>
<blockquote>
<p>エレベーターはきわめて緩慢な速度で上昇をつづけていた。おそらくエレベーターは上昇していたのだろうと私は思う。</p>
</blockquote>
<footer>
村上春樹『<cite>世界の終りとハードボイルド・ワンダーランド</cite>』より
</footer>
</article>
</code></pre>
<p>ふたつめ、引用元を <code>footer</code> 要素で、<code>blockquote</code> 要素を含む全体を <code>article</code> 要素でマークアップ。<a href="https://terkel.jp/archives/2010/05/blockquote-footer/">前回の記事</a> で見たように、引用元を <code>footer</code> でマークアップするのは悪くないと思うんですが、引用を <code>article</code> と見なすのはやや無理がありそうな気がしますね。というわけで、次。</p>
<h2>3. figure + figcaption</h2>
<pre><code class="language-html"><figure>
<blockquote>
<p>エレベーターはきわめて緩慢な速度で上昇をつづけていた。おそらくエレベーターは上昇していたのだろうと私は思う。</p>
</blockquote>
<figcaption>
村上春樹『<cite>世界の終りとハードボイルド・ワンダーランド</cite>』より
</figcaption>
</figure>
</code></pre>
<p>今のところいちばん良さそうかなと思っているのがこれです。引用元を <code>figcaption</code> 要素で、<code>bloclquote</code> 要素を含む全体を <code>figure</code> 要素でマークアップします。<a href="http://www.w3.org/TR/2010/WD-html5-20100304/">HTML5 の 2010 年 3 月 4 日付 W3C 草案</a> での <code>figure</code> と <code>figcaption</code> の定義は以下のとおりです:</p>
<blockquote cite="http://www.w3.org/TR/2010/WD-html5-20100304/semantics.html#the-figure-element" lang="en">
<p>The <code>figure</code> element represents some flow content, optionally with a caption, that is self-contained and is typically referenced as a single unit from the main flow of the document.</p>
<p>The element can thus be used to annotate illustrations, diagrams, photos, code listings, etc, that are referred to from the main content of the document, but that could, without affecting the flow of the document, be moved away from that primary content, e.g. to the side of the page, to dedicated pages, or to an appendix.</p>
</blockquote>
<p class="Credit"><small>(<a href="http://www.w3.org/TR/2010/WD-html5-20100304/semantics.html#the-figure-element">4.5.12 The figure element — HTML5 [W3C Working Draft 4 March 2010]</a>)</small></p>
<blockquote cite="http://www.w3.org/TR/2010/WD-html5-20100304/semantics.html#the-figcaption-element" lang="en">
<p>The <code>figcaption</code> element represents a caption or legend for the rest of the contents of the <code>figcaption</code> element’s parent <code>figure</code> element, if any.</p>
</blockquote>
<p class="Credit"><small>(<a href="http://www.w3.org/TR/2010/WD-html5-20100304/semantics.html#the-figcaption-element">4.5.13 The figcaption element — HTML5 [W3C Working Draft 4 March 2010]</a>)</small></p>
<p>引用元の情報はまさに引用のキャプションと見なすことができるので、かなりしっくりくる気がします。ただ、<code>figure</code> 要素は「主たるコンテントから切り離せる」ものとされているのに対し、引用は前後の文脈と密接に関連する場合が多いので、そのあたりがやや微妙かもしれません。</p>
<p>また上記草案では、<code>figure</code> と <code>figcaption</code> の用例として詩の一節を引用する場合を挙げています。<code>blockquote</code> 要素を用いていないのが気になりますが:</p>
<pre><code class="language-html"><figure>
<p>'Twas brillig, and the slithy toves<br>
Did gyre and gimble in the wabe;<br>
All mimsy were the borogoves,<br>
And the mome raths outgrabe.</p>
<figcaption>
<cite>Jabberwocky</cite> (first verse). Lewis Carroll, 1832-98
</figcaption>
</figure>
</code></pre>
<p><code>figure</code> と <code>figcaption</code> の例をもうひとつ、<a href="http://html5doctor.com/the-figure-figcaption-elements/" title="The figure & figcaption elements | HTML5 Doctor">HTML5 Doctor の記事</a> より。引用というよりソースコードとその注釈をマークアップするケースですが:</p>
<pre><code class="language-html"><figure>
<blockquote>
<p><code>&lt;small&gt;&lt;a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/"&gt;Creative Commons Attribution Share-alike license&lt;/a&gt;&lt;/small&gt;</code></p>
</blockquote>
<figcaption>
Using <code>&lt;small&gt;</code> around a <a href="http://creativecommons.org/choose/" title="Choose a License">Creative Commons license</a> link with <code>rel="license"</code>
</figcaption>
</figure>
</code></pre>
<p>どうでしょうか。<code>figure</code> と <code>figcaption</code> でいけそうかなと思うんですが… いやー、難しい!</p>
google-code-prettify を導入
2010-05-14T00:00:00Z
https://terkel.jp/archives/2010/05/google-code-prettify/
<p>ソースコードを強調表示するシンタックス・ハイライトをブログに導入したくていくつか調べてみたんだけど、結局 <a href="http://code.google.com/p/google-code-prettify/">google-code-prettify</a> にした。行番号を入れたりのリッチな機能は必要なくて、シンプルにシンタックスの抽出をやってくれるものを探していたので。</p>
<p>導入にあたっては、<a href="http://hail2u.net/blog/webdesign/install-google-code-prettify.html" title="hail2u.net - Weblog - google-code-prettifyを導入した">hail2u.net の記事</a> を参考に Google の <a href="http://closure-compiler.appspot.com/home">Closure Compiler</a> を利用した。このブログで扱うソースコードというと HTML か CSS か JavaScript、まれに PHP といったところなので、コアである <code>prettify.js</code> のほかに <code>lang-css.js</code> を加えてコンパイルした。</p>
<p>カラーリングは頑張って微妙な色合いも試してみたけど、ことごとく挫折。最終的には <a href="http://www.w3.org/TR/css3-color/#html4" title="CSS Color Module Level 3">CSS の color キーワード</a> でざっくり指定するのがしっくりきた。</p>
<pre><code class="language-css">.prettyprint .kwd,
.prettyprint .tag { color: purple; }
.prettyprint .typ,
.prettyprint .atn { color: maroon; }
.prettyprint .str,
.prettyprint .atv { color: navy; }
.prettyprint .lit { color: blue; }
.prettyprint .pun { color: teal; }
.prettyprint .pln { color: black; }
.prettyprint .dec,
.prettyprint .com { color: green; }
</code></pre>
<p>なお、バージョン 8 未満の IE では改行が除去されてしまうというバグが発生する。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/google-code-prretify-ie.png" />
</figure>
<p>シカトしようかとも思ったけど、さすがにこれじゃ読んでいられないので、コンディショナル・コメントで対応した。「バージョン 8 以上の IE とそのほかのブラウザ」という条件なので、記述がちょっとややこしい。</p>
<pre><code class="language-html"><!--[if gt IE 7]><!-->
<script type="text/javascript" src="/js/google-code-prettify.js"></script>
<!--<![endif]-->
</code></pre>
印刷用の CSS と jQuery プラグイン
2010-05-14T00:00:00Z
https://terkel.jp/archives/2010/05/styles-and-scripts-for-print/
<p role="note"><small>URL のリストを出力するスクリプトを一部修正して <a href="https://gist.github.com/1239386">Gist に置きました</a>。</small></p>
<hr />
<p>このサイトの印刷時のスタイルというものをまったく考えていなかったことに気づいたので、あわてて CSS と jQuery プラグインを書いて対応した。テストするのに結構な量の紙を消費したけど、サイトを見てる人には印刷してもらわない限り工夫が伝わんないってのがなんかもったいないとか思ったので、やったことをまとめて記事にしてみる。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/print-styles-01.png" />
<figcaption>Fig 1: スクリーンショット</figcaption>
</figure>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/print-styles-02.png" />
<figcaption>Fig 2: 印刷プレヴュー</figcaption>
</figure>
<h2>CSS ファイル</h2>
<p>印刷専用の CSS ファイルは用意せず、汎用 CSS ファイルの末尾に <code>@media</code> ルールで記述している。サイトの規模や運用方法なんかにもよるだろうけど、ファイル数はなるべく減らしたいので。</p>
<h2>不要な要素を削除</h2>
<p>CSS ではまずは印刷物として必要のない要素を <code>display: none;</code> で削除。各種ナビゲーション、ボタン、関連記事のリスト、サイドバー (検索、タグ・クラウドなど) あたりをばっさり消した。</p>
<h2>表示エリアの幅</h2>
<p>スクリーンでのレイアウトは左側に大きくパディングをとってるけど、印刷時は本文部分を中心に <code>width</code> を <code>auto</code>、左右の <code>padding</code> と <code>margin</code> を <code>0</code> にして、表示領域をなるべく広く確保。</p>
<h2>タイポグラフィ</h2>
<p>ロゴや見出しに Web フォントを使ってるけど、同じフォントがローカルにも入ってないと印刷には反映されない、というのは盲点だった。そのためロゴは Helvetica/Arial を使った印刷専用のスタイルに大幅修正。邪魔にならないサイズに抑えつつ、それだけだとちょっとさみしいので Favicon 画像を <code>content</code> プロパティで挿入してみた。</p>
<pre><code class="language-css">.logo {
font: 16px/1 "Helvetica Neue", "Helvetica", "Arial", sans-serif;
}
.logo:before {
content: url(/img/favicon.png);
margin: 0 8px 0 0;
float: left;
}
</code></pre>
<p>本文部分のフォントフェイスはメイリオで、サイズは 10px、行間はスクリーンよりやや大きく。メイリオはスクリーンで ClearType が無効の場合にかなり汚いので使うのがためらわれるけど、印刷だと小さいサイズでも読みやすいしボールドがしっかりボールドになるしでけっこうおすすめ。背景色と前景色はモノクロ、でもリンクやコードなどの配色はスクリーンのまま。</p>
<pre><code class="language-css">body {
font: 10px/1.8 "Meiryo", "Lucida Grande", "Verdana", sans-serif;
background: white;
color: black;
}
</code></pre>
<h2>リンクの URL をリストアップ</h2>
<p>言うまでもなく、印刷されたドキュメントはハイパーリンクの機能を持たないので、なんらかの手段でリンク先の URL を表現したいところ。よく用いられるのは、CSS の <code>content</code> プロパティで <code>href</code> 属性の値を出力する方法:</p>
<pre><code class="language-css">.content-body a:after {
content: " (" attr(href) ")";
}
</code></pre>
<p>詳しくは <a href="http://www.alistapart.com/articles/goingtoprint/">A List Apart: Articles: CSS Design: Going to Print</a> などを参照のこと。スマートだけど、とくに長い URL の場合に文章のリズムがくずれて読みにくくなってしまうのが難点。そこで今回は、リンクの URL を抽出して記事のおわりにリストアップする jQuery プラグインを書いてみた:</p>
<pre><code class="language-javascript">(function ($) {
$.fn.printHrefList = function () {
return this.each(function () {
if (!$(this).is(':has(a[href])')) {
return;
}
var $this = $(this),
$hrefList = $('<dl class="href-list" />').appendTo(this).hide(),
urlArr = [];
$this.find('a[href]').each(function () {
var $this = $(this),
url = this.href,
index;
if ($.inArray(url, urlArr) < 0) {
urlArr.push(url);
index = urlArr.length;
$hrefList.append('<dt>' + index + '</dt><dd>' + url + '</dd>');
} else {
index = $.inArray(url, urlArr) + 1;
}
$this.after(
$('<sub class="href-index">[' + index + ']</sub>').hide()
);
});
});
};
})(jQuery);
</code></pre>
<p>なにをやってるかというと、</p>
<ol>
<li>対象要素の末尾に <code>dl</code> 要素を生成し、いったん非表示に</li>
<li>対象要素内の <code>a</code> 要素を見つけて、それぞれのうしろに <code>sub</code> 要素を生成して連番をふり、やはりいったん非表示</li>
<li><code>a</code> 要素の番号を <code>dt</code> に入れて <code>dl</code> に追加</li>
<li>同じく <code>a</code> 要素の <code>href</code> 属性値を <code>dd</code> に入れて <code>dl</code> に追加</li>
</ol>
<p>という流れ。たとえば <code>.content-body</code> 内のリンクを抽出したいなら、まずこうしてメソッドを呼び出す:</p>
<pre><code class="language-javascript">$(function () {
$('.content-body').printHrefList();
});
</code></pre>
<p>そして、リスト (<code>dl</code>) とリンクの番号 (<code>sub</code>) が <code>.hide()</code> で非表示になっているので、印刷時のみ表示されるようにスタイルを指定する:</p>
<pre><code class="language-css">@media print {
sub.href-index {
display: inline !important;
}
dl.href-list {
display: block !important;
}
}
</code></pre>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/print-styles-03.png" />
<figcaption>Fig 3: スクリプトと CSS 適用後の印刷プレヴュー</figcaption>
</figure>
<p><del datetime="2010-05-15">同じ URL が複数出現した場合にちょっとうざいかなと思ったけど、対応するとややこしくなりそうなので保留。</del><ins datetime="2010-05-15">同じ URL が複数出現した場合に繰り返し出力しないよう修正した。</ins></p>
Bulletproof @font-face: Smiley variation
2010-05-16T00:00:00Z
https://terkel.jp/archives/2010/05/bulletproof-font-face-smiley-variation/
<p>CSS の @font-face ルールの「安全な」書式として <a href="http://paulirish.com/">Paul Irish</a> 氏の提唱する <a href="http://paulirish.com/2009/bulletproof-font-face-implementation-syntax/">Bulletproof @font-face syntax</a> (邦訳: <a href="http://hail2u.net/blog/webdesign/bulletproof-at-font-face-syntax.html">hail2u.net - Weblog - 安全な@font-faceの書き方(抄訳)</a>) がいつの間にかアップデートされていました。“Smiley variation” と名付けられたその最新版はこうなってます:</p>
<pre><code class="language-css">@font-face {
font-family:
'Graublau Web';
src:
url('GraublauWeb.eot');
src:
local('☺'),
url('GraublauWeb.otf') format('opentype');
}
</code></pre>
<p>“☺”。そう、「スマイリー・フェイス」です。はじめはなにかのジョークかと思いましたがそんなことはなく、マジでした。これを <code>src</code> プロパティのローカル参照部分に指定すると「より安全」というわけです。なぜか?</p>
<p>まず、この「スマイリー版」に至る前、「オリジナル版」の Bulletproof @font-face はこうでした:</p>
<pre><code class="language-css">@font-face {
font-family:
'Graublau Web';
src:
url('GraublauWeb.eot');
src:
local('Graublau Web Regular'),
local('Graublau Web'),
url('GraublauWeb.otf') format('opentype');
}
</code></pre>
<p>ポイントはふたつの <code>src</code> プロパティです。IE は Web フォントとして EOT 形式しかサポートしていませんが、そのほかのどのブラウザも EOT 形式をサポートしていません。そこで、ローカルのフォント名を参照する <code>local()</code> 書式を解釈できない IE の実装を利用して、ふたつの指定を分岐させているのです。つまりこの例は、「IE はサーバ上の <code>GraublauWeb.eot</code> を参照。それ以外のブラウザは、もしローカルに Graublau Web Regular または Graublau Web という名前のフォントがあればそれを、なければサーバの <code>GraublauWeb.otf</code> を参照せよ」と言っていることになります。</p>
<p>さて、「オリジナル版」から「スマイリー版」への修正点は、このふたつめの <code>src</code> プロパティのうちローカルのフォント名を参照する部分です。この書き方のどこに問題があるのかというと、<strong>ローカルのフォント名はユーザの環境に依存するので、サイト制作者の意図とは異なるフォントが読み込まれる可能性がある</strong>、という点らしいです (参考: <a href="http://typophile.com/node/63992">Different Fonts Named The Same: Does This Happen Frequently? | Typophile</a>)。つまり、サイト制作者がローカルのフォント名として Graublau Web を指定しても、もし Helvetica を Graublau Web という名前で使用している人がいれば、その環境では Helvetica で表示されてしまう、ということになります。まれなケースではありますが、その可能性は否定できないわけです。</p>
<p>じゃあローカル参照を省略しちゃえばよくね? となるんですが、前述のとおりそもそもこの記述は IE とそのほかのブラウザで指定を振り分けるためのものなので、<code>local()</code> の部分を削除すると IE 向けの指定が上書きされてしまう—つまり IE で Web フォントが無効になってしまいます。</p>
<p>そこで Irish 氏が提案しているのが、<strong>ローカル参照としてあえて「ありえないフォント名」を指定する</strong>という方法です。Mac では Unicode の 2 バイト文字がフォント名として無効なこともあり、“☺” という名前のフォントがローカルにインストールされている、または今後リリースされる可能性はまずないであろう、と。</p>
<p>この結果、IE は変わらず <code>local()</code> が指定された <code>src</code> プロパティを無視するのでサーバの EOT フォントを読み込み、そのほかのブラウザは “☺” フォントをローカルで探すものの見あたらないのでやはりサーバのフォントを読み込む、ということになります。めでたしめでたし。</p>
<p>なお、以前このブログでも <a href="https://terkel.jp/archives/2009/12/font-face-with-font-squirrel/">紹介</a> した <a href="http://www.fontsquirrel.com/">Font Squirrel</a> でダウンロードできる CSS ファイルはこの「スマイリー版」で記述されており、Irish 氏もその利用をすすめています。</p>
未来
2010-06-07T00:00:00Z
https://terkel.jp/archives/2010/06/the-future/
<blockquote cite="urn:ISBN:978-4094022254">
<p>「信じたい」と思えない未来なんて、「未来」に価しない。</p>
</blockquote>
<p class="Credit"><small>(橋本治『ぼくらの未来計画――貧乏は正しい!』)</small></p>
<blockquote cite="urn:ISBN:978-4062633000">
<p>「暗示の外に出ろ。俺たちには未来がある」</p>
</blockquote>
<p class="Credit"><small>(いとうせいこう『解体屋外伝』)</small></p>
<blockquote>
<p>未来は僕等の手の中‼</p>
</blockquote>
<p class="Credit"><small>(真島昌利「未来は僕等の手の中」)</small></p>
HTML5 の autofocus 属性を jQuery でクロスブラウザに
2010-07-18T00:00:00Z
https://terkel.jp/archives/2010/07/html5-autofocus-fix-with-jquery/
<p>一部を修正して <a href="https://gist.github.com/1236495">Gist に置きました</a>。IE6 と 7 で <code>autofocus</code> 属性値を省略すると動作しない件にも対応しています。</p>
<p>HTML5 ではフォームのコントロールに <a href="http://www.w3.org/TR/2010/WD-html5-20100624/association-of-controls-and-forms.html#autofocusing-a-form-control" title="4.10.19.4 Autofocusing a form control — HTML5 (W3C Working Draft 4 March 2010)"><code>autofocus</code> 属性</a> が定義されています。その名のとおり、ページが読み込まれたときにコントロールに自動でフォーカスするためのものです。</p>
<pre><code class="language-html"><input type="search" name="s" autofocus>
<input type="submit" value="Search">
</code></pre>
<p>現時点では Safari 5.0、Chrome 5.0、Opera 10.60 がサポートしています。そこで、前回の <a href="https://terkel.jp/archives/2010/07/html5-placeholder-fix-with-jquery/">placeholder の記事</a> と同様に、IE6–8 や Firefox でも HTML5 で <code>autofocus</code> を扱えるように jQuery スクリプトを書いてみました。</p>
<pre><code class="language-javascript">$(function () {
var supportsInputAttribute = function (attr) {
var input = document.createElement('input');
return attr in input;
};
if (!supportsInputAttribute('autofocus')) {
$('[autofocus]').focus();
}
});
</code></pre>
<p>とても簡単です。まず <code>autofocus</code> 属性がサポートされているか調べ、もしサポートされていなければ <code>focus()</code> メソッドで <code>autofocus</code> 属性を持つ要素にフォーカスします。<a href="https://terkel.jp/demo/html5-autofocus-fix-with-jquery.html">デモ</a> を用意したので確認してみてください。</p>
<p>なお、<code>autofocus</code> は <a href="http://www.w3.org/TR/2010/WD-html5-20100624/common-microsyntaxes.html#boolean-attributes" title="2.4.2 Boolean attributes — HTML5 (W3C Working Draft 4 March 2010)">boolean attribute</a> なので、前述のマークアップ例のように属性の省略記法が使えるのですが、そうすると IE6 と 7 ではこのスクリプトが動作しません。そのため以下のように属性名と値を省略せずに書く必要があります。</p>
<pre><code class="language-html"><input type="search" name="s" autofocus="autofocus">
</code></pre>
HTML5 の placeholder 属性を jQuery でクロスブラウザに
2010-07-18T00:00:00Z
https://terkel.jp/archives/2010/07/html5-placeholder-fix-with-jquery/
<p role="note"><small>2011-09-23更新: 一部を修正して <a href="https://gist.github.com/1236496">Gist に置きました</a>。</small></p>
<hr />
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/html5-placeholder.png" />
</figure>
<p>フォームの入力フィールドにあらかじめテキストを表示させておく「プレースホルダ」。ブラウザの検索バーなんかに見られるような、フィールドが空のときは薄く文字が表示されていて、フォーカスすると消えるあれです。このプレースホルダの機能、HTML5 では <code>input</code> 要素や <code>textarea</code> 要素の <strong><code>placeholder</code> 属性</strong>で簡単に実現できます。</p>
<pre><code class="language-html"><label>お名前 <input type="text" name="fn" placeholder="山田 太郎"></label>
</code></pre>
<p>しかしながら、この <code>placeholder</code> 属性をサポートしているのは今のところ Safari と Chrome のみ。そのほかのブラウザでは無視されてしまいます。そこで、この <code>placeholder</code> 属性をクロスブラウザで扱えるようにする jQuery スクリプトを書いてみました。<a href="https://terkel.jp/demo/html5-placeholder-fix-with-jquery.html">実際に動作しているデモ</a> も用意したのでどうぞ。</p>
<pre><code class="language-javascript">$(function () {
var supportsInputAttribute = function (attr) {
var input = document.createElement('input');
return attr in input;
};
if (!supportsInputAttribute('placeholder')) {
$('[placeholder]').each(function () {
var
input = $(this),
placeholderText = input.attr('placeholder'),
placeholderColor = 'GrayText',
defaultColor = input.css('color');
input.
focus(function () {
if (input.val() === placeholderText) {
input.val('').css('color', defaultColor);
}
}).
blur(function () {
if (input.val() === '') {
input.val(placeholderText).css('color', placeholderColor);
} else if (input.val() === placeholderText) {
input.css('color', placeholderColor);
}
}).
blur().
parents('form').
submit(function () {
if (input.val() === placeholderText) {
input.val('');
}
});
});
}
});
</code></pre>
<p>解説してみます。まずはじめのポイントは、ブラウザが <code>placeholder</code> 属性をサポートしているかどうかを判定している点です。判定には実際にはドキュメントに現れないダミーの <code>input</code> 要素を作り、<code>placeholder</code> プロパティの有無を調べます。その結果、もしブラウザが <code>placeholder</code> をサポートしていればスクリプトは何もしません。以降のスクリプトはサポートしていないブラウザでのみ実行されます。</p>
<pre><code class="language-javascript">var supportsInputAttribute = function (attr) {
var input = document.createElement('input');
return attr in input; // 引数で指定された属性がサポートされていれば true を返す
};
if (!supportsInputAttribute('placeholder')) {
// placeholder 属性をサポートしないブラウザでのみ実行
}
</code></pre>
<p><code>placeholder</code> 属性は <code>input</code> 要素だけではなく <code>textarea</code> 要素でも使われるので、セレクタは以下のように <code>placeholder</code> 属性を持つすべての要素を対象とします。</p>
<pre><code class="language-javascript">$('[placeholder]').each(function () {
// placeholder 属性を持つすべての要素で実行
});
</code></pre>
<p>次に、対象の各要素の <code>placeholder</code> 属性の値と、プレースホルダの前景色をそれぞれ変数に格納します。ここではプレースホルダの前景色に具体的な色ではなくシステムカラーの <code>GrayText</code> を指定。OS やブラウザの GUI で選択できないテキストやなんかに使われる色ですね。実際の色は環境に依存するわけですが、だいたい <code>#999</code> とか <code>#aaa</code> あたりになるようです。また読み込み時のフィールドの前景色も保持しておきます。</p>
<pre><code class="language-javascript">var
input = $(this),
placeholderText = input.attr('placeholder'), // placeholder 属性の値
placeholderColor = 'GrayText', // プレースホルダの前景色
defaultColor = input.css('color'); // フィールドの本来の前景色
</code></pre>
<p>そして、フィールドがフォーカスを得たときと失ったときにその <code>value</code> を調べ、プレースホルダの表示と非表示を実行します。ページの読み込み時にはフィールドがブラー状態になるようにし、その時点でフィールドが空なら <code>placeholder</code> 属性の値をフィールドにセット、そしてフォーカス時にプレースホルダが表示されていればそれを消去。同時に前景色も切り替えています。最後に、フィールドの <code>value</code> にプレースホルダが入った状態でそのまま送信されないように、フォームのサブミット時にも値をチェックしています。</p>
<pre><code class="language-javascript">input.
focus(function () { // フォーカス時
if (input.val() === placeholderText) {
input.val('').css('color', defaultColor);
}
}).
blur(function () { // ブラー時 (フォーカスが外れたとき)
if (input.val() === '') {
input.val(placeholderText).css('color', placeholderColor);
} else if (input.val() === placeholderText) {
input.css('color', placeholderColor);
}
}).
blur(). // ページ読み込み時にいったんブラー
parents('form').
submit(function () { // サブミット時
if (input.val() === placeholderText) {
input.val('');
}
});
</code></pre>
<p>プレースホルダをどのように表現するかについては、新たに <code>span</code> などの要素を生成して CSS でフィールドに重ねるという手法もありますが、ここではフィールドの <code>value</code> にプレースホルダのテキストを突っ込むというアプローチを採りました。そのため、クライアントサイドでフォームをバリデートするようなスクリプトとの共存は難しいかもしれません。</p>
<p>またこのスクリプトの弱点として「<code>placeholder</code> 属性の値と同じ文字列をサブミットできない」という点があります。つまり、たとえば “Lorem ipsum” というプレースホルダが設定されたフィールドに “Lorem ipsum” という文字列を入力しても、それはプレースホルダと見なされてしまい送信できないわけです。これはうまく解決する方法が思いつかなかったので、とりあえずプレースホルダの文言を工夫するしかないです…</p>
<p>ところで、プレースホルダにはどのようなテキストがふさわしいのでしょうか。W3C の仕様では以下のように書かれています:</p>
<blockquote cite="http://www.w3.org/TR/2010/WD-html5-20100624/common-input-element-attributes.html#the-placeholder-attribute" lang="en">
<p>The <code>placeholder</code> attribute represents a <em>short</em> hint (a word or short phrase) intended to aid the user with data entry. A hint could be a sample value or a brief description of the expected format. The attribute, if specified, must have a value that contains no U+000A LINE FEED (LF) or U+000D CARRIAGE RETURN (CR) characters.</p>
<p>Note: For a longer hint or other advisory text, the <code>title</code> attribute is more appropriate.</p>
<p>The <code>placeholder</code> attribute should not be used as an alternative to a <code>label</code>.</p>
</blockquote>
<p class="Credit"><small>(<a href="http://www.w3.org/TR/2010/WD-html5-20100624/common-input-element-attributes.html#the-placeholder-attribute">4.10.7.2.11 The placeholder attribute — HTML 5 [W3C Working Draft 4 March 2010]</a>)</small></p>
<p>というわけで、<code>placeholder</code> が示すのは「ユーザのデータ入力を補助するためのちょっとしたヒント」といったところですね。具体的には「こんな感じで入力してくださいね」という記入例のようなものなどでしょうか。また長いヒントや注意書きなどは <code>title</code> 属性のほうがよいでしょう、とされています。ちなみに今回のスクリプトの <a href="https://terkel.jp/demo/html5-placeholder-fix-with-jquery.html">デモ</a> は上記仕様にあったマークアップ例を使わせてもらってます。</p>
<p>とくに注意したいのが「<code>label</code> 要素の代替として用いられるべきではない」という部分です。たとえば以下のようなマークアップはけっこうやってしまいそうですが、あまりよろしくないですね:</p>
<pre><code class="language-html"><input type="text" placeholder="お名前">
<input type="email" placeholder="メールアドレス">
</code></pre>
シングルライン CSS
2010-08-07T00:00:00Z
https://terkel.jp/archives/2010/08/single-line-css/
<p>最近、CSS を書くときにコードのフォーマットを今までと少し変えてみてます。宣言 (プロパティと値のセット) ごとに改行するのではなく、セレクタごとに改行する、いわゆる <strong>シングルライン CSS</strong> です。つまり、</p>
<pre><code class="language-css">table {
border-collapse: collapse;
margin: 2em 0;
}
table th, table td {
pading: 0.5em 1em;
border: 1px solid silver;
}
</code></pre>
<p>↑ こうじゃなくて、</p>
<pre><code class="language-css">table { border-collapse: collapse; margin: 2em 0; }
table th,
table td { pading: 0.5em 1em; border: 1px solid silver; }
</code></pre>
<p>↑ こう。パッと見は読みづらく感じるかもしれませんが、実際に自分のコードを管理してみると意外にそんなことはなくて、すぐに慣れます。</p>
<p>このフォーマットにして良かったのは、まず探している箇所が見つけやすくなりました。CSS コードを読む場合、まず見るのは宣言ではなくセレクタであるはずで、その点でこのフォーマットは 1 行に 1 セレクタなので目で追うのがすごく楽です。</p>
<p>もうひとつは CSS モジュールの設計に良い影響が期待できること。ある程度の大きさのモジュールの場合、宣言ごとの改行だとコード上で見えているのは常にモジュールの一部でしかないのに対し、セレクタごとに改行するとモジュール全体を見通すことが容易で、しかもそれぞれのモジュールが「かたまり」として浮かび上がって見えてきます。その結果、より可搬性や独立性の高いモジュールの設計を意識しやすくなりました。</p>
<p>そもそもこのフォーマットを試したのは、CSS のコードがひたすら縦方向に長くなっていくところがイヤで、そこをなんとか圧縮したかったからなんですが、結果的にそれだけではなく、CSS の設計面を今までとは違った角度から見られるようになったことは大きな収穫でした。</p>
HTML5 + WAI-ARIA: 入門篇
2010-08-10T00:00:00Z
https://terkel.jp/archives/2010/08/beginning-html5-and-wai-aria/
<p>このサイトを HTML5 でリニューアルした際に保留としたまますっかり忘れかけていましたが、ようやく <strong><a href="http://www.w3.org/WAI/intro/aria.php" title="WAI-ARIA Overview">WAI-ARIA</a></strong> を導入してみました。</p>
<p>WAI-ARIA は W3C の <a href="http://www.w3.org/WAI/">Web Accessibility Initiative (WAI)</a> が公開している技術仕様で、Web コンテントや Web アプリケーションのアクセシビリティを強化することを目的としています。具体的には、Web ブラウザや支援技術 (AT) がコンテントのセマンティクスをより適切に認識できるよう、HTML ドキュメントに要素の「役割」や「状態」といった詳細な情報を付与するものです。名称に RIA とあるように、Ajax などによるリッチ・インターネット・アプリケーションをおもな対象とした仕様ですが、HTML5 によるシンプルな Web ページに取り入れることもできます。ここでは WAI-ARIA の HTML5 への導入について「入門篇」としてまとめてみました。</p>
<p>WAI-ARIA ではドキュメントの要素が「どのような役割を持っているか」を「<strong>ロール</strong> (role)」と呼び、HTML 要素の <strong><code>role</code> 属性</strong> として表現します。仕様には多くのロールが定義されていますが、そのうち Web ページの文書構造を定義したものが <a href="http://www.w3.org/TR/wai-aria/roles#landmark_roles">Landmark Roles</a> という一連のロールです。Landmark という名前のとおり、ドキュメントの特定の領域に対して「目印」をつけるイメージでしょうか。たとえば、サイト内検索フォームを含む <code>nav</code> 要素に対して、以下のようにロールを示すことができます:</p>
<pre><code class="language-html"><nav role="search">
<h2>Search this site</h2>
<form ...>
<p><input type="search" ...>...</p>
</form>
</nav>
</code></pre>
<p>では、以下のような「ページヘッダ」「コンテント」「サイドバー」「ページフッタ」からなる典型的な Web ページを想定し、いくつかのロールについてどのようにマークアップに組み込むかを考えてみます:</p>
<pre><code class="language-html"><body>
<header class="pageHeader">
<h1 class="logo">...</h1>
<nav class="globalNav">
<ul>...</ul>
</nav>
</header>
<article class="content">
<header class="contentHeader">
<h1>...</h1>
<time pubdate datetime="...">...</time>
</header>
<div class="contentBody">
...
</div>
</article>
<aside class="sidebar">
...
</aside>
<footer class="pageFooter">
<nav class="legal">
<ul>...</ul>
</nav>
<p class="copyrighgt"><small>&#169;...</small></p>
</footer>
</body>
</code></pre>
<p>まず、ロゴやサイト内検索などを含むサイト全体に向けたコンテンツ領域のためのロール、<a href="http://www.w3.org/TR/wai-aria/roles#banner"><code>banner</code></a> を「ページヘッダ」に組み込むことができます:</p>
<pre><code class="language-html"><header role="banner" class="pageHeader">
<h1 class="logo">...</h1>
<nav class="globalNav">
<ul>...</ul>
</nav>
</header>
</code></pre>
<p><a href="http://www.w3.org/TR/wai-aria/roles#contentinfo"><code>contentinfo</code></a> は「親となるドキュメントについての情報を含む領域」とされており、そこに含まれる情報の例として「著作権や個人情報についての考え方」が挙げられています。「ページフッタ」が該当しますね:</p>
<pre><code class="language-html"><footer role="contentinfo" class="pageFooter">
<nav class="legal">
<ul>...</ul>
</nav>
<p class="copyright"><small>&#169;...</small></p>
</footer>
</code></pre>
<p><a href="http://www.w3.org/TR/wai-aria/roles#main"><code>main</code></a> はその名のとおり「ドキュメントの主たるコンテント」です。ブログの個別記事ページなら記事本体の <code>artcile</code> 要素がふさわしいでしょう:</p>
<pre><code class="language-html"><article role="main" class="content">
<header class="articleHeader">
<h1>...</h1>
<time pubdate datetime="...">...</time>
</header>
<div class="articleContent">
...
</div>
</article>
</code></pre>
<p>以上、主要な Landmark ロールについて簡単な例を挙げてみました。このように HTML のソースコードにちょっと手を加えるだけで、アクセシビリティの強化が図れるだけでなく、たとえばサイトのヘッダには記事のヘッダにはない特別なセマンティクスを与えたように、マークアップをより明確にすることができるのです。</p>
<p>というわけで、HTML5 でのマークアップには WAI-ARIA をぜひおすすめしたいのですが、情報がまだ少ないために導入がためらわれる場合もあると思います。また WAI-ARIA の仕様は小さいものではないので、すべてを把握しようとすると大変です。しかし、今回の例のようにページの基本的な構造に組み込むのは難しいことではないので、フロントエンドに携わる皆さんにはぜひ取り組んでみてもらいたいと思います。そしてより良い使い方についての議論などが活発になって、情報が増えるといいですよね。実際、僕もまだ理解していない部分ばかりですし。たとえば、HTML5 の <code>nav</code> 要素と WAI-ARIA の <code>navigation</code> ロールなど、意味のかぶるものをどう捉えるべきかとか。</p>
<p>最後に今回参考にしたリソースをまとめておきます。まず W3C の文書ですが、技術仕様 WAI-ARIA 1.0 のほか、いくつかの関連文書が公開されています:</p>
<ul>
<li><a href="http://www.w3.org/TR/wai-aria/">Accessible Rich Internet Applications (WAI-ARIA) 1.0</a></li>
<li><a href="http://www.w3.org/TR/wai-aria-primer/">WAI-ARIA Primer</a></li>
<li><a href="http://www.w3.org/TR/wai-aria-practices/">WAI-ARIA Authoring Practices 1.0</a></li>
<li><a href="http://www.w3.org/TR/wai-aria-implementation/">WAI-ARIA User Agent Implementation Guide 1.0</a></li>
<li><a href="http://www.w3.org/TR/wai-aria-roadmap/">Roadmap for Accessible Rich Internet Applications (WAI-ARIA Roadmap)</a></li>
</ul>
<p>加えて上記仕様の邦訳とそのほかにいくつか。とくに Opera の Gez Lemon 氏の記事は WAI-ARIA を今すぐ使い始めるべきとを強くアピールしてくれていて好きです。「Aria のロールやプロパティを追加すると、HTML 4.01 や XHTML 1.0 でバリデートしない。しかしそれでもよいのだ」とか「ARIA を使うことにデメリットは何もない」とか:</p>
<ul>
<li><a href="http://www.hitachi.co.jp/universaldesign/wai-aria/index.html">WAI-ARIA (日本語訳): 日立のユニバーサルデザイン</a></li>
<li><a href="http://www.mitsue.co.jp/column/backnum/20090501.html">WAI-ARIA の誕生と現状 | コラム | ミツエーリンクス</a></li>
<li><a href="http://dev.opera.com/articles/view/introduction-to-wai-aria/">Introduction to WAI ARIA - Opera Developer Community</a>
<ul>
<li>邦訳: <a href="http://d.hatena.ne.jp/aratako0/20090709/p1">WAI-ARIA 導入 (日本語訳) - TRANS</a></li>
</ul>
</li>
<li><a href="http://thinkit.co.jp/book/2008/08/27/161">WAI-ARIA によるアクセシブル RIA | Think IT</a></li>
</ul>
Web サイトのスマートフォン最適化: UA 判別篇
2010-08-11T00:00:00Z
https://terkel.jp/archives/2010/08/optimizing-websites-for-smartphones-with-ua-detection/
<p><strong><a href="http://www.apple.com/jp/iphone/">iPhone</a></strong> 買いました。iPhone 4。はじめてのスマートフォンですよ。</p>
<p>で、この機会にこのサイトのスマートフォン最適化を図ろうと考えたわけです。今までなにもしてなかったので。しかし恥ずかしながらスマートフォン向けのサイトを作った経験がなかったので、どこから手をつけたものかわからない。そこで、とりあえず参考になりそうなネタを探そうと「wordpress iphone 最適化」あたりでググってみたところ (このサイトは WordPress で作ってます)、どうも <a href="http://wordpress.org/extend/plugins/wptouch/">WPtouch iPhone Theme</a> というプラグインが人気らしい。このプラグインは有効にするだけで WordPress サイトをスマートフォン向けに最適化してくれる便利なもので、採用してるサイトもよく見かけます。</p>
<p>でもプラグインをそのまま導入したんじゃ面白くない。やっぱテーマは自分でいじりたいし。となると、とりあえず知りたいのは「スマートフォンからのアクセスをどのように判別しているのか」または「スマートフォン向けのコンテントやスタイルをどのように振り分けているのか」といったところで、そこらへんがわかればあとはいつものテーマ作りの手法でどうにかなるだろうと考えまして、とりあえずダウンロードしてソースコードを覗いてみたんです。あわよくば自前のテーマの参考にしようと。すると <code>wptouch.php</code> というファイルに以下のような箇所を見つけました:</p>
<pre><code class="language-php"><?php
$useragents = array(
'iPhone', // Apple iPhone
'iPod', // Apple iPod touch
'Android', // 1.5+ Android
'dream', // Pre 1.5 Android
'CUPCAKE', // 1.5+ Android
'blackberry9500', // Storm
'blackberry9530', // Storm
'blackberry9520', // Storm v2
'blackberry9550', // Storm v2
'blackberry9800', // Torch
'webOS', // Palm Pre Experimental
'incognito', // Other iPhone browser
'webmate' // Other iPhone browser
);
?>
</code></pre>
<p>これはどこからどう見てもスマートフォン判別用の文字列 (の配列)。どうやらこれを HTTP ヘッダの <code>User-Agent</code> と突き合わせて、スマートフォンからのアクセスを判別しているらしい。そうとわかればあとは簡単で、自作テーマの <code>functions.php</code> にこんな関数を書いてみました:</p>
<pre><code class="language-php"><?php
// Thanks to BraveNewCode's WPtouch iPhone Theme for the UA list.
// (http://wordpress.org/extend/plugins/wptouch/)
function is_mobile () {
$useragents = array(
'iPhone', // Apple iPhone
'iPod', // Apple iPod touch
'Android', // 1.5+ Android
'dream', // Pre 1.5 Android
'CUPCAKE', // 1.5+ Android
'blackberry9500', // Storm
'blackberry9530', // Storm
'blackberry9520', // Storm v2
'blackberry9550', // Storm v2
'blackberry9800', // Torch
'webOS', // Palm Pre Experimental
'incognito', // Other iPhone browser
'webmate' // Other iPhone browser
);
$pattern = '/'.implode('|', $useragents).'/i';
return preg_match($pattern, $_SERVER['HTTP_USER_AGENT']);
}
?>
</code></pre>
<p>この <code>is_mobile()</code> 関数でやっているのは、</p>
<ol>
<li>まず想定されるスマートフォンを判別するための文字列の配列を作り、</li>
<li>それを正規表現パターンに変換して、</li>
<li>HTTP ヘッダの <code>User-Agent</code> にマッチすれば <code>true</code> を返す、</li>
</ol>
<p>といったところです。これで、<code>is_mobile()</code> を <a href="http://wpdocs.sourceforge.jp/Conditional_Tags" title="条件分岐タグ - WordPress Codex 日本語版">条件分岐タグ</a> としてテンプレートで使うことができます。たとえばスマートフォン専用の CSS を読み込ませる場合はこうです:</p>
<pre><code class="language-php"><?php if (is_mobile()) { ?>
<link rel="stylesheet" type="text/css" href="/css/mobile.css" />
<?php } ?>
</code></pre>
<p>「スマートフォン以外の場合にサイドバーを読み込む」ならこう:</p>
<pre><code class="language-php"><?php
if (!is_mobile()) {
get_sidebar();
}
?>
</code></pre>
<p>なお同様の判別は JavaScript でも可能です。スマートフォン用 CSS の適用はこんな感じでできます:</p>
<pre><code class="language-javascript">// Thanks to BraveNewCode's WPtouch iPhone Theme for the UA list.
// (http://wordpress.org/extend/plugins/wptouch/)
function is_mobile () {
var useragents = [
'iPhone', // Apple iPhone
'iPod', // Apple iPod touch
'Android', // 1.5+ Android
'dream', // Pre 1.5 Android
'CUPCAKE', // 1.5+ Android
'blackberry9500', // Storm
'blackberry9530', // Storm
'blackberry9520', // Storm v2
'blackberry9550', // Storm v2
'blackberry9800', // Torch
'webOS', // Palm Pre Experimental
'incognito', // Other iPhone browser
'webmate' // Other iPhone browser
];
var pattern = new RegExp(useragents.join('|'), 'i');
return pattern.test(navigator.userAgent);
}
if (is_mobile()) {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = '/css/mobile.css';
document.getElementsByTagName('head')[0].appendChild(link);
}
</code></pre>
<p>蛇足ながら、上記 <code>if</code> 文の <code>link</code> 要素を生成する部分は、jQuery なら以下のように書けますね:</p>
<pre><code class="language-javascript">$(function () {
if (is_mobile()) {
$('<link/>').attr({
rel: 'stylesheet',
type: 'text/css',
href: '/css/mobile.css'
}).appendTo('head');
}
});
</code></pre>
<p>しかし、ここまで長々と書いといてなんですが、こういった UA 判別のアプローチって、実際のところどうなんでしょうね? 判別のために文字列のリストを用意するっていう部分が、どうもいまいちなんじゃないかって気がするんですよね。たとえば、今後出てくるであろう新しいスマートフォンに対応しようとすると、このリストを永遠にメンテナンスし続けなきゃなんないじゃないですか。実際、つい先日も WPtouch iPhone Theme のアップデートで新しい BlackBerry が 3 つも追加されてたし。</p>
<p>コンテントを出し分けたり別の URL へリダイレクトしたりしようとすると、やはり今回のような UA 検出が必要かもしれませんが、もしスマートフォンを判別する目的がスタイルの振り分けなら、やっぱ <a href="http://standards.mitsue.co.jp/resources/w3c/TR/css3-mediaqueries/">メディアクエリー</a> を使うのが王道なのかなと思い始めてます。というわけで、この続きは「メディアクエリー篇」で…</p>
search 型 input 要素のスタイルをリセット
2010-08-13T00:00:00Z
https://terkel.jp/archives/2010/08/reset-input-type-search-style/
<p>HTML5 では、<code>input</code> 要素の <code>type</code> 属性に <code>search</code> という検索フィールドのための値が使えます。現時点ではこの <code>search</code> タイプをサポートしているのは Safari と Chrome のみなのですが、これらの対応ブラウザでは、入力したテキストをキャンセルするボタンが表示され、Mac ではフィールドが角丸になります。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/input-type-search-1.png" />
</figure>
<p>しかし、Safari と Chrome でこの <code>search</code> タイプの <code>input</code> を CSS でスタイリングしようとしてもほとんどコントロールできず、ブラウザのデフォルトでレンダリングされてしまいます。<code>font</code>、<code>padding</code>、<code>border</code>、<code>background</code> といったごく基本的なプロパティがことごとく無効。これをなんとかリセットし、<code>text</code> タイプと同様にスタイリングできるようにもっていくのはけっこう面倒で、以下のようなコードが必要です:</p>
<pre><code class="language-css">/* Reset input[type="search"] */
input[type="search"] {
-webkit-appearance: textfield;
-webkit-box-sizing: content-box;
}
input[type="search"]:focus {
outline-offset: -2px;
}
input[type="search"]::-webkit-search-decoration {
display: none;
}
</code></pre>
<p>順に説明すると、まず <a href="http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariCSSRef/Articles/StandardCSSProperties.html#//apple_ref/doc/uid/TP30001266-_webkit_appearance" title="Safari CSS Reference: Supported CSS Properties"><code>-webkit-appearance</code></a> という、コントロールの外観を決めるプロパティで <code>searchfield</code> というデフォルト値が設定されているので、<code>textfield</code> 値で上書き。これで基本的なプロパティは制御が可能になります。また、<a href="http://developer.apple.com/safari/library/documentation/AppleApplications/Reference/SafariCSSRef/Articles/StandardCSSProperties.html#//apple_ref/doc/uid/TP30001266--webkit-box-sizing" title="Safari CSS Reference: Supported CSS Properties"><code>-webkit-box-sizing</code></a> プロパティが <code>border-box</code> になっているので、<code>text</code> タイプと同じ <code>content-box</code> にしておきます。</p>
<p>この段階でほとんど <code>text</code> タイプと同じスタイルになるのですが、よく見るとまだ細かな違いがあります。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/input-type-search-2.png" />
</figure>
<p>まず、フォーカス時に表示されるアウトラインと要素の間に微妙な隙間があります。これは <code>outline-offset</code> で制御が可能で、<code>-2px</code> にすると <code>text</code> タイプと同じになるようです。</p>
<p>もうひとつ、入力領域の左側に <code>padding</code> プロパティではコントロールできない余白が発生します。これはどうやら <code>::-webkit-search-decoration</code> という擬似要素のようで、デフォルトでは以下のような指定になっています:</p>
<pre><code class="language-css">input[type="search"]::-webkit-search-decoration {
-webkit-appearance: searchfield-decoration;
display: inline-block;
}
</code></pre>
<p>正直、どういう意味を持つ要素なのかいまいちよくわからないのですが、ともあれこれを <code>display: none;</code> で非表示にすれば余白はなくなります。</p>
<p><code>::-webkit-search-decoration</code> 擬似要素は <a href="http://developer.apple.com/safari/library/documentation/appleapplications/reference/safarihtmlref/Articles/Attributes.html#//apple_ref/doc/uid/TP40008058-results" title="Safari HTML Reference: Supported Attributes"><code>results</code></a> 属性という Apple 独自の拡張が関係しています。<code>results</code> 属性は <code>search</code> 型 <code>input</code> 要素の検索履歴を保存し入力候補としてリストアップするためのもので、値として履歴の表示件数を数値で指定します (<code><input type="search" results="10"></code>)。Safari でしか利用できませんが、指定すると虫眼鏡と下向き三角形のアイコンが表示され、履歴を参照できるようになります。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/input-type-search-4.png" />
</figure>
<p><code>::-webkit-search-decoration</code> 擬似要素はこのアイコンまわりのスタイルを指定するものらしく、そのため <code>results</code> 属性を指定している場合は非表示にできません。</p>
<p>なお、この <code>::-webkit-search-decoration</code> 擬似要素については <a href="http://b.hatena.ne.jp/forestk/20100821#bookmark-24076080" title="はてなブックマーク - forestkのブックマーク - 2010年8月21日">forestk さんのご指摘</a> をもとに追記しました。ありがとうございます。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/input-type-search-3.png" />
</figure>
<p>以上でようやく <code>search</code> タイプのスタイルがリセットできます。あとは <code>text</code> タイプと同様のスタイリングが可能なはずです。<a href="https://terkel.jp/demo/reset-input-type-search-style.html">デモ</a> を用意したので、Mac の Safari か Chrome で確認してみてください。</p>
HTML5 のテーブル関連要素
2010-11-02T00:00:00Z
https://terkel.jp/archives/2010/11/html5-tabular-data/
<p>HTML5 の <a href="http://www.w3.org/TR/html5/tabular-data.html#tabular-data">テーブル関連要素の仕様</a> は HTML 4.01 から変更されている部分がけっこうあるようなので、変更点を簡単にまとめてみました。なお本稿での HTML5 の仕様は <a href="http://www.w3.org/TR/2010/WD-html5-20101019/">2010 年 10 月 19 日付 W3C 草案</a> を参照しています。</p>
<ul>
<li><a href="http://www.w3.org/TR/html5/tabular-data.html#the-table-element"><code>table</code> 要素</a> はテーブルの内容を説明するための <a href="http://www.w3.org/TR/html5/tabular-data.html#attr-table-summary"><code>summary</code> 属性</a> を持てるが、<a href="http://www.w3.org/TR/html5/tabular-data.html#table-descriptions">代替手段</a> を用いることが推奨される。たとえば表の前にテキストを配置したり、<code>caption</code> 要素や <code>figcaption</code> 要素を用いたりなど。</li>
<li><a href="http://www.w3.org/TR/html5/tabular-data.html#the-caption-element"><code>caption</code> 要素</a> の内容モデルは <a href="http://www.w3.org/TR/html5/content-models.html#flow-content">Flow content</a> なので、ほとんどの要素を含むことができる。たとえば <code>p</code> とか <code>ul</code> とか。ただし <code>table</code> 要素を子孫に含んではダメ。</li>
<li><a href="http://www.w3.org/TR/html5/tabular-data.html#the-col-element"><code>col</code> 要素</a> は <code>span</code> 属性を持たない <a href="http://www.w3.org/TR/html5/tabular-data.html#the-colgroup-element"><code>colgroup</code> 要素</a> の子要素でなければならない。つまり <code>table</code> の直下に置いてはダメで、必ず <code>colgroup</code> の中に置く必要がある。</li>
<li><a href="http://www.w3.org/TR/html5/tabular-data.html#the-tbody-element"><code>tbody</code> 要素</a> は省略できる。XHTML 1.0 といっしょ。</li>
<li><a href="http://www.w3.org/TR/html5/tabular-data.html#the-tfoot-element"><code>tfoot</code> 要素</a> は <code>tbody</code> 要素または <code>tr</code> 要素のうしろに出現してもよい。つまり、HTML 4.01 では <code>thead</code> → <code>tfoot</code> → <code>tbody</code> の順でなければいけなかったのが、<code>thead</code> → <code>tbody</code> → <code>tfoot</code> もアリ。ただし、同じ <code>table</code> 要素内に複数あってはダメ。</li>
<li><a href="http://www.w3.org/TR/html5/tabular-data.html#the-td-element"><code>td</code> 要素</a> は <a href="http://www.w3.org/TR/2010/WD-html5-20101019/tabular-data.html#attr-th-scope"><code>scope</code> 属性</a> を持てない。同属性を持てるのは <a href="http://www.w3.org/TR/html5/tabular-data.html#the-th-element"><code>th</code> 要素</a> だけ。</li>
<li><code>td</code> 要素と <code>th</code> 要素の <a href="http://www.w3.org/TR/html5/obsolete.html#attr-tdth-abbr"><code>abbr</code> 属性</a> と <a href="http://www.w3.org/TR/html5/obsolete.html#attr-tdth-axis"><code>axis</code> 属性</a> は廃止。仕様では <a href="http://www.w3.org/TR/html5/obsolete.html#non-conforming-features">代替手段</a> が提案されており、<code>abbr</code> 属性は「セルの内容を明白かつ簡潔にすべし、より詳細なテキストを含めるには <code>title</code> 属性を使え」、<code>axis</code> 属性は「対応する <code>th</code> 要素の <code>scope</code> 属性を使え」としている。</li>
</ul>
<p>以前に書いた <a href="https://terkel.jp/archives/2010/04/the-dl-element-in-html5/"><code>dl</code> 要素</a> もそうですが、今までおなじみの要素でも HTML5 で仕様が再定義されていることがあります。新しい要素とか廃止されたフィーチャーとかの大きな変更は <a href="http://www.w3.org/TR/html5-diff/">HTML5 differences from HTML4</a> (邦訳: <a href="http://standards.mitsue.co.jp/resources/w3c/TR/html5-diff/">HTML5 における HTML4 からの変更点</a>) などにまとめられているのでわかりやすいですが、たとえば本稿で取り上げた <code>col</code>/<code>colgroup</code> 要素みたいに地味な変更は仕様書を読んでいても気づきにくいので注意が必要ですね。</p>
PHP で著作権表示の年を自動更新
2010-12-30T00:00:00Z
https://terkel.jp/archives/2010/12/auto-update-copyright-date-using-php/
<p>PHP を使ってサイトの <a href="http://ja.wikipedia.org/wiki/%E8%91%97%E4%BD%9C%E6%A8%A9%E8%A1%A8%E7%A4%BA" title="著作権表示 - Wikipedia">著作権表示</a> (コピーライト) の年を自動で更新したいとき、よく用いられるのが以下のようなコードです:</p>
<pre><code class="language-html">&#169; 2001–<?php echo date('Y'); ?> Example.com
</code></pre>
<p>このコードが埋め込まれたページを 2010 年に見た場合、© 2001–2010 Example.com と出力されます。</p>
<p>これは 2001 年に公開されたサイトの例ですが、ではこれから新しく公開するサイトの場合はどうでしょうか。上記の書式をそのまま当てはめると、たとえば 2010 年に公開されたサイトを同じ年に見た場合、出力結果は © 2010–2010 というおかしなことになってしまいます。</p>
<p>そこで、2010 年の間は © 2010 と表示されて、2011 年になったところで © 2010–2011 と更新されるようにしてみます:</p>
<pre><code class="language-php">&#169; <?php
$then = 2010; // サイトの公開年
$now = date('Y');
if ($then < $now) {
echo $then.'–'.$now;
} else {
echo $then;
}
?> Example.com
</code></pre>
<p>サイトの公開年 (<code>$then</code>) と現在の年 (<code>$now</code>) を比較して出力を分岐させるわけです。もし WordPress なら、以下のように関数を <code>functions.php</code> に書いておいてもいいかもしれません:</p>
<pre><code class="language-php">function get_copyright_date ($then) {
$now = date('Y');
if ($then < $now) {
return $then.'–'.$now;
} else {
return $then;
}
}
</code></pre>
<p>WordPress テンプレート内で公開年を引数にして使います:</p>
<pre><code class="language-html">&#169; <?php echo get_copyright_date(2010); ?> Example.com
</code></pre>
<p>著作権表示自体の是非はさておき。</p>
百景
2011-01-02T00:00:00Z
https://terkel.jp/archives/2011/01/hyakkey/
<p><a href="http://www.hyakkey.com/">百景</a> という、テレビ・舞台の美術やマンションギャラリーなどの企画・設計・制作を手がけるデザイン会社の Web サイト作りをお手伝いしました。私がひとりでデザインから実装まですべて手がけたのは、自分の個人サイト以外でははじめてです。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/hyakkey.jpg" />
</figure>
<p>クライアントは設立して 1 年、従業員 5 名の会社で、今まで Web サイトを持っていませんでした。そのため、私が今までの仕事でおもに担当してきたフロントエンド部分だけでなく、クライアントとの打ち合わせをはじめ、ドメインやサーバの手配、情報設計、ライティングなど、Web サイト作りの過程をひととおり経験することができました。</p>
<p>Web デザインの現場では、まずヴィジュアル・デザインのモックアップ (カンプ) を Photoshop や Fireworks で作り、それをクライアントに見せてゴーサインをもらい、そしてフロントエンドの実装に入る、という流れが一般的です。ですが今回のプロジェクトでは、カンプを作ってクライアントに見せることはせず、実際に HTML と CSS と JavaScript で Web ページを作るところからはじめる、というアプローチを採りました。クライアントにはすべてをブラウザで確認してもらうわけです。そもそもデザインがシンプルだったからというのもあるかもしれませんが、ワークフローとしてうまくいったと思います。</p>
<p>デザイン面では、ロゴがすでにあったので、そのイメージを活かすよう、タイポグラフィを中心に据えてシンプルにまとめることを心がけました。一部には <a href="https://developers.google.com/fonts/docs/getting_started">Google Fonts API</a> を利用して Web フォントを埋め込んでいます。グローバルナビゲーションに <a href="https://fonts.google.com/specimen/Reenie+Beanie">Reenie Beanie</a>、見出しに <a href="https://fonts.google.com/specimen/Josefin+Sans">Josefin Sans</a> という、いずれも <a href="https://fonts.google.com/">Google Fonts</a> で提供されているフォントです。</p>
<p>マークアップは HTML5 です。<code>canvas</code> や <code>video</code> などの派手なフィーチャーはありませんが、HTML5 ならではの要素として、コンタクト情報に <a href="http://www.w3.org/TR/microdata/">Microdata</a> を組み込んでいます。</p>
<p>border-radius など CSS3 のフィーチャーもいくつか採用しています。クライアントに対しては、たとえば「IE だとここのボタンの角が丸くなりません」などいくつか具体例を挙げて説明し、環境によって見え方が異なるという点を理解していただきました。</p>
<p>というわけで、かなり好きなようにやらせていただいたサイトです。百景のみなさん、どうもありがとうございました。</p>
HTML5 のカスタムデータ属性を jQuery プラグインのオプションとして使う
2011-01-10T00:00:00Z
https://terkel.jp/archives/2011/01/html5-custom-data-attributes-as-jquery-plugin-options/
<p>HTML5 ではマークアップに <a href="http://www.w3.org/TR/html5/elements.html#embedding-custom-non-visible-data-with-the-data-attributes">カスタムデータ属性</a> を埋め込むことができますが、これを jQuery プラグインのオプションとして利用する方法について考えてみました。なお、ここでやっていることと同様のことが『<a href="http://www.amazon.co.jp/o/ASIN/4873114683/terkel-22" title="Amazon.co.jp: jQueryクックブック: jQuery Community Experts, 株式会社クイープ: 本">jQuery クックブック</a>』の「レシピ 12.7」に書かれていたので参考にしています。</p>
<p>まず、従来の典型的な jQuery プラグインでのオプションの扱い方は、オプションをオブジェクトとして定義し、そこに適切な適当なデフォルト値を与え、メソッド呼び出しの際に必要に応じて上書きする、というものです:</p>
<pre><code class="language-javascript">(function ($) {
$.fn.myPlugin = function (options) {
// デフォルトのオプションをメソッド呼び出し時の指定で上書き
var opts = $.extend({}, $.fn.myPlugin.defaults, options);
return this.each(function () {
// 関数の本体
});
};
// デフォルトのオプションを設定
$.fn.myPlugin.defaults = {
width: 160,
speed: 'fast',
repeat: true
};
$(function () {
// メソッドの呼び出し時にオプションのうち 1 つを上書き
$('.myClass').myPlugin({
width: 320
});
});
})(jQuery);
</code></pre>
<p><a href="http://api.jquery.com/jQuery.extend/"><code>$.extend()</code></a> を使って空のオブジェクト (<code>{}</code>) をデフォルトオプションのオブジェクト (<code>$.fn.myPlugin.defaults</code>) で上書き (拡張) し、さらにメソッドを呼び出す際に引数 (<code>options</code>) で上書きできるようにしています。こうすることで、メソッド呼び出し時に必要なオプションだけを指定してあとはデフォルトのまま、といったことが可能です。上記の例ではメソッド呼び出し時にオプション <code>width</code> を上書きしているので、関数の中で <code>opts.width</code> は <code>320</code> という値に書き替えられています。</p>
<p>こういったプラグインに HTML5 のカスタムデータ属性を絡めるにはどうするか。具体的には、メソッドに渡すオプションとして、デフォルトを継承しつつ、メソッド呼び出し時に指定でき、さらにマークアップのカスタムデータ属性で上書きできるようにするにはどうすればいいか。</p>
<p>例として、Twitter の API を使って複数のアカウントそれぞれの Tweet を数件ずつを出力するようなプラグインを考えてみます。それにはオプションとして Twitter のアカウント名や表示件数を指定できることが必要になりますが、アカウント名はマークアップにカスタムデータ属性として埋め込み、表示件数はメソッド呼び出し時に指定できるようにしてみます:</p>
<pre><code class="language-javascript">(function ($) {
$.fn.loadTweets = function (options) {
// デフォルトのオプションをメソッド呼び出し時のオプションで上書き *1
options = $.extend({}, $.fn.loadTweets.defaults, options);
return this.each(function () {
var $this = $(this);
// メソッドを呼び出す要素ごとにカスタムデータ属性の値を取得 *2
var customData = {
screen_name: $this.data('twitter-screen-name'),
count: $this.data('twitter-count'),
include_rts: $this.data('twitter-include-rts')
};
// *1 を *2 で上書き
var opts = $.extend({}, options, customData);
});
};
// デフォルトのオプションを設定
$.fn.loadTweets.defaults = {
count: 10,
include_rts: true
};
$(function () {
// クラス .tweets を持つ要素ごとに loadTweets() メソッドを呼び出し
$('.tweets').loadTweets({
count: 4
});
});
})(jQuery);
</code></pre>
<pre><code class="language-html"><!-- 各要素のカスタムデータ属性にオプションを指定 -->
<div class="tweets" data-twitter-screen-name="BarackObama"></div>
<div class="tweets" data-twitter-screen-name="DalaiLama"></div>
</code></pre>
<p>まずデフォルトのオプションをメソッド呼び出し時の引数に上書きし、さらに要素ごとにカスタムデータ属性の値で上書きしています。つまり同じオプション項目について、マークアップのカスタムデータ属性 → メソッド呼び出し時の引数 → デフォルト、という優先順位になるわけです。またメソッド呼び出し時の引数同様、カスタムデータ属性は必要な項目のみ指定することができます。</p>
<p>なお、上記のようにカスタムデータ属性の値を <a href="http://api.jquery.com/data/"><code>data()</code></a> メソッドで取得できるのは jQuery 1.4.3 以降です。それ以前のバージョンの場合は <code>$this.attr('data-twitter-screen-name')</code> などとする必要があります。</p>
Sass でもう一度 CSS を楽しく!
2011-03-07T00:00:00Z
https://terkel.jp/archives/2011/03/sass-makes-css-fun-again/
<p>僕もようやく <a href="http://sass-lang.com/">Sass</a> をはじめました。評判どおり、ヤバいです。CSS を書くすべての人に習得してほしいとすら思います。とくに、最近 CSS を書いていてもつまらなかったり、設計に行き詰まりを感じたりしている人は、迷わず Sass を試してみるべきです。Sass のサイトには “<strong>Sass makes CSS fun again</strong>”—「Sass でもう一度 CSS を楽しく」というフレーズが掲げられていますが、ハッタリではありません。</p>
<p>しかし、実際に Sass を導入するのは敷居が高いと感じる人も多いのではないかと思います。コマンドラインとかよくわからん、独自構文の学習コストが気になる、実際に仕事で使えるのか疑問…など。</p>
<p>そこでこの記事では、僕が Sass をはじめるにあたって感じていた不安などをもとに、「Sass は難しくないよ!」というアピールを試みます。少しでも Sass 導入の障壁を取り除く助けになればうれしいです。</p>
<h2>はじめに</h2>
<p>そもそも Sass とはなにか、Sass のどこがすごいのか、といったことを知るには以下のリソースが最適です。まずチェックしてみてください。必見・必読です:</p>
<ul>
<li><a href="http://www.ustream.tv/recorded/12128935">Ustream.tv: 小久保浩大郎「Sass徹底解説〜SassがもたらすCSSのパラダイムシフト」其の一</a></li>
<li><a href="http://www.ustream.tv/recorded/12129141">Ustream.tv: 小久保浩大郎「Sass徹底解説〜SassがもたらすCSSのパラダイムシフト」其のニ</a></li>
<li><a href="http://hail2u.net/documents/sass-and-sassy-css.html">Sass、そしてSassy CSS (SCSS)</a></li>
</ul>
<h2>インストール</h2>
<p>さて、いざ Sass を試してみようと思ってググってみたものの、多くの記事は「コマンドプロンプトを起動して…」とか「ターミナルに以下のコマンドを…」みたいなところからはじまっていて戸惑った人も多いのではないでしょうか。しかも「まず Ruby をインストールし…」とまるで馴染みのないプログラミング言語まで出てくる始末。多くの非プログラマにとって、コマンドラインを操作するあの「<strong>黒い画面</strong>」は馴染みがなく、とっつきにくいものだと思います。</p>
<p>しかし、「黒い画面」は Sass をインストールするときと作業に入るときにほんの少しのコマンドを打ち込むだけで、Sass のコード自体はいつもの使い慣れたエディタで編集できます。また Ruby はインストール時にちょっとだけ意識しなければいけませんが、以降はまったく気にする必要がないので、知識がなくても問題ありません。</p>
<p>まず、「黒い画面」がはじめてで怖いという人は是非この記事を読んでみてください。僕はこれで克服しました:</p>
<ul>
<li><a href="http://fjord.jp/love/548.html">Webデザイナーの為の「本当は怖くない」”黒い画面”入門 Part.01 | FJORD, LLC(合同会社フィヨルド)</a></li>
</ul>
<p>そして Windows/Mac へのインストールや編集の準備はすごく簡単です。手順は以下の記事がわかりやすいと思います:</p>
<ul>
<li><a href="http://www.hamashun.me/archives/1294573.html">hamashun.me : Windows PC に Ruby と Sass を導入する方法</a></li>
<li><a href="http://linker.in/journal/2010/10/sassdreamweavercss.php">SassとDreamweaverのコードヒントでCSSをさらに効率的に|linker journal|linker</a></li>
</ul>
<h2>構文</h2>
<p>「Sass は CSS を拡張するメタ言語」などと言われるとややこしそうな印象を受けますがそんなことはありません。Sass の記法である <strong>SCSS</strong> (Sassy CSS) 構文は CSS と互換性があります。そのため、たとえばすでに書いた <code>style.css</code> という CSS ファイルを <code>style.**scss**</code> と拡張子を変えるだけで Sass として機能します。つまり Sass の構文を覚えないと何もできないということはなく、書き慣れた CSS はそのままに、少しずつ「Sass 化」していくことができるのです。</p>
<p>それに、入れ子、変数、ミックスインといった Sass 構文のフィーチャーは、どれも CSS をひととおり習得しているなら直感的に理解できるもので、触っているうちにすぐに書けるようになると思います。</p>
<p>以下のリソースは公式のリファレンスです。いきなりすべてを使いこなすことは難しいしその必要もないですが、ざっと見渡しただけでも Sass がいかにパワフルか伝わると思います:</p>
<ul>
<li><a href="http://sass-lang.com/tutorial.html">Sass - Syntactically Awesome Stylesheets</a>
<ul>
<li>邦訳: <a href="http://hail2u.net/documents/sass-tutorial.html">Sass - チュートリアル</a></li>
</ul>
</li>
<li><a href="http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html">File: SASS_REFERENCE</a></li>
<li><a href="http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html">Module: Sass::Script::Functions</a></li>
</ul>
<h2>チームでの導入</h2>
<p>そして、Sass 導入における最大の難関は、チームで CSS を編集するプロジェクトに導入すること—つまり「会社で使えるかどうか」ではないでしょうか。</p>
<p>これはたしかに簡単ではないと思います。複数のメンバーが CSS を編集する可能性がある場合、その全員が Sass を学ぶ必要がありますが、メンバーのスキルやモチベーションには差があるでしょうし、導入や習得のための時間を割けないこともあるでしょう。</p>
<p>それでも導入を検討する価値は充分にあるし、そこにトライできる環境にいる人は是非ともそうしてみてほしいです。もちろんすべてのメンバーが同等の習熟度にある必要はありません。たとえばリーダーが基本のフレームワークを作り、ほかのメンバーが必要に応じてモジュールを追加する、というような運用も通常の CSS に比べてやりやすいです。</p>
<p>そして、もしチームに Sass を導入することができないとしても、ひとりひとりが Sass を習得することをあきらめてほしくない、と強く願います。なぜなら、Sass のもっとも素晴らしい点は、効率化や保守性の向上より、それを学ぶことによって CSS をより構造的に捉えられるようになることだと思うからです。Sass を習得すれば、「素」の CSS を書いたりマークアップしたりするときにも必ずプラスの影響があります。</p>
<h2>おわりに</h2>
<p>Web のフロントエンド技術を習得する最良の方法のひとつは、優れたサイトの「ソースを見る」ことです。しかし Sass は製作者のローカルで CSS を生成するものなので、ブラウザから Sass のソースを読むことができません。そこで Sass のテクニックを学ぶために製作者どうしで情報を共有したいところなのですが、Sass についての情報はまだまだ少なく、それはなかなか容易ではないというのが現状です。</p>
<p>ですから皆さん、是非、Sass を使ってみてください。そしてシブいミックスインを書いて公開してください!</p>
OOCSS の Spacing クラスのようなものを Sass で
2011-03-18T00:00:00Z
https://terkel.jp/archives/2011/03/oocss-spacing-classes-using-sass/
<p>「<a href="https://github.com/stubbornella/oocss/blob/master/core/spacing/space.css">OOCSS (Object Oriented CSS) の Spacing クラス</a> のようなもの」というのは、よくあるこういったやつです:</p>
<pre><code class="language-css">/*
p,m = padding,margin
a,t,r,b,l,h,v = all,top,right,bottom,left,horizontal,vertical
*/
.pt0, .pv0, .pa0 { padding-top: 0px !important; }
.pr0, .ph0, .pa0 { padding-right: 0px !important; }
.pb0, .pv0, .pa0 { padding-bottom: 0px !important; }
.pl0, .ph0, .pa0 { padding-left: 0px !important; }
.pt10, .pv10, .pa10 { padding-top: 10px !important; }
.pr10, .ph10, .pa10 { padding-right: 10px !important; }
.pb10, .pv10, .pa10 { padding-bottom: 10px !important; }
.pl10, .ph10, .pa10 { padding-left: 10px !important; }
.pt20, .pv20, .pa20 { padding-top: 20px !important; }
...
.mt0, .mv0, .ma0 { margin-top: 0px !important; }
.mr0, .mh0, .ma0 { margin-right: 0px !important; }
.mb0, .mv0, .ma0 { margin-bottom: 0px !important; }
.ml0, .mh0, .ma0 { margin-left: 0px !important; }
.mt10, .mv10, .ma10 { margin-top: 10px !important; }
.mr10, .mh10, .ma10 { margin-right: 10px !important; }
.mb10, .mv10, .ma10 { margin-bottom: 10px !important; }
.ml10, .mh10, .ma10 { margin-left: 10px !important; }
.mt20, .mv20, .ma20 { margin-top: 20px !important; }
...
</code></pre>
<p>こんなふうに上下左右の <code>padding</code> と <code>margin</code> を定義したクラスをあらかじめ用意しておき、必要に応じて HTML にクラスを付与して余白をコントロールしようというわけです。</p>
<p>これの扱いにくい点としては、用意したけど実際には使わない無駄なクラスが発生してしまうことや、新たなクラスを追加する際の編集が面倒なことなどが挙げられます。</p>
<p>で、この手法そのものの是非とかはとりあえず置いといて、<strong>Sass</strong> を使うとこういったコードを効率的に生成できますよ、という話。</p>
<pre><code class="language-scss">/* SCSS */
@mixin spacing($size) {
$type: 'p';
$prop: 'padding';
@for $i from 1 through 2 {
@if $i > 1 {
$type: 'm';
$prop: 'margin';
}
.#{$type}t#{$size} { #{$prop}-top: #{$size}px !important; }
.#{$type}r#{$size} { #{$prop}-right: #{$size}px !important; }
.#{$type}b#{$size} { #{$prop}-bottom: #{$size}px !important; }
.#{$type}l#{$size} { #{$prop}-left: #{$size}px !important; }
.#{$type}v#{$size},
.#{$type}a#{$size} {
@extend .#{$type}t#{$size};
@extend .#{$type}b#{$size};
}
.#{$type}h#{$size},
.#{$type}a#{$size} {
@extend .#{$type}r#{$size};
@extend .#{$type}l#{$size};
}
}
}
</code></pre>
<p>なんか無駄に仰々しい気もしますが、こんな感じのミックスインを定義しておいて、あとは必要な余白のサイズを引数にして <code>@include</code> します:</p>
<pre><code class="language-scss">/* SCSS */
@include spacing(0);
@include spacing(10);
@include spacing(20);
</code></pre>
<p>これをコンパイルすると以下の CSS が生成されます (改行やスペースは読みやすいようにいじってます):</p>
<pre><code class="language-css">/* CSS */
.pt0, .pv0, .pa0 { padding-top: 0px !important; }
.pr0, .ph0, .pa0 { padding-right: 0px !important; }
.pb0, .pv0, .pa0 { padding-bottom: 0px !important; }
.pl0, .ph0, .pa0 { padding-left: 0px !important; }
.mt0, .mv0, .ma0 { margin-top: 0px !important; }
.mr0, .mh0, .ma0 { margin-right: 0px !important; }
.mb0, .mv0, .ma0 { margin-bottom: 0px !important; }
.ml0, .mh0, .ma0 { margin-left: 0px !important; }
.pt10, .pv10, .pa10 { padding-top: 10px !important; }
.pr10, .ph10, .pa10 { padding-right: 10px !important; }
.pb10, .pv10, .pa10 { padding-bottom: 10px !important; }
.pl10, .ph10, .pa10 { padding-left: 10px !important; }
.mt10, .mv10, .ma10 { margin-top: 10px !important; }
.mr10, .mh10, .ma10 { margin-right: 10px !important; }
.mb10, .mv10, .ma10 { margin-bottom: 10px !important; }
.ml10, .mh10, .ma10 { margin-left: 10px !important; }
.pt20, .pv20, .pa20 { padding-top: 20px !important; }
.pr20, .ph20, .pa20 { padding-right: 20px !important; }
.pb20, .pv20, .pa20 { padding-bottom: 20px !important; }
.pl20, .ph20, .pa20 { padding-left: 20px !important; }
.mt20, .mv20, .ma20 { margin-top: 20px !important; }
.mr20, .mh20, .ma20 { margin-right: 20px !important; }
.mb20, .mv20, .ma20 { margin-bottom: 20px !important; }
.ml20, .mh20, .ma20 { margin-left: 20px !important; }
</code></pre>
<p>たとえばもし 25px のがあとから必要になったら、<code>@include spacing(25);</code> と 1 行加えるだけ。これならあらかじめ大量のクラスを用意せずに必要なクラスだけを作るのが容易だし、無駄を少なく抑えられます。プロジェクト間で使い回すにもミックスインだけを持っていけばいいので楽。</p>
<p>あと、この手の CSS にはある種の後ろめたさのようなものがつきまとうものですが、それが Sass によって少しは軽減されるというか…</p>
Sass の @import ルール
2011-03-28T00:00:00Z
https://terkel.jp/archives/2011/03/sass-at-import-rule/
<p><a href="http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#import">Sass の <code>@import</code> ルール</a> は CSS ファイルだけではなく Sass ファイルもインポートできる。この機能は地味に見えるが、実際に使ってみるとものすごく便利。とくに、ミックスインをモジュールとしてファイルに分割しておき、必要に応じて呼び出すような場面でその便利さを痛感する。</p>
<p>例として、<code>opacity</code> プロパティのクロスブラウザ対応コードのミックスインを考えてみる。まず以下のようなコード片を <code>_opacity.scss</code> というファイル名で用意しておく:</p>
<pre><code class="language-scss">// _opacity.scss
@mixin opacity($alphavalue) {
opacity: $alphavalue;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=#{ $alphavalue * 100 })"; // for IE 8
filter: alpha(opacity=#{ $alphavalue * 100 }); // for IE 5-7
}
</code></pre>
<p>こういったモジュールとしてインポートして使う Sass ファイルは、それ単独で CSS にコンパイルする必要がない。そんなときはファイル名の先頭に <strong><code>_</code></strong> (アンダースコア) をつけておく。そうすると、ディレクトリごと <code>--watch</code> していてもそのファイルは単独ではコンパイルされない。</p>
<p>で、このファイルをメインの Sass ファイルからインポートすれば、<code>opacity</code> ミックスインを利用できる。なおその際、ファイルの拡張子と先頭のアンダースコアは省略可能:</p>
<pre><code class="language-scss">// style.scss
@import "opacity"; // _opacity.scss をインポート
.opaque {
@include opacity(0.8); // opacity ミックスインを参照
}
</code></pre>
<p>最後にこのメインの Sass ファイルをコンパイルすれば以下のような CSS が出来上がる:</p>
<pre><code class="language-css">/* style.css */
.opaque {
opacity: 0.8;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
filter: alpha(opacity=80);
}
</code></pre>
<p>ちなみに、ひとつの <code>@import</code> ルールで複数の Sass ファイルをいっぺんにインポートすることもできる:</p>
<pre><code class="language-scss">@import "reset", "fonts", "css3/border-radius";
</code></pre>
<p>どれだけ細かくファイルを分割しても最終的に 1 枚の CSS ファイルにコンパイルできるので、CSS の <code>@import</code> ルールとは違って HTTP リクエストの増大を気にする必要はない。</p>
<p>また、CSS の <code>@import</code> ルールは <code>@charset</code> ルールをのぞくすべてのルールに先行していなければならないが、Sass の <code>@import</code> は場所を選ばない。たとえば、CSS の末尾に記述されることの多い印刷用スタイルやモバイル用スタイルなどを別ファイルとして用意して Sass の最後にインポートする、といったことも容易だ。</p>
<p>このように、Sass は CSS の <code>@import</code> ルールが抱える問題の多くを解決し、スタイルシートのより柔軟な設計・開発・管理をサポートしてくれる。</p>
Firefox 4 のデフォルト CSS
2011-04-12T00:00:00Z
https://terkel.jp/archives/2011/04/firefox-4-default-css/
<p>Firefox 4 のデフォルト CSS は、以下のような URL をロケーションバーに入力すればブラウザから確認できる (ちなみに 3.6 とはパスが異なる):</p>
<ul>
<li><code>resource://gre-resources/html.css</code></li>
<li><code>resource://gre-resources/forms.css</code></li>
<li><code>resource://gre-resources/quirk.css</code></li>
</ul>
<p><code>resource://gre-resources/</code> を見るとほかにもいろいろある。内容は全部は見てないけど、HTML5 の新要素に対する指定や <code>:-moz-any()</code> セレクタやなんかが追加されてて、3.6 からけっこう変わってた。</p>
要素をスクロールに追従させる jQuery プラグイン
2011-05-22T00:00:00Z
https://terkel.jp/archives/2011/05/jquery-floating-widget-plugin/
<p><a href="http://store.apple.com/jp/configure/MC769J/A">Apple Store</a> のサイドバーのように、要素をウィンドウのスクロールに追従させる jQuery プラグイン、<a href="https://github.com/terkel/jquery-floating-widget">jQuery Floating Widget</a> を作りました。説明が難しいので、まずはデモをご覧ください!</p>
<ul>
<li><a href="https://terkel.jp/demo/jquery-floating-widget-plugin.html">jQuery Floating Widget plugin demo</a></li>
</ul>
<p>このアイデア自体は新しいものではなくて、たとえば以下の記事で詳しく紹介されています:</p>
<ul>
<li><a href="http://jqueryfordesigners.com/fixed-floating-elements/">Fixed Floating Elements | jQuery for Designers - Tutorials and screencasts</a></li>
</ul>
<p>この方法で基本的にうまくいくんですが、フッターの高さがある程度あると、下までスクロールしたときに該当要素がフッター領域に食い込んでしまう場合があります。そこで、上記記事での実装を参考に、要素の「動ける範囲」を制限するための処理などを加えたものを考えてみました。</p>
<p>例として、フロートによる 2 カラムのレイアウトで、サイドバーをスクロールに追従させる場合をもとに解説します。マークアップと基本的なスタイルは以下のとおりです:</p>
<pre><code class="language-html"><div class="header"> . . . </div>
<div class="content-wrapper">
<div class="content"> . . . </div>
<div class="sidebar">
<div class="floating-widget">
<!-- この要素がスクロールについてきます -->
</div>
</div>
</div>
<div class="footer"> . . . </div>
</code></pre>
<pre><code class="language-css">.content-wrapper {
position: relative;
*zoom: 1;
}
.content-wrapper:after {
display: block;
clear: both;
height: 0.01px;
content: "";
}
.content {
float: left;
width: 512px;
}
.sidebar {
float: right;
width: 256px;
}
.floating-widget {
margin: 50px 0;
}
</code></pre>
<p>該当要素の動ける範囲を制限する祖先要素 (<code>div.content-wrapper</code>) には、スクロールが下まで来たときに該当要素を絶対配置するための <code>position: relative;</code> と、高さを取得するための clearfix が必要です。</p>
<p>プラグイン本体とその呼び出し方は以下のとおりです:</p>
<pre><code class="language-javascript">// プラグイン
(function ($) {
$.fn.floatingWidget = function () {
return this.each(function () {
var $this = $(this),
$parent = $this.offsetParent(),
$window = $(window),
top = $this.offset().top - parseFloat($this.css('marginTop').replace(/auto/, 0)),
bottom = $parent.offset().top + $parent.height() - $this.outerHeight(true),
floatingClass = 'floating',
pinnedBottomClass = 'pinned-bottom';
if ($parent.height() > $this.outerHeight(true)) {
$window.scroll(function () {
var y = $window.scrollTop();
if (y > top) {
$this.addClass(floatingClass);
if (y > bottom) {
$this.removeClass(floatingClass).addClass(pinnedBottomClass);
} else {
$this.removeClass(pinnedBottomClass);
}
} else {
$this.removeClass(floatingClass);
}
});
}
});
};
})(jQuery);
</code></pre>
<pre><code class="language-javascript">// 呼び出し
$(function () {
$('.floating-widget').floatingWidget();
});
</code></pre>
<p>ウィンドウのスクロール位置を見て、要素がスクロールに追従している状態 (<code>.floating</code>) と祖先要素の下端にとどまっている状態 (<code>.pinned-bottom</code>) というそれぞれの状態に応じてマークアップのクラスを書き換えています。また最初に該当要素と祖先要素の高さを比較し、サイドバーの高さがコンテンツを超えるような場合はなにも起こりません。</p>
<p>ちなみに jQuery の <a href="http://api.jquery.com/offsetParent/"><code>offsetParent()</code></a> は <code>position</code> プロパティが <code>static</code> 以外である直近の祖先要素を返すメソッドです。また <a href="http://api.jquery.com/outerHeight/"><code>outerHeight()</code></a> メソッドはパディングとボーダーを含む要素の高さを返しますが、引数に <code>true</code> を渡すとさらにマージンも含めた高さを返します。</p>
<p>最後に、<code>.floating</code> と <code>.pinned-bottom</code> というクラスに対してスタイルを追加します:</p>
<pre><code class="language-css">.floating-widget.floating {
position: fixed;
top: 0;
}
.floating-widget.pinned-bottom {
position: absolute;
bottom: 0;
_position: static;
}
</code></pre>
<p>スクロールのたびにスクリプトでスタイルを書き換える方法もありますが、それだと動きがカクカクしがちなので、JavaScript の仕事は位置によってマークアップのクラスを変更するだけにして、配置は CSS にまかせるというアプローチを採りました。</p>
<p><code>position: fixed;</code> を解釈しない IE6 ではスクロールに追従しませんが、下まで来ると <code>position: absolute;</code> が適用されて要素が突然移動してしまうので、ハックで <code>static</code> を上書きしています。</p>
<p>ソースコードは以下からどうぞ。恥ずかしながら GitHub デビューしました!</p>
<ul>
<li><a href="https://github.com/terkel/jquery-floating-widget">terkel/jquery-floating-widget - GitHub</a></li>
</ul>
jQuery Last.fm Profile Plugin
2011-07-10T00:00:00Z
https://terkel.jp/archives/2011/07/jquery-lastfm-profile-plugin/
<p><a href="http://www.last.fm/api">Last.fm の API</a> を利用して、ユーザのプロファイルから最近聴いた曲やもっとも再生回数の多いアルバムやなんかを取得して表示する jQuery プラグイン。自分のサイト用に書いて使ってたんだけど、一部を書き直したり機能を追加したりして <a href="https://github.com/terkel/jquery-lastfm-profile">GitHub に公開してみました</a>。まずはデモをどうぞ:</p>
<ul>
<li><a href="https://terkel.jp/demo/jquery-lastfm-profile-plugin.html">Demo: jQuery Last.fm Profile Plugin</a></li>
</ul>
<p>使い方。まず jQuery と一緒にプラグインをインクルードしてください。jQuery のバージョンは 1.4.3 以降である必要があります:</p>
<pre><code class="language-html"><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="/path/to/jquery.lastfm-profile.js"></script>
</code></pre>
<p>データを表示させたい箇所には以下のように適当な要素を置いてください:</p>
<pre><code class="language-html"><div id="my-favourite-artists"></div>
</code></pre>
<p>そして <code>loadLastfmProfile()</code> メソッドを呼び出します:</p>
<pre><code class="language-javascript">$(function () {
$('#my-favourite-artists').loadLastfmProfile({
user: 'terkeljp',
method: 'TopArtists',
period: 'overall'
});
});
</code></pre>
<p>オプションはスクリプト呼び出し時に指定するだけではなく、HTML5 のカスタムデータ属性としてマークアップに仕込むこともできます:</p>
<pre><code class="language-html"><div id="my-favourite-artists"
data-lastfm-user="terkeljp"
data-lastfm-method="TopArtists"
data-lastfm-period="overall"></div>
</code></pre>
<p>指定できるオプションは以下のとおりです:</p>
<dl>
<dt><code>user</code> (<code>data-lastfm-user</code>)</dt>
<dd>データを取得する Last.fm ユーザ名。初期値は <code>'LAST.HQ'</code></dd>
<dt><code>method</code> (<code>data-lastfm-method</code>)</dt>
<dd>取得するデータの種類。<code>'TopArtists'</code> (再生回数の多いアーティスト)、<code>'TopAlbums'</code> (再生回数の多いアルバム)、<code>'TopTracks'</code> (再生回数の多い楽曲)、<code>'RecentTracks'</code> (最近再生した楽曲)、<code>'NowPlaying'</code> (現在再生中の楽曲) のうちいずれかを指定。初期値は <code>'TopAlbums'</code></dd>
<dt><code>period</code> (<code>data-lastfm-period</code>)</dt>
<dd>取得するデータの集計期間。<code>'7day'</code>、<code>'3month'</code>、<code>'6month'</code>、<code>'12month'</code>、<code>'overall'</code> のうちいずれかを指定。初期値は <code>'7day'</code></dd>
<dt><code>limit</code> (<code>data-lastfm-limit</code>)</dt>
<dd>取得するデータの件数。初期値は <code>10</code></dd>
<dt><code>image</code> (<code>data-lastfm-image</code>)</dt>
<dd>各アイテムの画像を表示するかどうか。初期値は <code>true</code></dd>
<dt><code>imageSize</code> (<code>data-lastfm-image-size</code>)</dt>
<dd>各アイテムの取得する画像のサイズ。<code>'small'</code> (幅 34px)、<code>'medium'</code> (幅 64px)、<code>'large'</code> (幅 126px) のうちいずれかを指定。初期値は <code>'medium'</code></dd>
<dt><code>imageSquare</code> (<code>data-lastfm-image-square</code>)</dt>
<dd>各アイテムの画像を正方形で取得したい場合は <code>true</code> を指定。初期値は <code>true</code></dd>
<dt><code>text</code> (<code>data-lastfm-text</code>)</dt>
<dd>各アイテムのタイトルやアーティスト名をテキストで表示するかどうか。<code>false</code> を指定すると画像の <code>alt</code> 属性とリンクの <code>title</code> 属性に同内容の値が入る。初期値は <code>true</code></dd>
<dt><code>playcount</code> (<code>data-lastfm-playcount</code>)</dt>
<dd>再生回数を表示するかどうか。初期値は <code>true</code></dd>
<dt><code>loadingMessage</code> (<code>data-lastfm-loading-message</code>)</dt>
<dd>データの取得が完了するまでの間に表示される内容を指定。初期値は <code>'Loading&#8230;'</code></dd>
<dt><code>errorMessage</code> (<code>data-lastfm-error-message</code>)</dt>
<dd>データの取得に失敗した場合に表示される内容を指定。初期値は <code>'Failed to load data.'</code></dd>
<dt><code>contentBefore</code> (<code>data-lastfm-content-before</code>)</dt>
<dd>アイテムのリストの前に挿入する内容。初期値は <code>''</code> (何も挿入されない)</dd>
<dt><code>contentAfter</code> (<code>data-lastfm-content-after</code>)</dt>
<dd>アイテムのリストの後ろに挿入する内容。初期値は <code>''</code> (何も挿入されない)</dd>
</dl>
<p>プラグインのデータは以下でダウンロードできます:</p>
<ul>
<li><a href="https://github.com/terkel/jquery-lastfm-profile">terkel/jquery-lastfm-profile - GitHub</a></li>
</ul>
<p>Last.fm というと最近はあまり話題にのぼることが少ない気がしますが、サイトを利用してる人は淡々とログを蓄積し続けている、みたいな印象ですかね。API はいろんなデータがいじれてけっこう楽しいですよ。</p>
フォント変えた
2011-08-08T00:00:00Z
https://terkel.jp/archives/2011/08/changed-font-family/
<p>このサイトの基本のフォントファミリーを変えてみた。</p>
<pre><code class="language-css">/* 変更前 */
body {
font-family: "Helvetica Neue",
"Helvetica",
"Arial",
"Hiragino Kaku Gothic Pro",
"ヒラギノ角ゴ Pro W3",
"メイリオ",
sans-serif;
}
/* 変更後 */
body {
font-family: "Lucida Grande",
"Hiragino Kaku Gothic Pro",
"ヒラギノ角ゴ Pro W3",
"メイリオ",
"Helvetica",
"Verdana",
sans-serif;
}
</code></pre>
<p>ざっくり言うと、Helvetica から Lucida Grande へ、Arial からメイリオ/Verdana への変更。本文で和文と欧文が混ざってるときに、欧文部分が Helvetica/Arial だとやや詰まり気味に感じられるのが気になりだし、だったらいっそ OS のシステムフォントに合わせるような方向で、と考えてこうなった。</p>
<p>このへんは千差万別のフォント環境を考えはじめるとキリがないので、「Windows XP でヒラギノがインストールされてる場合」よりも「Mac でメイリオがインストールされてる場合」を重視、ぐらいのゆるいアプローチです。</p>
Microdata + schema.org を実際に使ってみる
2011-08-30T00:00:00Z
https://terkel.jp/archives/2011/08/microdata-and-schema-org/
<p><a href="http://schema.org/">schema.org</a> は Google、Microsoft (Bing)、Yahoo! という Web 検索の大手 3 社が共同で取り組んでいる試みで、より構造化されたマークアップのための共有の語彙集 (vocabulary) を提供しようというものです。この schema.org の語彙を利用して、実際のマークアップに <a href="http://dev.w3.org/html5/md/">Microdata</a> を追加する具体例をいくつか考えてみました。</p>
<p>schema.org の <strong>アイテム型</strong> (item type) は <a href="http://schema.org/docs/full.html">階層</a> (hierarchy) のかたちで定義されています。型ごとに独自の <strong>プロパティ</strong> が定義され、上位の型のプロパティは下位の型に引き継がれます。最上位は <a href="http://schema.org/Thing">Thing</a> という汎用の型で、<code>name</code>、<code>url</code>、<code>image</code>、<code>description</code> というもっとも基本的なプロパティが定義されています。そしてその下に <a href="http://schema.org/CreativeWork">CreativeWork</a>、<a href="http://schema.org/Event">Event</a>、<a href="http://schema.org/Intangible">Intangible</a>、<a href="http://schema.org/Organization">Organization</a>、<a href="http://schema.org/Person">Person</a>、<a href="http://schema.org/Place">Place</a>、<a href="http://schema.org/Product">Product</a>、といった型があり、そこからそれぞれさらに詳細な型に分岐しています。schema.org を利用するには、まずこの <a href="http://schema.org/docs/full.html">型階層のツリー図</a> からアイテムにふさわしい型を見つけます。</p>
<h2>例 #1: 企業情報</h2>
<p>最初に、いわゆる企業サイトであればほぼ必ず用意される、社名、住所、電話番号などを記した「企業情報」のコンテンツを考えてみます。サンプルとして <a href="http://www.google.co.jp/intl/ja/about/corporate/company/address.html">Google の会社情報</a> のマークアップを使わせてもらいました (一部記述を省略しています):</p>
<pre><code class="language-html"><div>
<b>グーグル株式会社</b><br>
〒106-6126<br>
東京都港区六本木 6 丁目 10 番 1 号<br>
六本木ヒルズ森タワー 私書箱 22 号<br>
TEL: 03-6384-9000<br>
FAX: 03-6384-9001
</div>
</code></pre>
<p>企業情報で使えそうな型を schema.org で探すと、<a href="http://schema.org/Organization">Organization 型</a> の派生である <a href="http://schema.org/Corporation">Corporation 型</a> がよさそうです。これをマークアップに組み込んでみます:</p>
<pre><code class="language-html"><div itemscope itemtype="http://schema.org/Corporation">
<b itemprop="name">グーグル株式会社</b><br>
<span itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
〒<span itemprop="postalCode">106-6126</span><br>
<span itemprop="addressRegion">東京都</span>
<span itemprop="addressLocality">港区</span>
<span itemprop="streetAddress">六本木 6 丁目 10 番 1 号<br>
六本木ヒルズ森タワー</span>
私書箱 <span itemprop="postOfficeBoxNumber">22</span> 号
</span><br>
TEL: <span itemprop="telephone">03-6384-9000</span><br>
FAX: <span itemprop="faxNumber">03-6384-9001</span>
</div>
</code></pre>
<p>まず <code>itemscope</code> 属性でアイテムを定義し、同要素の <code>itemtype</code> 属性で schema.org の URL を指定してアイテムの型とします。そしてデータとして表現したい項目ごとに <code>itemprop</code> 属性を持つ要素でマークアップしてプロパティとします。</p>
<p><code>name</code>、<code>telephone</code>、<code>faxNumber</code> の各プロパティはそれぞれ要素の内容がそのまま値になっており、とくに難しいことはないと思います。少しややこしいのが <code>address</code> プロパティで、<code>itemprop</code> 属性を持った要素が同時に <code>itemscope</code> 属性を持っており、アイテムが入れ子になっています。</p>
<p>住所を表現する <a href="http://schema.org/PostalAddress">PostalAddress 型</a> の各プロパティを日本の住所表記に当てはめるのにやや迷うところですが、だいたいこんな感じになると思います:</p>
<dl>
<dt><code>addressCountry</code></dt>
<dd>国</dd>
<dt><code>postalCode</code></dt>
<dd>郵便番号</dd>
<dt><code>addressRegion</code></dt>
<dd>都道府県</dd>
<dt><code>addressLocality</code></dt>
<dd>市区町村</dd>
<dt><code>streetAddress</code></dt>
<dd>市区町村以降 (町・字・地番・住居表示・方書)</dd>
<dt><code>postOfficeBoxNumber</code></dt>
<dd>私書箱番号</dd>
</dl>
<p>そのほか、企業情報で使う機会の多そうなプロパティとしては、<code>description</code>、<code>url</code>、<code>email</code>、<code>foundingDate</code> といったところでしょうか。</p>
<h2>例 #2: ブログ記事</h2>
<p>ブログの個別記事のための型として <a href="http://schema.org/BlogPosting">BlogPosting 型</a> が用意されています:</p>
<pre><code class="language-html"><article itemscope itemtype="http://schema.org/BlogPosting" itemref="copyright">
<header>
<time pubdate datetime="2011-08-30" itemprop="datePublished">
August 30, 2011
</time>
<h1 itemprop="name">
<a href="/blog/microdata-schema-org.html" itemprop="url">
Microdata + schema.org
</a>
</h1>
<p>
Tag(s):
<span itemprop="keywords">
<a href="/tag/markup">markup</a>,
<a href="/tag/semanticweb">semanticweb</a>
</span>
</p>
</header>
<div itemprop="articleBody">
<!-- content goes here -->
</div>
</article>
...
<footer>
<p id="copyright">
&#169; 2008–2011
<span itemprop="author" itemscope itemtype="http://schema.org/Person">
<a href="/about/" rel="author" itemprop="url">
<b itemprop="name">Takeru Suzuki</b>
</a>
</span>,
licensed under a <a href="http://creativecommons.org/licenses/by/2.1/jp/" rel="license">Creative Commons Attribution 2.1 Japan</a>.
</p>
</footer>
</code></pre>
<p>アイテム (<code>article</code> 要素) の <code>itemref</code> 属性に注目してください。<code>itemref</code> 属性でドキュメント内の ID を指定した場合、その要素をアイテムのデータとして追加することができます。この場合、アイテム内にはない著者情報 (<code>itemprop="author"</code>) をスコープ外の要素 (<code>#copyright</code>) から取得しています。このように <code>itemref</code> 属性によってマークアップ構造に縛られない柔軟なデータ表現が可能で、たとえば複数のアイテムから同一のプロパティを参照するような場合などに便利です。</p>
<p>また、<code>itemprop</code> が指定された要素のほとんどはその内容 (<code>textContent</code>) がプロパティの値になりますが、一部の要素は異なる点にも注意が必要です (<a href="http://dev.w3.org/html5/md/#values">HTML Microdata - 2.4 Values</a>)。この例では、<code>a</code> 要素は <code>href</code> 属性、<code>time</code> 要素は <code>datetime</code> がそれぞれのプロパティの値となります。</p>
<h2>参考</h2>
<p>最後に、Microdata と schema.org を知る上で参考になるリソースをいくつか挙げておきます:</p>
<ul>
<li><a href="http://www.w3.org/TR/microdata/">HTML Microdata (W3C Working Draft)</a></li>
<li><a href="http://www.slideshare.net/myakura/microdata-a-primer">Microdata: A Primer</a>: 日本語のスライド。Microdata の基本がわかりやすく解説されています</li>
<li><a href="http://diveintohtml5.org/extensibility.html">Microdata - Dive Into HTML5</a>: 『<a href="http://www.amazon.co.jp/o/ASIN/4873114829/terkel-22">入門 HTML5</a>』のオリジナルテキスト。マークアップの具体例がわかりやすいです</li>
<li><a href="http://html5doctor.com/microdata/">Extending HTML5 — Microdata | HTML5 Doctor</a>: マークアップ例、schema.org も含む様々な語彙集やツールの紹介、関連リソースのリンク集、とたいへん充実した記事</li>
<li><a href="http://www.google.com/support/webmasters/bin/answer.py?answer=176035">microdata について - ウェブマスター ツール ヘルプ</a></li>
<li><a href="http://www.google.com/webmasters/tools/richsnippets">Webmaster Tools - Rich Snippets Testing Tool</a>: Google のテストツール</li>
<li><a href="http://foolip.org/microdatajs/live/">Live Microdata</a>: テストツール。JSON 形式でデータが見られます</li>
</ul>
<ul>
<li><a href="http://schema.org/">schema.org - Home</a></li>
<li><a href="http://googlewebmastercentral-ja.blogspot.com/2011/08/schemaorg.html">Google ウェブマスター向け公式ブログ: schema.org のご紹介: より便利なインターネットのための検索エンジンの取り組み</a></li>
<li><a href="http://www.google.com/support/webmasters/bin/answer.py?answer=1211158">schema.org FAQ - ウェブマスター ツール ヘルプ</a></li>
<li><a href="http://www.bing.com/community/site_blogs/b/search/archive/2011/06/02/bing-google-and-yahoo-unite-to-build-the-web-of-objects.aspx">Bing Introducing Schema.org: Bing, Google and Yahoo Unite to Build the Web of Objects - Search Blog - Site Blogs - Bing Community</a></li>
<li><a href="http://developer.yahoo.com/blogs/ydn/posts/2011/06/introducing-schema-org-a-collaboration-on-structured-data/">Introducing schema.org: A Collaboration on Structured Data · YDN Blog</a></li>
</ul>
Google Chrome Frame: サイト管理者向けガイド
2011-08-31T00:00:00Z
https://terkel.jp/archives/2011/08/google-chrome-frame-webmasters-guide/
<p role="note"><small>2013-06-30更新: 2013 年 6 月、<a href="http://blog.chromium.org/2013/06/retiring-chrome-frame.html">Googe Chrome Frame の開発終了</a> が発表されたのを受け、<a href="https://terkel.jp/archives/2013/06/rip-google-chrome-frame/">新しい記事</a> を書きました。</small></p>
<hr />
<p>IE で Google Chrome と同等のレンダリングを実現するプラグイン、<a href="http://www.google.com/chromeframe">Google Chrome Frame</a> が <a href="http://blog.chromium.org/2011/08/non-admin-chrome-frame-reaches-stable.html">正式版になりました</a>。ユーザはよりリッチで快適な Web 体験ができるし、サイト管理者としても事実上古い IE のシェアが減ることになって嬉しい、しかもインストールに管理者権限が不要という、ちょっといいプラグインなんですよね Chrome Frame。</p>
<p>とは言えユーザがインストールして使ってくれないことにははじまらないので、この Chrome Frame の利用を促進するためにサイト管理者にできることを紹介します。</p>
<h2>ページを Chrome Frame でレンダリングさせる</h2>
<p>まず、すでに Chrome Frame がインストールされている場合にページを Chrome Frame でレンダリングさせる方法です。HTML の <code>head</code> 要素内に以下の記述を加えます:</p>
<pre><code class="language-html"><meta http-equiv="X-UA-Compatible" content="chrome=1">
</code></pre>
<p>もし IE の <a href="http://msdn.microsoft.com/ja-jp/library/cc817574.aspx">meta スイッチ</a> を指定している場合、まとめて以下のように書きます:</p>
<pre><code class="language-html"><meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
</code></pre>
<p>これで、もし Chrome Frame がインストールされていれば、そのページは Chrome Frame でレンダリングされます。</p>
<h2>Chrome Frame のインストールを促す</h2>
<p>次に、まだ Chrome Frame をインストールしていないユーザにインストールを促す方法です。それには Google から提供されている <a href="http://www.chromium.org/developers/how-tos/chrome-frame-getting-started#TOC-Detecting-Google-Chrome-Frame-and-P"><code>CFInstall.js</code></a> というスクリプトを利用します:</p>
<pre><code class="language-html"><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"></script>
<script type="text/javascript">
window.attachEvent('onload', function () {
CFInstall.check({
mode: 'overlay'
});
});
</script>
</code></pre>
<p>このコードをページの <code>body</code> 要素内に記述します。その際 IE の <a href="http://msdn.microsoft.com/ja-jp/library/ms537512.aspx">条件コメント</a> を利用して、IE 以外のブラウザでロードされないようにしましょう。この例では IE8 未満を対象にしていますが、プロジェクトの要件によって検討してください。ついでにホワイトスペースや改行も削除してみます:</p>
<pre><code class="language-html"><body>
...
<!--[if lt IE 8 ]>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"></script>
<script type="text/javascript">window.attachEvent('onload',function(){CFInstall.check({mode:'overlay'});});</script>
<![endif]-->
</body>
</code></pre>
<p>スクリプトはロードされると Chrome Frame がインストールされているかどうかを判別し、もしされていなければインストールを促すダイアログを表示します。ユーザがインストールせずにダイアログを閉じた場合、以降は cookie によって同一ドメインでは表示されません (cookie の有効期限は 1 年間に設定されているようです)。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/google-chrome-frame.png" />
</figure>
<p>表示方法は <code>mode</code> オプションで指定できるようですが、この <code>'overlay'</code> という値が推奨されています。ここでは最低限のオプションしか指定していませんが、そのほかの仕様については <a href="http://www.chromium.org/developers/how-tos/chrome-frame-getting-started">ドキュメンテーション</a> を参照してください。</p>
<p>ちなみに <a href="http://html5boilerplate.com/">HTML5 Boilerplate</a> もバージョン 2.0 でこのスクリプトを採用していますね。</p>
<p>以上、IE に呪いの言葉を浴びせるのもいいけどそれ以外にもできることがあるかもよ、という話でした。</p>
CSS ルールセット構造図
2011-09-24T00:00:00Z
https://terkel.jp/archives/2011/09/css-rule-structure/
<p>ごく基本的なことなんだけど、すぐに忘れてごっちゃになるので図を描いた。せっかくなので上げとく。詳しくは <a href="http://www.w3.org/TR/css3-syntax/">CSS3 module: Syntax</a> や <a href="http://d.hatena.ne.jp/amachang/20080407/1207569883">CSS の名前の整理 - IT戦記</a> などを参照のこと。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/css-rule-structure.png" />
</figure>
WordCamp Tokyo 2011 をデザイン
2011-11-08T00:00:00Z
https://terkel.jp/archives/2011/11/designing-wordcamp-tokyo-2011/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/wctokyo2011-logo.png" />
</figure>
<p>今年 11 月 27 日に開催される WordPress のイベント、<a href="http://2011.tokyo.wordcamp.org/">WordCamp Tokyo 2011</a> にデザイナーとして参加し、ロゴやサイト、<a href="http://2011.tokyo.wordcamp.org/banner/">バナー</a> などをデザインしました。</p>
<p>僕はふだんの仕事ではフロントエンドエンジニアとして HTML、CSS、JavaScript を書いていることがほとんどで、ロゴなどのグラフィックデザインまで手がけることはめずらしいです。勢いで T シャツやステッカーまで作ってしまいました。</p>
<p>デザインのコンセプトなどについては同サイトに <a href="http://2011.tokyo.wordcamp.org/2011/10/23/designing-wordcamp-tokyo-2011/">記事を書きました</a>。おそらく WordCamp 史上もっとも地味なデザインではないかと思うんですが、僕の考える WordPress らしさを表現したつもりです。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/wctokyo2011-screen.png" />
</figure>
<p>もちろんイベント当日は僕も会場にいます。みなさんぜひ遊びに来てください!</p>
WordCamp と俺
2011-11-22T00:00:00Z
https://terkel.jp/archives/2011/11/wordcamp-and-me/
<p>いよいよこんどの日曜日に開催がせまった <a href="http://2011.tokyo.wordcamp.org/">WordCamp Tokyo 2011</a>。俺もデザイナーとして運営に参加しているわけですが、その運営スタッフがおのおののブログに日替わりで WordCamp についての記事を書く <a href="http://2011.tokyo.wordcamp.org/relay-blog/">リレーブログ</a> なる企画があり、このたび <a href="http://experiment.street-square.com/2011/11/21/wordcamp-tokyo-photo/">真木さんからのバトン</a> を受けて、いよいよ俺に順番がまわってきました。</p>
<p>何を書こうか少し悩みましたが、とくにこれといったネタもないので、俺と WordCamp の関係や、俺が WordCamp について思うところなどをだらだらと書いてみます。ちなみにこのブログでは Web デザインについて淡々と書くことがほとんどなので、こういったスタイルの記事はめずらしいです、すごく。</p>
<p>さて、俺がはじめて WordCamp に参加したのは 2010 年春の <a href="http://yokohama2010.wordcamp.jp/">WordCamp Yokohama 2010</a> でした。俺は基本的にこういったセミナー的なイベントにあまり積極的に参加しないし、それまで WordPress についてさほど勉強してたわけでもないのですが、当時仕事してなくて時間もあったし、タダだし、っていう軽い気持ちで参加したのでした。</p>
<p>会場でまず感じたのは、運営のある種の「ゆるさ」のようなものでした。かと言ってイベントはぐだぐだにはならず、なぜかそれなりに進行していく。少し大げさに言うと、イベントが運営スタッフによって動かされているのではなく、イベントが参加者もスピーカーもスポンサーも巻き込んでそれ自体の意思でずるずると動いているような、そんな感じ。そして俺にはその感じが面白かったし、けっこう心地良かったんです。</p>
<p>カンファレンスも、その筋の権威をお招きしてありがたいお話をうかがうみたいなノリがまるでなくて、現場で実際に WordPress に関わっている人たちがそれぞれの知見をシェアする場、という印象。スピーカーと参加者が明確に分かれてなくて、参加者のうち何人かがたまたま登壇してしゃべっている、そんな雰囲気でした。</p>
<p>カンファレンス後の懇親会も、ふだんならその手のはシカトしてとっとと帰るとこなんですが、勢いで参加してみたら思いのほか楽しかったです。あまり関係ないですが、そのとき <a href="http://www.cardcloud.com/cipher">こもりさん</a> にはじめてお会いして、「いま無職なんですよ」みたいな話をしたら「僕も無職みたいなもんです」って返されたのが妙に印象に残ってますね。</p>
<p>というように WordCamp Yokohama 2010 がとても楽しかったので、もし自分にも貢献できることがあればやってみたいなーなどとぼんやり考えて、横浜で出会った運営スタッフの <a href="http://www.understandard.net/">じゅんさん</a> に、もし次に首都圏で何かやるときは呼んでねーみたいな話をしてたんです。そしたら今年の秋、こんど東京でやるのでデザイナーやりませんかと声をかけていただき、今に至るというわけです (ありがとう、じゅんさん!)。だから今回の WordCamp に参加して自分も何かやってみたいと思った方は、実行委員長の <a href="http://waviaei.com/">とおるさん</a> あたりをつかまえて「何かやらせろ」って言ってみるといいです。なんなら次回の実行委員長とかやらせてもらえます。</p>
<p>以上、WordPress をマニアックに追っかけているわけでもない上、人見知りするし出不精だし友達も少ない、そんな俺でも WordCamp は楽しめるし、その気になれば運営スタッフとして関わることもできるよ、という話でした。<a href="http://2011.tokyo.wordcamp.org/registration/">参加登録</a> がまだの方はお早めにどうぞ!</p>
Open Sans
2011-12-09T00:00:00Z
https://terkel.jp/archives/2011/12/open-sans/
<p>このサイトのボディの欧文フォントとして <a href="http://www.google.com/webfonts">Google Web Fonts</a> で提供されている <a href="http://www.google.com/webfonts/specimen/Open+Sans">Open Sans</a> を使ってみることにした。<a href="https://chrome.google.com/webstore">Chrome ウェブストア</a> とかで採用されてるので見たことある人も多いんじゃないでしょうか。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/open-sans.png" />
</figure>
<p>比較的ニュートラルだけど、g や t やイタリックの f あたりのクセが好み。5 ウェイトでそれぞれにイタリックがあり、計 10 通りのバリエーションがあるのもいいです。とは言え実際にはそこまで必要ないので、このサイトでは 400、400 のイタリック、700、700 のイタリックという 4 種に絞って利用。</p>
<p>Google Web Fonts のフォントファイルを読み込むには CSS の <code>@import</code> ルールや JavaScript の API を使う方法もあるけど、おそらく <code>link</code> 要素でのインクルードがいちばん手軽で速いと思います。</p>
<pre><code class="language-html"><link rel="stylesheet"
href="http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700">
</code></pre>
<p>あとは CSS で <code>font-family</code> を指定するだけ。</p>
<pre><code class="language-css">body {
font-family: "Open Sans", "Hiragino Kaku Gothic ProN", "Meiryo", sans-serif;
}
</code></pre>
<p>ヒラギノやメイリオとの相性も悪くないと思うんですが、どうですかね。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/open-sans-mac.png" />
<figcaption>Open Sans + ヒラギノ角ゴ ProN (Mac)</figcaption>
</figure>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/open-sans-win.png" />
<figcaption>Open Sans + メイリオ (Windows)</figcaption>
</figure>
<p>ちなみに、このサイトでは長らく Helvetica Neue を使ってたけど、和文との相性が気になりだして Lucida Grande に鞍替え、でも Lucida Grande はイタリックがないしちょっとうるさい気がしてきたのでなんかいいのないかな、というのが今までの流れです。飽きたら Helvetica に戻します!</p>
Sass の @extend はどこがすごいのか
2011-12-16T00:00:00Z
https://terkel.jp/archives/2011/12/sass-extend/
<p>この記事では <a href="http://atnd.org/events/21919">Less & Sass Advent calendar 2011</a> の 16 日目として、Sass の <a href="http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#extend"><code>@extend</code></a> 機能について書いてみます。が、諸事情により締め切りを過ぎてからあわてて書いており、かなりとっ散らかったものになるであろうことをあらかじめお断りしておきます。</p>
<p>さて、まずは <code>@extend</code> の基本的な機能についてざっとおさらい。<code>@extend</code> される側として一連のスタイルを定義したセレクタがあり、そのセレクタを <code>@extend</code> で継承しつつプロパティを追加したりして、新しいセレクタを作ります:</p>
<pre><code class="language-scss">// SCSS
// 継承元のセレクタ
.button {
display: inline-block;
border: 1px solid gray;
background-color: silver;
&:hover {
border-color: black;
}
}
// .button セレクタを継承・拡張
.button-download {
@extend .button; // .button を継承
background-color: green; // プロパティを上書き
border-radius: 4px; // 新たなプロパティの追加
.icon { // ネストしたセレクタの追加
background: url(/img/download.png) no-repeat 0 50%;
}
}
</code></pre>
<p>この SCSS をコンパイルすると、こういう CSS が生成されます:</p>
<pre><code class="language-css">/* CSS */
.button,
.button-download {
display: inline-block;
border: 1px solid gray;
background-color: silver;
}
.button:hover,
.button-download:hover {
border-color: black;
}
.button-download {
background-color: green;
border-radius: 4px;
}
.button-download .icon {
background: url(/img/download.png) no-repeat 0 50%;
}
</code></pre>
<p>このように、共通するプロパティはひとつのルールセットに、そして差分だけが新たなルールセットにまとめられ、じつに合理的なコードが生成されます。ここでは 2 つのセレクタ間でしか <code>@extend</code> していませんが、これが増えてくるとさらにありがたみが増します。ボタンを例に出しましたが、たとえばリストやテーブルなど、基本的には似てるんだけど少しずつ違うスタイルのモジュールがいくつもある、みたいなときに威力を発揮します。</p>
<p>しかし、これだったら <a href="http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#mixins">ミックスイン</a> でもいいんじゃないの、という意見もあるかもしれません。この場合で言うと、<code>.button</code> のスタイルをミックスイン化して <code>.button-download</code> のルールセット内で <code>@include</code> すれば、結果として同じスタイルを実現することはできます。しかし、そこに至る考え方が <code>@extend</code> とミックスインではまるで違うのです。</p>
<p>ミックスインは、<code>@include</code> で挿入した箇所で展開されるコード片です。ミックスイン自体のコードは CSS としてコンパイルされず、<code>@include</code> されてはじめて実体を持ちます。そのため、使いそうなものをひととおりライブラリとして読み込んでおいて必要に応じて呼び出す、という使い方が可能です。</p>
<p>一方 <code>@extend</code> は、実際に存在している CSS のスタイルをもとにしたものです。一連のスタイル定義をいわば「スタイルオブジェクト」として捉え、<code>@extend</code> によってそれを継承・拡張して新たなオブジェクトを作るもの、と考えられます。</p>
<p>この「スタイルオブジェクト」というのは僕が勝手に呼んでいる名前で、なんとなくぼんやりとそう捉えている、というものです。僕はプログラマでもなければオブジェクト指向をきっちり勉強した経験もないので (こないだ友人の <a href="http://www.marugoshi.org/">@marugoshi</a> さんにちょっとだけご教授いただきましたが)、ここでぜひ皆さんのご意見をうかがいたいんですが、<strong>これってひょっとしてオブジェクト指向ですか?</strong></p>
<p>上の SCSS のコードでやってることって、<code>.button</code> っていうひとつのオブジェクトがあって、それを継承しつつも一部のプロパティが違ったり新たなプロパティが追加された <code>.button-download</code> っていうもうひとつのオブジェクトが生成されてる、っていうふうに捉えてるんですが…</p>
<p>そして僕はこういうふうにスタイルを捉えるようになって、明らかにマークアップとスタイルの設計が変わったんですよ。それまで、CSS ってどう書いても最終的にはグチャグチャになる運命 (さだめ) なのでは… と思っていたんですが、はじめてスタイルというものが実体を持って見えるようになった、ような気がしたんです、Sass の <code>@extend</code> を使うようになって。</p>
<p>オブジェクト指向の CSS というと <a href="https://github.com/stubbornella/oocss">OOCSS</a> というのが有名ですけど、あれってどうも曲解されているというか、ようするにスタイルをクラスに細切れにしてマークアップにぽんぽん放り込めばいいんでしょ、みたいな見方をされてる気がするんですよ。たとえばこんなの:</p>
<pre><code class="language-html"><a class="button button-download button-rounded button-green text-bold align-center valign-top font-15">ダウンロード</a>
</code></pre>
<p>これはさすがに極端ですが、でもいわゆる CSS フレームワーク的なアプローチを採ろうとすると多かれ少なかれこういったマークアップになりがちな気がします。</p>
<p>そうではなくて、マークアップをシンプルに保ち、かつスタイルを変更する際になるべく影響を受けないよいうに、あらかじめマークアップの各要素というかモジュールごとにスタイルとは切り離した適切な名前をつけておいて、スタイルはスタイルでオブジェクトとして体系化してマークアップから分離する、みたいな理想にオブジェクト指向な Sass で少し近づけるのかも… とか考えるんですが、どうでしょう。</p>
<p>最後に、Sass の <code>@extend</code> 関連で参考になった記事をいくつかリストアップしておきます:</p>
<ul>
<li><a href="http://nex-3.com/posts/99-selector-inheritance-the-easy-way-introducing-extend">Selector Inheritance the Easy Way: Introducing @extend : Nex3</a>:
開発者のブログ</li>
<li><a href="http://d.hatena.ne.jp/jdg/20110603/1307084785">Sassの@extendでCSSとHTMLをシンプルに - あと味</a>:
入門編として簡潔にまとまっていてわかりやすい</li>
<li><a href="http://www.culture27.com/blog/2011/07/sass_memo_4.php">Sass(Scss) Memo: @extend | Culture27</a>:
じつはややこしい <code>@extend</code> の仕様がかなり詳細に調べられていて素晴らしいです</li>
<li><a href="http://designshack.net/articles/css/extends-and-control-directives-two-crazy-things-sass-can-do-that-less-cant/">Extends and Control Directives: Two Crazy Things Sass Can Do That LESS Can’t | Design Shack</a>:
Sass は LESS と違って <code>@extend</code> とか使えてヤバい、という話
(あわせて読みたい: <a href="http://d.hatena.ne.jp/hokaccha/20111214/1323821463">LESSにextendを実装してみた - hokaccha.hamalog v2</a>)</li>
<li><a href="http://blog.millermedeiros.com/2011/11/the-problem-with-css-pre-processors/">The problem with CSS pre-processors | Blog | Miller Medeiros</a>:
Sass の問題点や要望など。<code>@extend</code> の継承元をコンパイルされないようにする機能とかたしかにあるといかも</li>
</ul>
<p>えー、タイトルで「どこがすごいのか」と大見得を切っておきながらこれといった結論に至らずお恥ずかしい限りです。あと、アドベントカレンダーのスケジュールを乱してまことに申し訳ございませんでした!</p>
俺の CSS リセット: 2011 冬
2011-12-25T00:00:00Z
https://terkel.jp/archives/2011/12/css-reset-2011-winter/
<p>年末だからというわけでもないのですが、いつものサイト作りに使う CSS リセットについて見直してみました。今までもちょっとずつ手を入れてはいたのですが、今回はかなり大きく修正しています。というのも、<a href="http://nicolasgallagher.com/">Nicolas Gallagher</a> と <a href="http://twitter.com/jon_neal">Jonathan Neal</a> の両氏による <a href="http://necolas.github.com/normalize.css/">normalize.css</a> を知り、大きく影響を受けたからです。</p>
<p>Normalize.css は「新手の CSS リセット」ではありません。CSS を「リセット」するのではなく「ノーマライズ」する、という新しい考え方です。CSS リセットとノーマライズはどちらも、ブラウザ間で CSS の実装に差異があることを前提にそれらを吸収しようとする、という同じ目的を持っています。ただ、リセットはすべてをまっさらな「さら地」にしようとするのに対し、ノーマライズは使える部分は残しつつ手を入れる必要のある部分だけを整える、という違いがあります。「ブラウザ間の CSS 実装に差異がある」とは言っても、それぞれのブラウザが勝手にてんでバラバラの方向を向いているわけではないので、歩調のあってるとこまでわざわざ殺さず、活かせるものはそのまま活かして、という発想です。</p>
<p>Normalize.css によって具体的にどんなスタイルになるかは <a href="http://necolas.github.com/normalize.css/demo.html">デモ</a> をご覧いただくのが手っ取り早いと思います。シンプルなサイトなら、ここにちょっとしたレイアウトのスタイルを追加すればそのまま完成するような、汎用性の高いスタイルです。</p>
<p>とは言え、長いことリセットという手法が一般的であったため、たとえばブロックレベル要素のマージンやリストのマーカーがデフォルトのままだったりすると扱いづらいという場合も多いんじゃないでしょうか。一から自分でコントロールできる新規プロジェクトならいいですが、チームでメンテナンスしていたり、運用・管理を他の人に移譲するものの場合、ある程度はコモンセンスというか浸透している手法でないと採用が難しい、というところもあると思います。とくにリセットもノーマライズもスタイルの基盤を作るもので、その後の CSS 設計のすべてに大きく影響するものなのでなおさらです。</p>
<p>というわけで、ノーマライズの考え方を取り入れつつも影響の大きそうな部分はリセットしておくという、新しいリセットのアプローチを模索しています。以下はそうやって出来た「俺の CSS リセット: 2011 冬」です。Normalize.css については <a href="https://github.com/necolas/normalize.css/wiki">GitHub の Wiki</a> に詳しい解説があるのでそちらも参照してみてください。そこには先人たちの様々な CSS テクニックが盛り込まれており、そのまま採用しないにしても読むだけで得られるものは少なくないと思います。</p>
<h2>ソースコード</h2>
<pre><code class="language-css">/*!
* CSS Reset 2011-12-25
* https://gist.github.com/1360380
*
* Author: Takeru Suzuki, https://terkel.jp/
* License: Public domain
*
* Inspired by Normalize.css: http://necolas.github.com/normalize.css/
*/
/* HTML5 display definitions */
section, nav, article, aside, hgroup,
header, footer, figure, figcaption, details {
display: block;
}
video, audio, canvas {
display: inline-block;
*display: inline;
*zoom: 1;
}
audio:not([controls]) {
display: none;
}
[hidden] {
display: none;
}
/* The root element */
html {
font-size: 100%;
overflow-y: scroll;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
/* Sections */
body {
font-family: sans-serif;
margin: 0;
}
h1, h2, h3, h4, h5, h6 {
font-size: 1em;
margin: 0;
}
/* Grouping content */
p, blockquote, dl, dd, figure {
margin: 0;
}
hr {
color: inherit;
height: auto;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
pre {
font-family: monospace, sans-serif;
white-space: pre-wrap;
word-wrap: break-word;
margin: 0;
}
ol, ul {
padding: 0;
margin: 0;
}
li {
list-style: none;
}
/* Text-level semantics */
a:focus {
outline: thin dotted;
}
a:hover, a:active {
outline: 0;
}
strong, b {
font-weight: bold;
}
small {
font-size: 0.83em;
}
q {
quotes: none;
}
abbr[title] {
border-bottom: 1px dotted;
}
code, samp, kbd {
font-family: monospace, sans-serif;
}
mark {
color: black;
background-color: yellow;
}
sub, sup {
font-size: 0.83em;
line-height: 0;
vertical-align: baseline;
position: relative;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
br {
letter-spacing: 0;
}
/* Embedded content */
img {
border: 0;
-ms-interpolation-mode: bicubic;
}
svg:not(:root) {
overflow: hidden;
}
/* Tabular data */
table {
border-collapse: collapse;
border-spacing: 0;
}
caption {
padding: 0;
text-align: left;
}
th, td {
text-align: left;
vertical-align: baseline;
padding: 0;
}
/* Forms */
form {
margin: 0;
}
fieldset {
border: 0;
padding: 0;
margin: 0;
}
legend {
border: 0;
*margin-left: -7px;
}
input, button, select, textarea {
font-family: inherit;
font-size: 1em;
color: inherit;
margin: 0;
}
input, button {
line-height: normal;
vertical-align: inherit;
*vertical-align: middle;
}
input::-moz-focus-inner,
button::-moz-focus-inner {
border: 0;
padding: 0;
}
input[type="search"] {
-webkit-appearance: textfield;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
input[type="search"]:focus {
outline-offset: -2px;
}
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box;
padding: 0;
}
input[type="submit"],
input[type="reset"],
input[type="button"],
button {
cursor: pointer;
-webkit-appearance: button;
*overflow: visible;
}
select {
background-color: inherit;
line-height: normal;
}
textarea {
vertical-align: top;
overflow: auto;
*font-family: sans-serif;
}
</code></pre>
<p>長い… 要素の分類と記述順は <a href="http://dev.w3.org/html5/spec/Overview.html">HTML5 の仕様書</a> を参考にしました。以下、それぞれのパートごとにできる限り解説してみます。</p>
<h3>HTML5 display definitions</h3>
<pre><code class="language-css">section, nav, article, aside, hgroup,
header, footer, figure, figcaption, details {
display: block;
}
video, audio, canvas {
display: inline-block;
*display: inline;
*zoom: 1;
}
audio:not([controls]) {
display: none;
}
[hidden] {
display: none;
}
</code></pre>
<p>まずは HTML5 の新仕様関連で、normalize.css 丸写しです。HTML5 以前の古いブラウザ向けですね。<code>video</code> や <code>audio</code> などマルチメディア系の要素は個人的に扱った経験がないため詳しくはわからないんですが、とりあえずは <code>display</code> まわりを揃える程度なので、このままいってよさそうです。将来的に実装が進んだときはもうちょっと複雑な記述が必要になるのかもしれません。<a href="http://dev.w3.org/html5/spec/Overview.html#the-hidden-attribute"><code>hidden</code> 属性</a> は HTML5 で新しく定義されたグローバル属性です。属性セレクタによる指定のため IE6 では非表示になりませんが。</p>
<h3>The root element</h3>
<pre><code class="language-css">html {
font-size: 100%;
overflow-y: scroll;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
</code></pre>
<p>次はドキュメントのルートであるところの <code>html</code> への指定で、ここも normalize.css まんまです。</p>
<p><code>font-size: 100%</code> は、フォントサイズを em 単位で指定した場合に「文字サイズの変更」をおこなうとサイズが極端に変動するという IE6/7 のバグへの対応です。これはいずれかの祖先要素のフォントサイズを % 単位で指定しておくと回避できるので、こうしておけば <code>body</code> 以下で自由に em が使えます。</p>
<p><code>overflow-y: scroll</code> は IE6/7 以外のブラウザ向けで、ドキュメントの高さがウィンドウより小さくても縦のスクロールバー領域を確保するというものです。</p>
<p>次の <code>-webkit-text-size-adjust: 100%</code> と <code>-ms-text-size-adjust: 100%</code> は iOS の文字サイズ自動アジャスト機能に対するもののようです。が、手元の iPhone で軽く検証したりググってみたりしたものの、正直よくわかっていません… とりあえず、この値を <code>none</code> にしてしまうのはどうもよくないらしいとか、IE Mobile がなぜか <code>-webkit-text-size-adjust</code> をサポートしてた (けど直った?) とか、iOS だけじゃなくてデスクトップ版 Safari にも影響があったとか、なんかややこしいらしいってことだけはわかりました。どなたかご教授いただけると嬉しいです! ここでは参考になりそうなリンクだけ並べてお茶を濁します:</p>
<ul>
<li><a href="http://developer.apple.com/library/IOs/#documentation/AppleApplications/Reference/SafariWebContent/AdjustingtheTextSize/AdjustingtheTextSize.html">Safari Web Content Guide: Customizing Style Sheets</a></li>
<li><a href="http://msdn.microsoft.com/ja-jp/library/ff462082(v=VS.92).aspx">MSDN - Windows Phone 用の Web 開発</a></li>
<li><a href="http://www.atmarkit.co.jp/fsmart/articles/iphone/04.html">iPhone向けWebアプリを作ろう(4/4) - @IT</a></li>
<li><a href="http://www.456bereastreet.com/archive/201011/beware_of_-webkit-text-size-adjustnone/">Beware of -webkit-text-size-adjust:none | 456 Berea Street</a></li>
<li><a href="http://www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/">Controlling text size in Safari for iOS without disabling user zoom | 456 Berea Street</a></li>
<li><a href="https://bugs.webkit.org/show_bug.cgi?id=56543">WebKit Bugzilla - Bug 56543 - CSS property "-webkit-text-size-adjust" means different things in Safari and iOS</a></li>
<li><a href="http://web.g.hatena.ne.jp/vantguarde/20110614/1308061678">-webkit-text-size-adjustがiOS以外でも効いてしまうらしい - vantguarde - web:g</a></li>
<li><a href="https://github.com/necolas/normalize.css/issues/28">#28: Delete -ms-text-size-adjust - Issues - necolas/normalize.css - GitHub</a></li>
</ul>
<h3>Sections</h3>
<pre><code class="language-css">body {
font-family: sans-serif;
margin: 0;
}
h1, h2, h3, h4, h5, h6 {
font-size: 1em;
margin: 0;
}
</code></pre>
<p><code>body</code> の <code>font-family</code> はとりあえずざっくりと指定しておいて、あとはプロジェクトごとに細かくやる (あるいはやらない) という感じ。<code>margin</code> はリセット。ちなみに <code>body</code> のマージンはデフォルトだと IE6/7 でやや大きいです。</p>
<p><code>hn</code> は normalize.css だと HTML5 のセクショニング要素の対応として <code>h1 { font-size: 2em; }</code> しか指定してない (<a href="https://github.com/necolas/normalize.css/issues/41">#41: Normalize headings - Issues - necolas/normalize.css - GitHub</a>) ですが、ここでは <code>h1</code> から <code>h6</code> まで <code>font-size</code> と <code>margin</code> をリセットしてます。</p>
<h3>Grouping content</h3>
<pre><code class="language-css">p, blockquote, dl, dd, figure {
margin: 0;
}
hr {
color: inherit;
height: auto;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
pre {
font-family: monospace, sans-serif;
white-space: pre-wrap;
word-wrap: break-word;
margin: 0;
}
ol, ul {
padding: 0;
margin: 0;
}
li {
list-style: none;
}
</code></pre>
<p>段落やリストなど、実際にサイトでよく使うとこですね。このへん、normalize.css ではあまりいじってないんですが、ここではけっこうリセットしてます。</p>
<p>まず <code>p</code> などブロックレベル要素の <code>margin</code> はリセット。<code>ul</code> と <code>ol</code> は <code>padding</code> も <code>0</code> に、<code>li</code> のマーカーもなし。normalize.css では <code>nav</code> 要素の子孫である場合にだけマーカーなしですが、実際問題としていわゆる普通のサイトではマーカーとして独自の画像を用意することが多いと思うので。</p>
<p><code>hr</code> は <a href="http://mxr.mozilla.org/mozilla-central/source/layout/style/html.css#632">Firefox のスタイルがちょっと例外的</a> なので他のブラウザに合わせる方向。IE6/7 以外は上下に 0.5em の <code>margin</code> を持っていますが、IE6/7 では上下の余白がコントロールできないため、きっちり見た目を揃えるのが難しいです。なのであえてリセットせずそのまま残してます。</p>
<p><code>pre</code> はまず <a href="http://en.wikipedia.org/wiki/User:Davidgothberg/Test59">Safari と Chrome でフォントサイズが揃わない問題</a> への対応として <code>font-family: monospace, sans-serif</code> を指定。あと行が長くなったときに折り返すようにしています。</p>
<h3>Text-level semantics</h3>
<pre><code class="language-css">a:focus {
outline: thin dotted;
}
a:hover, a:active {
outline: 0;
}
strong, b {
font-weight: bold;
}
small {
font-size: 0.83em;
}
q {
quotes: none;
}
abbr[title] {
border-bottom: 1px dotted;
}
code, samp, kbd {
font-family: monospace, sans-serif;
}
mark {
color: black;
background-color: yellow;
}
sub, sup {
font-size: 0.83em;
line-height: 0;
vertical-align: baseline;
position: relative;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
br {
*letter-spacing: 0;
}
</code></pre>
<p>いわゆるインライン要素。このあたりは基本的にデフォルトの <code>font-weight</code> や <code>font-style</code> をそのまま活かします。</p>
<p><code>a</code> の <code>outline</code> プロパティは、<a href="http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/">Eric Meyer 氏のリセットの古い版</a> で「ちゃんとあとから自分で定義し直してね!」っていう注釈つきで <code>:focus { outline: 0; }</code> となってた (<a href="http://meyerweb.com/eric/thoughts/2011/01/03/reset-revisited/">のちに修正された</a>) のがそのまま広まってしまった感があります。が、それではアクセシビリティ上の問題があるので、そのあたりを考慮したものになってます。以下、参考資料:</p>
<ul>
<li><a href="http://www.outlinenone.com/">CSS outline property - outline: none and outline: 0</a></li>
<li><a href="http://24ways.org/2009/dont-lose-your-focus">24 ways: Don't Lose Your :focus</a></li>
<li><a href="http://people.opera.com/patrickl/experiments/keyboard/test">Better CSS outline suppression</a></li>
<li><a href="http://white-stage.com/article.php/outline">フォーカス時の輪郭線(アウトライン)の役割をご存知ですか? - White Stage</a></li>
</ul>
<p><code>strong</code> と <code>b</code> は Firefox や WebKit のデフォルトでは <code>bold</code> ではなく <code>bolder</code> という相対値です。つまり、<code><h1><b>Steve Jobs</b>: 1955–2011</h1></code> というマークアップで <code>h1</code> の <code>font-weight</code> が <code>bold</code> (<code>700</code>) の場合、その中の <code>b</code> は <code>900</code> となるわけです (<a href="http://www.w3.org/TR/css3-fonts/#font-weight-prop">CSS Fonts Module Level 3 - 3.2 Font weight: the font-weight property</a>)。このままでもいいんですが、予期したウェイトよりも太くなってしまうってことがけっこうありそうなので <code>bold</code> に揃えよう、ってことだと思いますたぶん。ウェイトがノーマルかボールドしか使えない場合がほとんどの和文フォントではあまり気にする機会がありませんが。</p>
<p><code>sub</code> と <code>sup</code> は行の高さと縦位置の調整です (<a href="https://gist.github.com/413930">CSS for <sub> and <sup> — Gist</sup></sub></a>)。</p>
<p><code>br</code> は <a href="http://d.hatena.ne.jp/aratako0/20070131/p1">親要素に <code>letter-spacing</code> が指定されているときに連続して改行しても認識されない</a> という IE6/7 のバグへの対応。</p>
<h3>Embedded content</h3>
<pre><code class="language-css">img {
border: 0;
-ms-interpolation-mode: bicubic;
}
svg:not(:root) {
overflow: hidden;
}
</code></pre>
<p><code>img</code> はリンク時のボーダーを消して、<a href="http://msdn.microsoft.com/en-us/library/ms530822(v=vs.85).aspx">IE7 で拡大縮小したときに綺麗にする</a>、っていういつものやつです。<code>svg</code> は IE9 向けの指定みたいです。</p>
<h3>Tabular data</h3>
<pre><code class="language-css">table {
border-collapse: collapse;
border-spacing: 0;
}
caption {
padding: 0;
text-align: left;
}
th, td {
text-align: left;
vertical-align: baseline;
padding: 0;
}
</code></pre>
<p>テーブル関連はセル間の隙間をなくすのに加えて、キャプションとセルの文字方向とパディングをリセットしてます。</p>
<h3>Forms</h3>
<pre><code class="language-css">form {
margin: 0;
}
fieldset {
border: 0;
padding: 0;
margin: 0;
}
legend {
border: 0;
*margin-left: -7px;
}
input, button, select, textarea {
font-family: inherit;
font-size: 1em;
color: inherit;
margin: 0;
}
input, button {
line-height: normal;
vertical-align: inherit;
*vertical-align: middle;
}
input::-moz-focus-inner,
button::-moz-focus-inner {
border: 0;
padding: 0;
}
input[type="search"] {
-webkit-appearance: textfield;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
input[type="search"]:focus {
outline-offset: -2px;
}
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box;
padding: 0;
}
input[type="submit"],
input[type="reset"],
input[type="button"],
button {
cursor: pointer;
-webkit-appearance: button;
*overflow: visible;
}
select {
background-color: inherit;
line-height: normal;
}
textarea {
vertical-align: top;
overflow: auto;
*font-family: sans-serif;
}
</code></pre>
<p>そして最後はフォーム関連。やはりここがもっともややこしいですね。基本的に normalize.css まんまなので詳しくはそちらを参照していただきたいんですが、おもに以下のような指定を追加してます:</p>
<ul>
<li><code>fieldset</code> の余白とボーダーはリセット。</li>
<li>Chrome は <code>select</code> に <code>background-color</code> を指定しないとフォント系プロパティを継承しないので指定。</li>
</ul>
<p>HTML5 の新しいコントロール型として <code>search</code> 型にけっこうな手間をかけてますが、これからほかの新しい型の実装も進んだとき、今までのようにすべてリセットしてクロスブラウザでピクセルパーフェクトなルックを目指すというのはいよいよ現実的ではないと思います。そういった意味で、フォームこそ CSS ノーマライズという考え方の真価が発揮されるところかもしれません。</p>
<h2>メンテナンス</h2>
<p>さて、この手のコードは、チームや個人で一度これと決めてしまうとあまり中身を見直されることなくそのまま使い回されるということになりがちです。その結果として、すでに不要になった古い (バッド) ノウハウが残り続け、よくわからないまま「おまじない」として次世代に受け継がれていく… という、あまり好ましくない事態が想定されます。とくに今後、要らないベンダー接頭辞が残り続けているという事態はちょくちょく目にすることになりそうです。ですから、ブラウザの実装の進歩やシェアの変動を踏まえつつ、折を見て内容を吟味して、更新し続けることが重要だと考えます。</p>
<p>というわけで、上記 CSS のソースコードは Gist に置いてます。気がついたときにちょくちょく手を入れると思うので、本稿での記述とは違っていることがあるかもしれません。あと現時点でのデモページも用意しました。HTML の中身は normalize.css のをそのまま拝借しています:</p>
<ul>
<li><a href="https://gist.github.com/1360380">CSS Reset — Gist</a></li>
<li><a href="https://terkel.jp/demo/css-reset-2011-winter.html">Demo: CSS Reset 2011 Winter</a></li>
</ul>
<h2>参考</h2>
<p>最後に参考にしたリソースのリストを。まずはブラウザのデフォルトのスタイルシートを確認できるサイトです。IE のは公式じゃないし、Opera のは見つけられませんでした:</p>
<ul>
<li><a href="http://mxr.mozilla.org/mozilla-central/source/layout/style/html.css">mozilla-central mozilla/layout/style/html.css</a></li>
<li><a href="http://mxr.mozilla.org/mozilla-central/source/layout/style/forms.css">mozilla-central mozilla/layout/style/forms.css</a></li>
<li><a href="http://trac.webkit.org/browser/trunk/Source/WebCore/css/html.css">/trunk/Source/WebCore/css/html.css – WebKit</a></li>
<li><a href="http://www.iecss.com/">Internet Explorer UA Style Sheets</a></li>
<li><a href="http://css-class.com/test/css/defaults/UA-style-sheet-defaults.htm">CSS2.1 User Agent Style Sheet Defaults</a></li>
</ul>
<p>あと、メジャーな CSS リセットをいくつか:</p>
<ul>
<li><a href="http://meyerweb.com/eric/tools/css/reset/">CSS Tools: Reset CSS</a>: Eric Meyer’s CSS Reset</li>
<li><a href="http://html5doctor.com/html-5-reset-stylesheet/">HTML5 Reset Stylesheet | HTML5 Doctor</a></li>
<li><a href="http://yuilibrary.com/yui/docs/cssreset/">CSS Reset - YUI Library</a></li>
</ul>
<p>メリー・クリスマス!</p>
キャプションの幅を画像の幅に合わせる
2012-01-08T00:00:00Z
https://terkel.jp/archives/2012/01/shrink-to-fit-figcaption/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/shrink-to-fit-figcaption-fig1.png" />
<figcaption>Fig 1: Wikipedia のキャプションつき画像の例</figcaption>
</figure>
<p>ちょっとわかりにくいタイトルになってしまいましたが、つまり Wikipedia のやつ (<a href="https://terkel.jp/archives/2012/01/shrink-to-fit-figcaption/#fig1">Fig 1</a>) みたいに、「<strong>画像 (またはビデオなどの埋め込みコンテンツ) の下にキャプションをレイアウトするとき、キャプションが複数行にわたる場合は画像の幅に合わせて折り返したい (ただし画像の幅はバラバラ)</strong>」というのをシンプルかつ汎用的なかたちで実現する CSS を考えてみました。というか、このブログのレイアウト用にけっこう長いことあれこれ考えてたもののこれといった手が思いつかなくて放置していたんですが、<a href="http://stackoverflow.com/a/6536025">上手い解決を Stack Overflow でみつけた</a> のでパクった、という話です。</p>
<pre><code class="language-html"><figure>
<img src="/img/photo.jpg">
<figcaption>Lorem ipsum dolor sit amet</figcaption>
</figure>
</code></pre>
<p>ここではこのマークアップをもとに考えてみます。スタイルの要件をまとめると以下のとおり:</p>
<ul>
<li><code>figure</code> の幅は <code>img</code> の幅に合わせたい</li>
<li><code>img</code> の幅は不確定</li>
<li><code>figcaption</code> は存在しない場合もあり、もし存在すればテキスト量は不確定で、幅は <code>figure</code> の幅に合わせ、複数行にわたる場合はなりゆきで折り返したい</li>
</ul>
<p>考えられるアプローチのひとつとして、<code>figure</code> の幅についてあらかじめいくつかのパターンを決めておくというものがあります。<code>img</code> は <code>figure</code> の幅に合わせて書き出してもいいし、大きめに作っておいてブラウザで縮めてもいいでしょう。シンプルなグリッドがきっちり決まってる場合なんかはいいかもしれませんが、マークアップの <code>class</code> 属性や <code>data-*</code> 属性などを指定する必要があり、あまり汎用的とは言えないかもしれません。</p>
<pre><code class="language-css">figure.small { width: 160px; }
figure.mideium { width: 240px; }
figure.large { width: 320px; }
figure img { max-width: 100%; }
</code></pre>
<p>あるいは JavaScript で <code>img</code> の幅を取得して <code>figure</code> の幅を操作するという手もあります。これならかなり汎用性も高いです。ただ、JavaScript で画像のサイズの取得をエラー処理やなんかも含めてきっちりやるのって、けっこうたいへんですよね? 僕は何度か挫折しました…</p>
<p>あとは CMS とかのシステム側でうまいことやってもらうって感じですかね。画像のアップロード時に、その幅に応じて <code>style</code> 属性を自動的にかますような。<a href="http://ja.wikipedia.org/wiki/Help:%E7%94%BB%E5%83%8F%E3%81%AE%E8%A1%A8%E7%A4%BA">Wikipedia なんかはそんな感じ</a> でしょうし、WordPress のプラグインなんかでもそんなのありそう (調べてない)。</p>
<p>というわけで、やはり CSS だけでなんとかしたいなーというのが以下のコード。前述の Stack Overflow で見つけたやつに少しアレンジを加えたものです:</p>
<pre><code class="language-css">figure {
display: table;
width: 160px; /* minimum width */
*width: auto; /* for IE7 and below */
}
</code></pre>
<p>これだけ。<code>figure</code> はテーブルのように振る舞うので、<code>img</code> の幅が <code>figure</code> に指定した幅を超えた場合はその幅に合わせて広がります。またもし <code>img</code> の幅が <code>figure</code> に指定した幅に満たない場合でもつねにその幅が確保されます。<code>figcaption</code> は横に広がろうとしますが、<code>figure</code> の制限をうけてぴったりの幅に収まります。ちなみにここでは <code>figure</code> と <code>figcaption</code> ですが、<code>div</code> と <code>span</code> やなんかでも同じです。デモを用意したのでどうぞ:</p>
<ul>
<li><a href="https://terkel.jp/demo/shrink-to-fit-figcaption.html">Demo: Shrink-to-fit figcaption</a></li>
</ul>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/shrink-to-fit-figcaption-fig2.png" />
</figure>
<p>Stack Overflow のバージョンだと <code>width</code> の値が <code>1px</code> なんですが、それだと <code>img</code> の幅がごく小さいときに <code>figcaption</code> がせまくなり過ぎて読みづらいので、サイトのグリッド構成などに応じて最低限これだけの幅はほしいという値を指定しておくのがいいと思います。ちなみにその場合、<code>img</code> は左に寄せず中央に置くと座りがいいです。</p>
<p>同じく Stack Overflow バージョンは <code>img</code> と <code>figcaption</code> に対して <code>display: table-row</code> を指定していますが、それは必要ない気がします。検証した限りとくに不都合はないのでたぶん大丈夫だと思うんですが…</p>
<p>また、もし <code>img</code> に <code>max-width: 100%</code> というスタイルが指定されていると <code>figure</code> の幅に縮められてしまうので注意が必要です。レスポンシヴなデザインでよく使われるスタイルだと思いますが。</p>
<p><code>display: table</code> をサポートしていない IE7 以下では <code>figure</code> の幅が <code>width</code> の値のとおりに解釈され、結果として縦にひしゃげたかたちになりキャプションが読みづらくなってしまうので、<code>width: auto</code> で上書きしています。とは言えこれで IE8 以上と同じレイアウトになるわけではなく、ただボックスが横に広がるだけです。IE7 では <code>figure</code> と <code>img</code> に <code>max-width</code> を指定すればある程度はコントロールできます (<a href="https://terkel.jp/archives/2012/01/shrink-to-fit-figcaption/#fig-3">Fig 3</a>) が、もし同じレイアウトでということになると、前述のような JavaScript を用いたり幅を固定したりといった手法が必要でしょう。</p>
<figure id="fig-3">
<img decoding="async" alt="" src="https://terkel.jp/img/shrink-to-fit-figcaption-fig3.png" />
<figcaption>Fig 3: IE7 で `figure` 要素と `img` 要素に `max-width` プロパティを指定した場合の表示例</figcaption>
</figure>
<p>Web コンテンツがスマートフォンやタブレットといった多様なデバイスで閲覧される機会が増え、canvas や SVG といった手法も広まってきたいま、「画像」をいかに取り扱うかというのはあらためて考えなければいけない課題のひとつです。今回ここで紹介したのはレイアウトに関するちょっとしたテクニックに過ぎないですが、将来に向けてできる限りシンプルで汎用性の高い手法を模索していきたい、と考えた結果でもあります。</p>
<p>あけましておめでとうございます!</p>
for 属性に対する属性セレクタの IE7 での挙動
2012-02-22T00:00:00Z
https://terkel.jp/archives/2012/02/for-attribute-selectors-in-ie7/
<p>IE7 には、<code>label</code> 要素の <code>for</code> 属性に対する CSS の属性セレクタが無効になるバグがあります。</p>
<pre><code class="language-css">label[for="foo"] {
background-color: yellow;
}
</code></pre>
<p>この場合 <code>for="foo"</code> という属性を持つ <code>label</code> 要素の背景が黄色になるはずですが、IE7 では無視されてしまいます。これはどうやら <code>for</code> というキーワードが DOM の予約語であることに由来するバグのようです (参考: <a href="http://reference.sitepoint.com/css/attributeselector">Attribute Selector (CSS selector) - SitePoint CSS Reference</a>)。そのかわり、IE7 では <code>htmlFor</code> という属性名を利用すればスタイルが有効になります。</p>
<pre><code class="language-css">label[htmlFor="foo"] {
background-color: yellow;
}
</code></pre>
<p>ただこれだと IE8 以降やほかのブラウザが解釈してくれないので、<code>htmlFor</code> と <code>for</code> によるセレクタを並べます。</p>
<pre><code class="language-css">label[htmlFor="foo"],
label[for="foo"] {
background-color: yellow;
}
</code></pre>
<p>これで属性セレクタを解釈するすべてのブラウザでスタイルが有効になります。</p>
<ul>
<li><a href="https://terkel.jp/demo/for-attribute-selectors-in-ie7.html">Demo: <code>[for]</code> attribute selectors in IE7</a></li>
</ul>
Re-Make/Re-Model
2012-04-08T00:00:00Z
https://terkel.jp/archives/2012/04/re-make-re-model/
<p>およそ 2 年ぶりにこのサイトを全面的にリデザインしました。印象としてはさほど大きく変化していないと思うんですが、内部的にはけっこういじってます。細かい部分は追って別の記事にするとして、とりあえずおもな変更点などをざっとまとめてみました。</p>
<h2>レスポンシヴ!</h2>
<p>…ってほどではないのですが、レイアウトを表示域に応じたものにしています (Fig 1)。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/re-make-re-model-responsive.png" />
<figcaption>Fig 1: 表示域の幅 320px、768px、1024px (左から) でのスクリーンショット</figcaption>
</figure>
<pre><code class="language-css">body {
font-size: 1em;
}
@media screen and (max-width: 32em) {
body {
font-size: 0.875em;
}
}
[role="banner"],
[role="main"],
[role="contentinfo"] {
margin-left: auto;
margin-right: auto;
max-width: 46em;
padding-left: 1em;
padding-right: 1em;
}
@media screen and (min-width: 64em) {
[role="banner"],
[role="main"],
[role="contentinfo"] {
padding-left: 17em;
}
.logo {
left: 2em;
position: absolute;
}
}
</code></pre>
<p>CSS でレイアウトに関するおもな記述を抜き出すとこんな感じです。各コンテナの幅は指定せず最大幅のみ指定しています。</p>
<p>スマートフォンなど表示域の幅が狭い場合、フォントサイズがデフォルトのままだとやや大きく感じられたので、ベースをやや小さくしています (デフォルトが 16px なら 14px 相当)。この指定だと iPhone の縦で全角文字が 1 行あたりだいたい 20 文字入ります。</p>
<p>表示域の幅が十分に広い場合は左側に余白を作ってロゴをそちらに配置し、画面あたりの縦の情報量を増やしています。この左側の余白に記事の日付を置いたり画像をはみ出させたりとかも試してみましたが、あまり上手くいかなかったのでやめました。</p>
<p>なおメディアクエリをサポートしていない環境のために <a href="https://github.com/scottjehl/Respond">Respond.js</a> を使っています。</p>
<h2>ロゴとナビゲーション</h2>
<p>ヘッダのロゴとナビゲーションには <a href="http://www.theleagueofmoveabletype.com/league-gothic">League Gothic</a> を使っていましたが (Fig 2)、わりとよく見るようになったし、本来は大文字で使ったほうが活きる書体という気もするので変えることにしました。ロゴは <a href="http://www.google.com/webfonts/specimen/Open+Sans+Condensed">Open Sans Condensed</a> の Book 700、ナビゲーションは本文と同じ <a href="http://www.google.com/webfonts/specimen/Open+Sans">Open Sans</a> の Bold 700 に (Fig 3)。Open Sans がとても気に入っているということです!</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/re-make-re-model-header-v3.png" />
<figcaption>Fig 2: 旧ヘッダ</figcaption>
</figure>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/re-make-re-model-header-v4.png" />
<figcaption>Fig 3: 新ヘッダ</figcaption>
</figure>
<p>ロゴ部分にはこのブログについての簡単な説明のようなものを入れてみました。マークアップとしては <code>h1</code> と <code>h2</code> で、それらを <code>hgroup</code> でまとめて、さらに <code>a</code> でまるごとリンクにしています。</p>
<pre><code class="language-html"><a href="/">
<hgroup class="logo">
<h1>terkel.jp</h1>
<h2>A blog by…</h2>
</hgroup>
</a>
</code></pre>
<p>ナビゲーションのラベルはすべて大文字で、そうすると単語ごとの「かたまり感」のようなものが出せる反面、パッと見でテキストとしてやや認識しづらくなるので、文字間と単語間に余裕を持たせています。</p>
<pre><code class="language-css">.primaryNav {
font-weight: bold;
letter-spacing: 0.125em;
text-transform: uppercase;
word-spacing: 0.25em;
}
</code></pre>
<p>ロゴの装飾とナビゲーションのインジケーターに使っている「円」のイメージにはあまり意味はないのですが、全体的に堅いイメージになりがちなのが若干柔らぐのでいいかなと思ってます。</p>
<h2>タグ、関連記事、ツイート</h2>
<p>各記事のタグとタグクラウド、<a href="http://wordpress.org/extend/plugins/yet-another-related-posts-plugin/">Yet Another Related Posts Plugin</a> による「関連記事」、あと僕の Twitter から最新ツイートを表示するウィジェットをなくしました。</p>
<p>タグは記事を探す手がかりとして使えるだけではなく、その記事の言及している内容を端的に示すことができるということもあり採用していましたが、そういった部分はタイトルや概要をわかりやすくすることで解決したいなと考えてます。そのかわり今後は検索機能をもっと使いやすくしたいですね。</p>
<p>関連記事は必要に応じて記事内で言及したほうがいいという判断ですね。プラグインの精度はけっこう高くて良かったですが。</p>
<p>ツイートは自作 jQuery プラグインで読み込んでいたんですが、やはり前後の文脈をすっ飛ばしてそれだけ載っけてもよくわからんというか、場合によっては良くない印象を与えることもあると思ったので。ちなみに <a href="https://terkel.jp/archives/2011/07/jquery-lastfm-profile-plugin/">Last.fm のウィジェット</a> は誰も必要としていないですが自分が好きなので残します。</p>
<h2>カラー</h2>
<p>背景色のオフホワイト #f8f8f0、前景色のブルーブラック #002040、リンク色のブルー #0080ff の 3 色を基本にして、これらを <a href="http://sass-lang.com/">Sass</a> の <a href="http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#mix-instance_method">mix 関数</a> で混ぜて色を作っています。</p>
<pre><code class="language-scss">$white: #f8f8f0;
$black: #002040;
$blue: #0080ff;
$darkgray: mix($white, $black, 25%);
$gray: mix($white, $black, 50%);
$lightgray: mix($white, $black, 75%);
$palegray: mix($white, $black, 87.5%);
$darkblue: mix($black, $blue, 50%);
$lightblue: mix($white, $blue, 75%);
$paleblue: mix($white, $blue, 87.5%);
</code></pre>
<p>というわけでもちろん CSS は Sass を使って書いているわけですが、来るべき Sass 3.2 も視野に入れつつ書き方を試行錯誤しているので、現時点ではかなりぐちゃぐちゃ (「ソース見んな」って意味です)。近々プレリリース版を入れて整理して、まとまったら一式を GitHub に公開したいですね。</p>
<h2>Re-Make/Re-Model</h2>
<p>いままでホームページには最新の記事 1 本をまるまる載せてたんですが、直近の 8 本の抜粋を並べることにしました。でもそれだけだとちょっとさびしいのでスローガンというかキャッチコピーのようなものを置きたい、ということで <a href="http://www.youtube.com/watch?v=kWhzG9cQGgc">ロクシー・ミュージックの曲</a> から <strong>Re-Make/Re-Model</strong> というフレーズを拝借。フォントはロゴと同じ Open Sans Condensed の Book 300 で、<a href="http://fittextjs.com/">FixText</a> で幅に応じてフォントサイズが変化するようになってます。</p>
<p>このフレーズを選んだのはもちろんそれなりに思うところがあってのことなのですが、そのあたりはこれからこのブログや仕事などで見せていければと思っております!</p>
ブログ記事リストのマークアップ
2012-04-10T00:00:00Z
https://terkel.jp/archives/2012/04/markup-for-blog-post-list/
<p><a href="https://terkel.jp/archives/2012/04/re-make-re-model/">サイトをリデザインした</a> のにともない、全体的にマークアップについても見直しているのですが、ちょっと悩んだのがホームやアーカイヴ・ページなどにある「ブログ記事の概要や抜粋のリスト」です。</p>
<p>よく見かけるのは以下のようなマークアップで、うちもリデザイン前はだいたいこんな感じでした:</p>
<pre><code class="language-html"><section class="articleExcerptList">
<h1>Recent articles</h1>
<article>
<h2><a href="...">ブログ記事リストのマークアップ</a></h2>
<time datetime="...">April 10, 2012</time>
<p><!-- 概要・抜粋 --></p>
<a href="...">Continue reading</a>
</article>
<article>
<h2><a href="...">リデザインしました!</a></h2>
<time datetime="...">April 8, 2012</time>
<p><!-- 概要・抜粋 --></p>
<a href="...">Continue reading</a>
</article>
. . .
</section>
</code></pre>
<p>各アイテムが記事ごとのタイトル、メタデータ (日付やタグなど)、適当な長さの概要・抜粋、「続きを読む」リンクといったものから構成されていて、それぞれが <code>article</code> 要素、というかたちです。よく見かけるというか、ざっと調べたところかなりの割合のブログがこうでしたね。</p>
<p>で、これって <code>article</code> でいいんだろうか、というのが気になったわけです。</p>
<p><code>article</code> 要素について <a href="http://www.w3.org/TR/2012/WD-html5-20120329/the-article-element.html#the-article-element">仕様</a> にはこう書かれています:</p>
<blockquote cite="http://www.w3.org/TR/2012/WD-html5-20120329/the-article-element.html#the-article-element" lang="en">
<p>The <code><a href="http://www.w3.org/TR/2012/WD-html5-20120329/the-article-element.html#the-article-element">article</a></code> element represents a self-contained composition in a document, page, application, or site and that is, in principle, independently distributable or reusable, e.g. in syndication. This could be a forum post, a magazine or newspaper article, a blog entry, a user-submitted comment, an interactive widget or gadget, or any other independent item of content.</p>
</blockquote>
<p>「<code>article</code> 要素は、ドキュメント、ページ、アプリケーション、またはサイトにおいて<strong>それだけで機能する構成要素</strong>を表すもので、それは原理的にはたとえばフィードなどで独立して共有されたり再利用されたりすることが可能なものです。フォーラムの発言、雑誌や新聞の記事、ブログのエントリー、ユーザーの投稿したコメント、インタラクティヴなウィジェットやガジェット、そのほか独立した内容を持つアイテムがこれにあたるでしょう」といったところですね (オレオレ翻訳)。</p>
<p>リストの各項目の内容はたしかに “blog entry” のデータなので <code>article</code> 要素で間違いはないようにも思えますが、“self-contained composition in a document” かというとちょっと違う気がします。それぞれの<strong>リンク先</strong>の記事そのものは self-contained ですが、リストを含むドキュメント (たとえばホームページ) においてそれらはあくまで別のドキュメントの概要や抜粋であり、それだけで機能するとは言いがたいと思うのです。概要や抜粋のリストはいわば「目次」のようなものであり、記事そのものではありません。逆に、複数の記事が並んでいてもそれぞれ全文を掲載していれば <code>article</code> でもいいかなと思います。</p>
<p>というわけで、これらは <code>article</code> ではなく <code>section</code> のほうが良いのではないだろうか、と思うのですがどうでしょう:</p>
<pre><code class="language-html"><section class="articleExcerptList">
<h1>Recent articles</h1>
<section>
<h2><a href="...">ブログ記事リストのマークアップ</a></h2>
<time datetime="...">April 10, 2012</time>
<p><!-- 概要・抜粋 --></p>
<a href="...">Continue reading</a>
</section>
<section>
<h2><a href="...">リデザインしました!</a></h2>
<time datetime="...">April 8, 2012</time>
<p><!-- 概要・抜粋 --></p>
<a href="...">Continue reading</a>
</section>
. . .
</section>
</code></pre>
<p>また、概要などがなく、タイトルと日付ぐらいのリストなら <code>ul</code> がいいかなと思います:</p>
<pre><code class="language-html"><ul class="articleList">
<li>
<a href="...">ブログ記事リストのマークアップ</a>
<time datetime="2012-04-09">April 9, 2012</time>
</li>
<li>
<a href="...">リデザインしました!</a>
<time datetime="2012-04-08">April 8, 2012</time>
</li>
. . .
</ul>
</code></pre>
<p>HTML5 のセクショニングの基本的な考え方として、見出しがある (あるいはあってもおかしくない) ものはとりあえず <code>section</code> として、中身が (major な) ナビゲーションなら <code>nav</code>、それだけで機能するようなものなら <code>article</code>、本文とあんまり関係なければ <code>aside</code>、みたいな感じに考えるといいかなと思ってます最近は。</p>
テーブルセルの vertical-align: baseline
2012-04-12T00:00:00Z
https://terkel.jp/archives/2012/04/vertical-align-baseline-in-table-cell/
<p>CSS でテーブルセルに対して <code>vertical-align: baseline</code> を指定したときの挙動はちょっと面白いです。そのセルが属するテーブル行で <code>vertical-align: baseline</code> が指定されたセルのうち、テキストの最初の行のベースラインの位置がもっとも低いセルによってそのテーブル行のベースラインが決まり、セルのテキストの最初の行のベースラインがそこに合わせられます (<a href="http://www.w3.org/TR/CSS2/tables.html#height-layout">17.5.3 Table height algorithms [CSS 2.1]</a>)。たとえば同一行の見出しセルとデータセルでフォントサイズが異なる場合でも、このアルゴリズムによってバランス良く配置することが可能です。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/vertical-align-baseline-in-table-cell-1.png" />
<figcaption>Fig 1: フォントサイズの異なるセルに `vertical-align: baseline` を指定した結果</figcaption>
</figure>
<p>これを応用して、テーブル以外の要素でも <code>display: table-cell</code> を指定すれば、横に並べたフォントサイズの異なる異なるボックスのベースラインを揃えることができます。</p>
<pre><code class="language-html"><article>
<header>
<time>April 12, 2012</time>
<h1>The Rise and Fall of...</h1>
</header>
...
</article>
</code></pre>
<p>たとえばこのようなマークアップがあり、記事の日付とタイトルを横に並べたい場合、</p>
<pre><code class="language-css">h1, time {
display: table-cell;
/* vertical-align: baseline; */
...
}
h1 { font-size: 1.5em; ... }
time { font-size: 0.75em; ... }
</code></pre>
<p>このように指定すれば、フォントサイズの異なる <code>h1</code> と <code>time</code> のベースラインはきれいに揃います。<code>vertical-align</code> の初期値は <code>baseline</code> なので、多くの場合はわざわざ指定する必要がないはずです。もしどちらか一方のテキストが複数行にわたっても、ベースラインは最初の行をもとに決定されます。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/vertical-align-baseline-in-table-cell-2.png" />
<figcaption>Fig 2: フォントサイズの異なる要素に `display: table-cell` を指定した結果</figcaption>
</figure>
<p>もしこれと同じレイアウトを <code>display: table-cell</code> ではなくフロートなどでやろうとした場合、2 つの要素の <code>font-size</code> と <code>line-height</code> の値をもとにマージンやパディングを調整しなければならずかなり面倒なので、けっこううれしい挙動だと思うんですがどうでしょう。逆に、ベースラインではなくボックスの上端で揃えたい場合は <code>vertical-align: top</code> などのスタイルを追加する必要があります。</p>
<p>なんか書いてるうちにそんなん当たり前だろ何を今さらって言われそうな気がしてきましたが。</p>
画像置換のあれへの補足
2012-04-17T00:00:00Z
https://terkel.jp/archives/2012/04/css-image-replacement-2012/
<p>先月あたり、CSS による画像置換テクニックの話題がにわかに盛り上がりを見せていました。その経緯について <a href="http://d.hatena.ne.jp/ub-pnr/20120417/1334637257">まとりさんの記事</a> で紹介されていますが、僕からも簡単に補足してみます。</p>
<p>まず、よく知られた画像置換のテクニックとしていわゆる<strong>ファーク式</strong>がありました:</p>
<pre><code class="language-css">/* Phark method */
.ir {
height: 100px;
width: 400px;
background: url(image.png) no-repeat 0 0;
text-indent: -9999px;
}
</code></pre>
<p>このテクニックは長らく利用され続けてきましたが、その代替として、パフォーマンス面でより良いとされる <a href="http://scottkellum.com/">Scott Kellum</a> さんのテクニック (<strong>ケラム式</strong>) が <a href="http://www.zeldman.com/2012/03/01/replacing-the-9999px-hack-new-image-replacement/">Jeffrey Zeldman さんの記事</a> で紹介されました:</p>
<pre><code class="language-css">/* Kellum method */
.ir {
height: 100px;
width: 400px;
background: url(image.png) no-repeat 0 0;
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
}
</code></pre>
<p>そしてこのケラム式が <a href="https://github.com/h5bp/html5-boilerplate/issues/1005">HTML5 Boilerplate のチームによって検討される</a> 過程で <a href="http://nicolasgallagher.com/another-css-image-replacement-technique/">もうひとつのテクニック</a> (<strong>H5BP 式</strong>) が <a href="https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757c9e03dda4e463fb0d4db5a5f82d7">提案</a> されます:</p>
<pre><code class="language-css">/* H5BP method */
.ir {
height: 100px;
width: 400px;
background: url(image.png) no-repeat 0 0;
font: 0/0 a;
text-shadow: none;
color: transparent;
}
</code></pre>
<p>ただしこの H5BP 式は、<a href="http://hail2u.net/blog/webdesign/on-image-replacement.html">該当する要素で <code>em</code> 単位が使えない</a>、コードが短さを優先したためややトリッキーでわかりづらい、IE6 でテキストが消えずゴマ粒のように残ってしまう、などの欠点があります。</p>
<p>さらに、ケラム式と H5BP 式ともに <a href="http://jsfiddle.net/necolas/drHaR/2/">IE7 でバグ</a> があります。</p>
<p>そしてこれはとくに重要な点ですが、以上 3 つのテクニックはいずれも、CSS が有効かつ画像が無効 (読み込みに失敗した場合や非表示に設定している場合など) という状況では何も表示されなくなってしまうという、アクセシビリティ上の問題があります。</p>
<p>というわけで、疑似要素を利用した <a href="http://nicolasgallagher.com/css-image-replacement-with-pseudo-elements/">ナッシュ式</a> に IE7 以下向けのフォールバックとしてファーク式を加えたものが「比較的まし」な画像置換かな、というのが僕の見解です:</p>
<pre><code class="language-css">/* Nash method + fallback */
.ir {
height: 100px;
width: 400px;
overflow: hidden;
*text-indent: -9999px; /* for IE7/6 */
*background: url(image.png) no-repeat 0 0; /* for IE7/6 */
}
.ir:before {
content: url(image.png);
display: inline-block;
font-size: 0;
line-height: 0;
}
</code></pre>
<p>IE8 以上であれば CSS 有効/画像無効の場合でもテキストが表示されるのは大きいですね。ちなみに画像置換の歴史は <a href="http://css-tricks.com/examples/ImageReplacement/">CSS-Tricks の記事</a> に詳しいです。</p>
Browse Happy!
2012-05-19T00:00:00Z
https://terkel.jp/archives/2012/05/browse-happy/
<p>古いブラウザを使っているユーザに最新版へのアップグレードを呼びかけるプロジェクト、<a href="http://browsehappy.com/">Browse Happy</a> が日本語に翻訳されました。このプロジェクトは 2004 年に <a href="http://www.webstandards.org/2004/08/22/browsehappy-bad-grammar-for-a-good-cause/">The Web Standards Project (WaSP) が発足させ</a>、2005 年に <a href="http://wordpress.org/news/2005/06/browsing-happy/">WordPress.org が引き継いだ</a> という経緯のようですが、はっきり言ってここ数年はその存在がほとんど忘れられていたと思います。それが最近になって WordPress.org の翻訳チームによって各国語への翻訳がはじめられ、ちょっとだけ再注目されつつあります。現時点では約 20 の言語への翻訳が完了しているようです。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/browsehappy.png" />
</figure>
<p>サイトを見るとわかるとおり、WordPress.org が管理しているとは言えその内容は WordPress とは直接の関係がなく、広くウェブのユーザ全般にアピールするものです。そもそもブラウザにはいろいろあってユーザが自由に選べるということや、古いブラウザのセキュリティ上の問題などを周知し、さらに各ブラウザの最新版のダウンロードを促す、というコンテンツがひとつのページにまとまっていて、「とりあえずここ見て!」って言えて便利だし、じつに有意義なプロジェクトだと思います。</p>
<p>で、このサイトをユーザに対して周知したいわけですが、実際のところ周知したいのは古い IE のユーザということになると思うので、条件コメントを使ってあるバージョン以下の IE の場合にメッセージを表示する、という方法が考えられます。たとえば <a href="http://html5boilerplate.com/">HTML5 Boilerplate</a> のテンプレートでは、以下のように IE7 未満のユーザ向けに Google Chrome Frame へのリンクとあわせて表示されるようになっています:</p>
<pre><code class="language-html"><!--[if lt IE 7]>
<p class=chromeframe>Your browser is <em>ancient!</em> <a href="http://browsehappy.com/">Upgrade to a different browser</a> or <a href="http://www.google.com/chromeframe/?redirect=true">install Google Chrome Frame</a> to experience this site.</p>
<![endif]-->
</code></pre>
<p>アップグレードを促す前にまず「あなたの使っているブラウザは古いですよ」ということを伝えなければいけないわけですが、この Your browser is <em>ancient!</em> をそのまま日本語にしてしまうとややきついので、もう少しやんわりと、かつ明確に伝わるものにしたいところです。また想定されるユーザ層などによってセキュリティやパフォーマンスなど訴求したいポイントも異なると思うので、やはりプロジェクトごとに文言は検討すべきでしょう。ちなみにこのサイトでは IE8 未満を対象にメッセージを表示するようにしています:</p>
<pre><code class="language-html"><!--[if lt IE 8]>
<p class="ie-prompt" style="background-color:#FBFB78;font-size:87.5%;margin:0;padding:1em;">お使いのブラウザはバージョンが古いため、サイトを快適にご利用いただけないかもしれません。<a href="http://browsehappy.com/">最新のブラウザにアップグレード</a> するか、<a href="http://www.google.com/chromeframe/?redirect=true">Google Chrome Frame をインストール</a> してください。</p>
<![endif]-->
</code></pre>
<p>さて、こういった施策はやはりそれなりの規模のクライアント・ワークで実施してこそ効果が期待できるものです。とは言えコンテンツとは直接関係のないものを加えることを製作者側から提案するのは気が引ける、ということもあると思います。しかしながら、古いブラウザのシェアを下げたいというのは製作者側の都合だけではなく、クライアントにとっても自社のサイトをよりリッチに快適に利用してもらえる機会が増えるということにつながり、たしかなアドヴァンテージになるはずです。サポートするブラウザを検討すると同時に、こういった施策の導入も積極的に検討していきたいところです。</p>
CSS ショートハンド・プロパティの問題点
2012-06-14T00:00:00Z
https://terkel.jp/archives/2012/06/problem-with-css-shorthand-propaties/
<p>CSS のショートハンド・プロパティは複数のプロパティを一括して宣言できますが、メンテナンスしづらくなったり、思わぬバグの原因になったりすることがあります。そしてその問題が見えにくいことがさらに面倒です。<a href="http://www.w3.org/TR/CSS2/fonts.html#font-shorthand"><code>font</code> プロパティ</a> を例に、実際にどのような弊害があるのか検討してみます。</p>
<pre><code class="language-css">html {
font: 87.5%/1.5 "Georgia", serif;
}
</code></pre>
<p>このショートハンドは一見すると次の 3 つのプロパティをひとまとめにしたものに見えます。</p>
<pre><code class="language-css">html {
font-size: 87.5%;
line-height: 1.5;
font-family: "Georgia", serif;
}
</code></pre>
<p>しかし、<code>font</code> プロパティは上記のほか <code>font-style</code>、<code>font-variant</code>、<code>font-weight</code> プロパティも指定でき、そして省略されたプロパティには初期値が割り当てられます。つまり、実際には以下のように宣言されていることになります。</p>
<pre><code class="language-css">html {
font-style: normal;
font-variant: normal;
font-weight: normal;
font-size: 87.5%;
line-height: 1.5;
font-family: "Georgia", serif;
}
</code></pre>
<p>さて、このショートハンドで書かれたコードをチームで共有する場合を考えてみます。ひょっとするとこのコードを書いた人は、明示されているプロパティのみを宣言したかったのであり、プロパティの省略とそれに伴う暗黙の初期化については意図していなかったのかもしれません。しかしコードを読む人にとってはそこに記述されているコードがすべてなので、それはすべて意図的なものと捉えるしかありません。つまり、ここでは <code>font-style</code>、<code>font-variant</code>、<code>font-weight</code> の値として <code>normal</code> を指定する必要がある、と読むことになるわけです。こうしてコードに対する認識の食い違いが生まれ、本来は必要のないスタイルが定義され、そして最悪の場合にはバグを生むことになります。</p>
<p>ただ実際のところ、<code>html</code> や <code>body</code> 要素に対して <code>font</code> プロパティを宣言するのはいわゆるリセットやノーマライズ的な意味での場合が多いので、上記の例が問題になることはあまりないかもしれません。しかしそれはレンダリング結果にたまたま影響がないだけで、やはり表面化していない問題が潜んでいるのだと思います。</p>
<p>もうひとつの例として、<a href="http://nicolasgallagher.com/another-css-image-replacement-technique/">HTML5 Boilerplate の画像置換テクニック</a> のコードを見てみます。</p>
<pre><code class="language-css">.ir {
font: 0/0 a;
text-shadow: none;
color: transparent;
}
</code></pre>
<p>この <code>font</code> プロパティのうち、ここでのスタイルの要件を満たすために必要なのは <code>font-size</code> と <code>line-height</code> のみです。<code>font-family</code> は必要ないのですが、構文上省略できないため、せめてコードを短くしたいという理由で書体名ではなく <code>a</code> という文字列が宣言されています。また省略された 3 つのプロパティに初期値を指定する必要もありません。しかしこのようにトリッキーな記述をされると、あとから編集する人が手を入れることが難しく、内容が検討されないまま「おまじない」としてコピペされ続けてどこかで思わぬ弊害を生んだり、逆に検討しようとすると無駄な時間がかかったりする可能性があります。こういったハック寄りのテクニックではとくに、必要最低限の記述にとどめるべきでしょう。</p>
<p><code>font</code> プロパティのほかにも、たとえばブロックボックスを親要素の左右中央に配置するスニペット <code>margin: 0 auto;</code> は上下まで指定する必要があるか検討すべきだし、<code>background</code> プロパティなんかはいい加減に書いてると思わぬ結果を招くことがよくあるので、やはりショートハンド全般に注意が必要です。</p>
<p>というわけで、ショートハンド・プロパティはコードが短くすっきりする反面、余分なプロパティを宣言してしまうことがあり、かつそれが意図されたものかどうかわかりづらくなってしまう、という問題があります。やはりその都度必要なプロパティだけを宣言するよう心掛けるのが良いのではないでしょうか。CSS の場合、そういった余分な宣言があっても結果的に問題が表面化しないということも多いので、なかなか意識するのが難しいところではありますが、このあたりを考慮できると、将来にわたって安全で運用しやすい CSS に一歩近づけるように思います。</p>
スクリプトが無効の場合のスタイル
2012-07-01T00:00:00Z
https://terkel.jp/archives/2012/07/styles-for-noscript/
<p>たとえばホームページのビジュアル要素など、いったん非表示にしておいてスクリプトでふわっとフェードインさせたい、みたいなことはよくある。そのとき非表示にする操作も JavaScript にやらせると一瞬見えてしまうことがあるので CSS で非表示化したいが、それだとスクリプトが無効の場合に何も表示されなくなってしまう… というような、スクリプトによる操作を前提にしたスタイルのフォールバックをどうするかという問題。</p>
<p>ここのところよく使っていたのは、JavaScript で <code>html</code> 要素の <code>class</code> 属性を操作し、それをもとに CSS を書くという手。Modernizr でも使われてるあれ。</p>
<pre><code class="language-javascript">(function () {
var root = document.documentElement;
root.className = root.className.replace(/\bno[-_]?js\b/ig, '') + ' js';
})();
</code></pre>
<p>こんなようなコードを <code>head</code> 内で読み込んでおけば、スクリプトが有効の場合には <code>html</code> 要素の <code>no-js</code> (または <code>no_js</code> や <code>noJS</code>) クラスが削除されて <code>js</code> クラスが付与されるので、これをもとに CSS のルールセットを分岐させればいい。</p>
<pre><code class="language-css">.foo { ... }
.js .foo { display: none; }
</code></pre>
<p>またはこう:</p>
<pre><code class="language-css">.foo { display: none; ... }
.no-js .foo { display: block; }
</code></pre>
<p>ちなみに Sass 3.2 の placeholder (<code>%</code>) セレクタを使うとこう書けて便利:</p>
<pre><code class="language-scss">.js %js-hidden { display: none; }
.foo { @extend %js-hidden; ... }
</code></pre>
<p>このスクリプトは <code>body</code> の最後に置いたのでは遅いので、<code>head</code> に置くほうがいい。なお HTML 4.01 や XHTML 1.0 では <code>html</code> 要素は <code>class</code> 属性を持てない (動くけど)。</p>
<p>そしてもうひとつの手として最近思いついたのが、<code>head</code> 内で <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#the-noscript-element"><code>noscript</code> 要素</a> を使って別のスタイルシートを読み込む方法。</p>
<pre><code class="language-html"><head>
...
<link rel="stylesheet" href="/css/style.css">
<noscript>
<link rel="stylesheet" href="/css/noscript.css">
</noscript>
...
</head>
</code></pre>
<p>デフォルトのスタイルシートではスクリプト有効の前提で書いて、無効の場合のスタイルを別ファイルに書けばいい。ひとつの要素に対して複数のファイルを編集しなきゃいけないけど、スニペットに依存しない点は良いと思う。</p>
<p>なお HTML 4.01 や XHTML 1.0 では <code>head</code> 内に <code>noscript</code> を置けないし、<code>noscript</code> 内に <code>link</code> を置けない。HTML5 Rocks!</p>
最近試している Sass の書き方
2012-07-12T00:00:00Z
https://terkel.jp/archives/2012/07/my-sass-way/
<p>最近、Sass 3.2 (プレリリース版) を使って新しい書き方を模索しているんですが、その方向性に自信が持てないので、ちょっとさらしてみて反応を見ようという試みです。</p>
<p>まず基本的な方向として、以下のような考え方を参考にしています:</p>
<ul>
<li><a href="http://alpha.mixi.co.jp/2012/10791/">なぜ @kotarok さんは mixin より extend を推すのか - mixi Engineers' Blog</a></li>
<li><a href="http://hail2u.net/blog/webdesign/sass-identity.html">Sassの存在意義 - Weblog - hail2u.net</a></li>
<li><a href="http://hail2u.net/blog/webdesign/sass-identity-follow-up.html">Sassの存在意義への補足 - Weblog - hail2u.net</a></li>
</ul>
<p>マークアップに合わせてスタイルを書くのでもなく、スタイルに合わせてマークアップするのでもない、それぞれを適切に書いた上で結びつける、というようなことを僕なりにやろうとしています。スタイルの実装と、それらを利用するためのインターフェイスを分離する、みたいなイメージで、具体的には Placeholder (<code>%</code>) セレクタと <code>@extend</code> を中心にしたものです。</p>
<pre><code class="language-scss">// _breadcrumbs.scss
%breadcrumbs {
backgrund-color: $palegray;
}
%breadcrumbs-link {
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
%breadcrumbs-separator {
color: $gray;
}
%breadcrumbs-current {
font-weight: bold;
}
</code></pre>
<p>例としてパンくずナビゲーションのスタイルを考えてみます。まずこのように <code>%</code> セレクタを使ってスタイルをパーツに分解して書き下ろします。このとき、マークアップの要素タイプやクラス名や入れ子構造などは考えず、ただ必要なスタイルに名前をつけていく感じです。これをたとえば <code>_breadcrumbs.scss</code> というファイルにしておきます。</p>
<p><code>_breadcrumbs.scss</code> はスタイルを定義しているだけで、それだけでは CSS を生成しません。CSS を生成する Sass ファイルとして <code>style.scss</code> を用意し、<code>_breadcrumbs.scss</code> を <code>@import</code> し、そしてマークアップとスタイルを <code>@extend</code> を使ってつなぎ合わせます。</p>
<pre><code class="language-html"><div class="crumbs-nav">
<a href="/">Home</a> <span class="separator">›</span>
<a href="/artist">Artist</a> <span class="separator">›</span>
<em>Bobby Womack</em>
</div>
</code></pre>
<p>マークアップがこのようなものだったとします。このとき、マークアップは <code>_breadcrumbs.scss</code> のスタイル定義を気にする必要はなく、(ひとまず) 妥当なマークアップであれば良いです。そして <code>style.scss</code> では以下のように書きます。</p>
<pre><code class="language-scss">// style.scss
@import "breadcrumbs";
.crumbs-nav {
@extend %breadcrumbs;
a {
@extend %breadcrumbs-link;
}
.separator {
@extend %breadcrumbs-separator;
}
em {
@extend %breadcrumbs-current;
}
}
</code></pre>
<p>スタイル定義はマークアップに依存しないので、たとえばパンくずが <code>div.crumbs-nav</code> ではなく <code>ol</code> だったり <code>#pankuzu</code> だったりしても、手を入れるのは <code>style.scss</code> の一部だけです (とは言え、スタイルを適用するのに要素が足りなかったり、スタイルの調整が必要な場合もあります)。この調子であらゆるスタイルをそれぞれモジュールとして定義し、<code>style.scss</code> 上でそれらをインクルードし、マークアップと結びつけていきます。その結果、CSS が 1 行も書かれていない <code>style.scss</code> と多数の Sass モジュールが出来上がります。</p>
<p>こうするとまずスタイルを定義する人とマークアップする人の分業がやりやすくなるはずというのがありますが、なによりマークアップとスタイルがそれぞれを束縛し合ったまま足踏みしているような状況から抜け出すきっかけになるのでは、というのが大きいです。</p>
<p>加えて、「このスタイルは汎用的なものか」「どこかで使い回す可能性があるか」みたいなことをいちいち考えず、すべてのスタイルをフラットなモジュールとして捉えられるというのも特徴です。これは良いことなのかちょっと微妙とも思いますが。</p>
<p>これでマークアップ、スタイル、そして両者を結びつける役割が分離できてめでたしめでたし、と言いたいところですが、スタイル定義を一切含まず、ひたすら <code>@import</code> と <code>@extend</code> を繰り返すだけのファイルを見ていると、なんだか遠いところに来てしまったような気がして言い知れぬ不安を覚えます。とくにひとりでフロントエンドすべてを面倒見るような規模の場合、このやり方だとメリットが見えにくいというか、実際に僕が今ひとりでこうやっていて、いったいどこに向かってるんだろうかという気持ちになったのでこの記事を書いています。</p>
<p>あとファイルをどんな感じで分割するか、<code>@import</code> はどうやるのが良いか (ファイルの先頭にまとめてかそのつどか) といったあたりも悩むところです。どこに何を書いたかすぐに分からなくなるし。</p>
<p>ちなみに、実際にこのやり方で書いてみるとふつうの CSS の 3 倍手間がかかるし、3 倍頭を使いますが、それはむしろ良いことだと考えているというか、そういうものだという理解です。「ウェブ標準」が流行ったときに structure と presentation の分離ということが盛んに言われましたが、結局のところただ HTML と CSS のファイルが分離できただけでは、という気がしていた者としては、ある種の手応えはあるし、そのうち何かが見えてくるはず、とは思います。</p>
<p>皆さん、どんなふうに書いてますか?</p>
@media と @extend
2012-07-13T00:00:00Z
https://terkel.jp/archives/2012/07/at-media-and-at-extend/
<p>Sass で <code>@extend</code> を CSS の <code>@media</code> と絡めて使おうとすると、組み合わせによってはエラーや警告が出てしまうので注意が必要。</p>
<pre><code class="language-scss">%foo {
color: red;
}
.bar {
@media screen and (min-width: 768px) {
@extend %foo; // ERROR!
margin: auto;
}
}
</code></pre>
<p>スクリーンの幅が 768px 以上のときは <code>.bar</code> に <code>%foo</code> を継承させる、という意図だけど、これは “Extend directives may only be used within rules.” というエラーが出て通らず、ファイルのコンパイルが丸ごと失敗してしまう。</p>
<pre><code class="language-scss">%foo {
color: red;
}
@media screen and (min-width: 768px) {
.bar {
@extend %foo; // WARNING
margin: auto;
}
}
</code></pre>
<p>こうやって <code>@media</code> を外側に持ってくるとエラーにはならないけど、警告が出て <code>@extend</code> が評価されない (そのほかの宣言は大丈夫)。メッセージは “@extending an outer selector from within @media is deprecated. You may only @extend selectors within the same directive. This will be an error in Sass 3.3. It can only work once @extend is supported natively in the browser.” と言っていて、いまは警告で済むけど次はない、ってことらしい。</p>
<p><code>@media</code> の内側から外のセレクタを <code>@extend</code> することはできないようなので、必要であれば <code>@extend</code> される側のセレクタの中に <code>@media</code> を宣言することになる。</p>
<pre><code class="language-scss">%foo {
@media screen and (min-width: 768px) {
color: red;
}
}
.bar {
@extend %foo; // Works!
}
</code></pre>
<p>ただ、このやり方だと <a href="https://terkel.jp/archives/2012/07/my-sass-way/">スタイルを細切れにして <code>@extend</code> しまくる</a> 設計の場合に継承元セレクタごとにいちいちクエリを書く必要があり、出力結果も <code>@media</code> まみれのちょっと悲惨なものになる。<code>@media</code> と絡むところでは無理に <code>@extend</code> しようとせず、素の CSS に近い感じで書くのがいいのかもしれない。とくに最近はメデイアクエリでスタイルを細かく分岐させることも多いと思うので気をつけたい。ていうか気をつけます。</p>
NIR ミックスイン
2012-07-20T00:00:00Z
https://terkel.jp/archives/2012/07/sass-mixin-for-nir/
<p><a href="http://nicolasgallagher.com/css-image-replacement-with-pseudo-elements/">NIR (Nash Image Replacement)</a> をわりとよく使うようになったので、最近は Sass のミックスインにしています:</p>
<pre><code class="language-scss">@mixin nir ($src, $w: auto, $h: auto, $x: 0, $y: 0) {
overflow: hidden;
@if ($w != auto) {
width: $w;
height: $h;
}
*text-indent: -9999px;
*background-image: url($src);
*background-repeat: no-repeat;
@if ($x != 0) {
*background-position: $x $y;
}
&:before {
content: url($src);
display: inline-block;
font-size: 0;
line-height: 0;
@if ($x != 0) {
margin-left: $x;
margin-top: $y;
}
}
}
@mixin nir-position ($x, $y) {
&:before {
margin-left: $x;
margin-top: $y;
}
*background-position: $x $y;
}
</code></pre>
<p>もっともシンプルな使い方はスプライトではなく単独の画像を使う場合で、画像のパスと幅と高さを <code>nir()</code> に渡すだけ。</p>
<pre><code class="language-scss">.logo {
@include nir("/img/logo.png", 128px, 36px);
}
</code></pre>
<p>結果こうなります:</p>
<pre><code class="language-css">.logo {
overflow: hidden;
width: 128px;
height: 36px;
*text-indent: -9999px;
*background-image: url("/img/logo.png");
*background-repeat: no-repeat;
}
.logo:before {
content: url("/img/sprite.png");
display: inline-block;
font-size: 0;
line-height: 0;
}
</code></pre>
<p>スプライト画像の場合は座標の指定も必要です。たとえばソーシャル系のリンクをロールオーバーつきのアイコンで表現するにはこんな感じ:</p>
<pre><code class="language-scss">.social-links {
a {
display: inline-block;
@include nir("/img/sprite.png", 32px, 32px);
&[href^="https://twitter.com/"] {
@include nir-position(-180px, -190px);
&:hover {
@include nir-position(-180px, -230px);
}
}
&[href^="http://www.facebook.com/"] {
@include nir-position(-220px, -190px);
&:hover {
@include nir-position(-220px, -230px);
}
}
}
}
</code></pre>
<p>まず <code>a</code> 要素に対して <code>nir()</code> でスプライト画像のパスとアイコンのサイズを指定して、次いでリンク先や状態ごとに各アイコンの座標を <code>nir-position()</code> で個別に指定しています。</p>
<pre><code class="language-css">.social-links a {
display: inline-block;
overflow: hidden;
width: 32px;
height: 32px;
*text-indent: -9999px;
*background-image: url("/img/sprite.png");
*background-repeat: no-repeat;
}
.social-links a[href^="https://twitter.com/"] {
*background-position: -180px -190px;
}
.social-links a[href^="https://twitter.com/"]:before {
margin-left: -180px; margin-top: -190px;
}
.social-links a[href^="https://twitter.com/"]:hover {
*background-position: -180px -230px;
}
.social-links a[href^="https://twitter.com/"]:hover:before {
margin-left: -180px; margin-top: -230px;
}
.social-links a[href^="http://www.facebook.com/"] {
*background-position: -220px -190px;
}
.social-links a[href^="http://www.facebook.com/"]:before {
margin-left: -220px; margin-top: -190px;
}
.social-links a[href^="http://www.facebook.com/"]:hover {
*background-position: -220px -230px;
}
.social-links a[href^="http://www.facebook.com/"]:hover:before {
margin-left: -220px; margin-top: -230px;
}
</code></pre>
<p>擬似要素なので Firefox 以外でアニメーションできないとかそもそもコンパイル結果のコードがうざいとかいろいろありますが、ちょっとしたアイコンやなんかにはやっぱり便利なのでけっこう重宝します。</p>
jQuery Image Rollover
2012-08-04T00:00:00Z
https://terkel.jp/archives/2012/08/jquery-image-rollover/
<p><a href="http://events.jquery.org/2012/sf/">jQuery Conference</a> で発表されたらしい、<a href="http://dougneiner.com/">Douglas Neiner</a> さんの <a href="http://code.dougneiner.com/presentations/contextual-jquery-3/">Contextual jQuery 3</a> というスライドが興味深かったので、参考にしながらためしに画像ロールオーバー (マウスが乗っかると画像が差し替わるあれ) の jQuery プラグインを書いてみました。ワーク・イン・プログレス。</p>
<ul>
<li><a href="https://github.com/terkel/jquery-imagerollover">terkel/jquery-imagerollover · GitHub</a></li>
</ul>
<p>この手のスクリプトでよくあるのが、<code>$(document).ready()</code> のタイミングで各画像に <code>.each()</code> で処理をバインドするというやり方で、僕もその方法で書いたプラグインを使っていました。たとえば <code>.rollover</code> というクラスを持った画像を対象にする場合、だいたいこんな感じです:</p>
<pre><code class="language-javascript">$(document).ready(function () {
$('.rollover').each(function () {
...
$(this).bind({
mouseenter: function () {
// ロールオーバー処理
},
mouseleave: function () {
// デフォルトに戻す処理
}
});
});
});
</code></pre>
<p>しかし、このやり方だと <code>.rollover</code> が 100 個あれば 100 個の要素を検索して 100 回の初期化がおこなわれることになります。これを <a href="http://api.jquery.com/on/"><code>.on()</code></a> を使って以下のように書き換え、1 回の初期化で済ますようにしました:</p>
<pre><code class="language-javascript">$(document).on('mouseenter mouseleave', '.rollover', function (event) {
...
if (event.type === 'mouseenter') {
// ロールオーバー処理
} else {
// デフォルトに戻す処理
}
});
</code></pre>
<p>ここでは説明のためかなり大雑把に書いていますが、基本的にこんな感じです。加えて、クラス名ではなく画像ファイル名の接尾辞によって要素を選択するようにしたり、<code>mouseenter/mouseleave</code> と同時に <code>focusin/focusout</code> も対象にしたり、ロールオーバー時の画像をプリロードして各画像に <code>.data()</code> で持たせたり、イベントを重複して登録しないようにチェックを入れたりとかしています。</p>
<p>jQuery のプラグインというといつも決まった書式でばかり書いていたので、なれない書き方でかなり苦労している上、いまいち内容に自信が持てませんが、個人的に苦手なイベント系の理解が少しだけ深まったような気がします。</p>
リンクのスタイルを変えた
2012-08-05T00:00:00Z
https://terkel.jp/archives/2012/08/changed-link-style/
<p>このサイトの本文などのリンクのスタイルを少し変えました。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/link-style-new.png" />
</figure>
<p>いままではボールドで前景色は明るいブルー (<code>#0080ff</code>)、<code>:hover</code> で <code>text-decoration: underline</code> というスタイルだったのを、ウェイトはノーマル、前景色を暗く (<code>#00509f</code>) し、<code>border-bottom</code> で薄いグレーの下線、そして <code>:hover</code> 時に前景とボーダーを明るいブルーに、というスタイルにしました。</p>
<pre><code class="language-css">[role="complementary"] a,
.credits a,
.mainContentBody a {
border-bottom: 1px solid #d9ddda;
color: #00509f;
text-decoration: none;
}
[role="complementary"] a:hover,
.credits a:hover,
.mainContentBody a:hover {
border-bottom-color: #0080ff;
color: #0080ff;
}
</code></pre>
<p>CSS としては上記のような感じですが、これだと記事中の画像にリンクがある場合に不要なボーダーができてしまうので、<code>figure > a { border-bottom-width: 0; }</code> みたいに上書きしてます。このへんもっと上手く書きたいんですが地味に難しいですね。</p>
<p>変えたのは前景色の明るさがうるさく感じるようになったのがきっかけですが、たとえば Android の和文フォントがボールドにならないなど、環境によって異なるフォントのスタイルになるべく依存しないほうがいいな、というのもあります。</p>
mustache と lscache
2012-08-07T00:00:00Z
https://terkel.jp/archives/2012/08/mustache-and-lscache/
<p>このサイトでは <a href="http://www.last.fm/api">Last.fm API</a> からデータを取ってきて僕が最近よく聴いてるアルバムを表示する、っていうのをやってるんですが、このスクリプトを <a href="http://mustache.github.com/"><strong>mustache</strong></a> と <a href="https://github.com/pamelafox/lscache"><strong>lscache</strong></a> というライブラリを組み合わせて書き直してみたところけっこういい感じになったので、簡単に紹介してみます。</p>
<p>mustache は様々な言語で利用できるテンプレート・エンジンで、ここで使っているのはその JavaScript 実装である <a href="https://github.com/janl/mustache.js">mustache.js</a> です。導入や使い方については <a href="http://blog.mach3.jp/2010/10/mustache-template-engine.html">まっはさんの記事</a> がわかりやすくて参考になりました。</p>
<p>まず API から JSON データを取得し、これを整形して mustache 用のオブジェクトにします:</p>
<pre><code class="language-javascript">var data = {
heading: 'This Week’s Top 10',
albums: [
{
name: 'Solaris – Cliff Martinez',
url: 'http://www.last.fm/music/Cliff+Martinez/Solaris',
image: 'http://userserve-ak.last.fm/serve/64s/43127407.png'
},
{
name: 'Marquee Moon – Television',
url: 'http://www.last.fm/music/Television/Marquee+Moon',
image: 'http://userserve-ak.last.fm/serve/64s/76164550.png'
},
...
]
};
</code></pre>
<p>そして mustache テンプレートを準備:</p>
<pre><code class="language-javascript">var template =
'<h2>{{heading}}</h2>' +
'<ol>' +
'{{#albums}}<li>' +
'<a href="{{url}}">' +
'<img src="{{image}}" alt="{{name}}">' +
'</a>' +
'</li>{{/albums}}' +
'</ol>';
</code></pre>
<p>テンプレートはこのように文字列で定義します。<code>{{key}}</code> っていうのが mustache タグで、データの入る部分です。<code>{{#albums}}</code> から <code>{{/albums}}</code> まではループですね。このテンプレートとデータを <code>Mustache.render()</code> に渡せば HTML を生成してくれるので、これを DOM に挿入すれば完成です:</p>
<pre><code class="language-javascript">var html = Mustache.render(template, data);
$('#container').html(html);
</code></pre>
<p>で、このもとになる JSON データを毎回 API から取得するのは無駄なので、一度 HTML を作成したらそれをローカルにキャッシュして再利用しよう、というのが次のステップです。そこで lscache を使います。lscache は <a href="http://www.w3.org/TR/webstorage/#the-localstorage-attribute"><code>localStorage</code></a> によるデータの取り扱いを簡単にしてくれるライブラリです。</p>
<pre><code class="language-javascript">lscache.set('lastfmHTML', html, 60 * 24);
</code></pre>
<p>このように <code>lscache.set()</code> メソッドでデータをローカルに保存します。データとして渡せるのは文字列またはオブジェクトです。ここでは <code>'lastfmHTML'</code> というキーに先ほど生成した HTML 文字列を保存しています。データの保持期間が分単位の数値で指定でき、この例では 24 時間を指定しています。</p>
<p>このキャッシュされたデータを API 呼び出しの前にチェックして、データがあればそのまま使い、なければ API からデータを取得して HTML を生成してキャッシュ、というかたちにします。キャッシュされたデータを取得するには <code>lscache.get(key)</code> です:</p>
<pre><code class="language-javascript">var cache = lscache.get('lastfmHTML');
if (cache) {
$('#container').html(cache);
} else {
// データ取得、HTML 生成、キャッシュ
...
$('#container').html(html);
lscache.set('lastfmHTML', html, 60 * 24);
}
</code></pre>
<p>コード例がかなり雑ですが、だいたいこんな流れです。どちらのライブラリもシンプルで直感的に扱えます。</p>
<p><code>localStorage</code> については、はじめて触ったけど簡単だしすげーいいじゃんっていうのと同時に、いままで考えたことのない領域なのでどう使っていけばいいのかいまいちわからんというか、<a href="https://dev.mozilla.jp/2012/03/there-is-no-simple-solution-for-local-storage/">問題提起</a> されたりもしてるみたいだし慎重になっちゃいますねー、という感じですね (歯切れ悪い…)。</p>
Google Web Fonts が IE で適切に読み込まれない
2012-09-03T00:00:00Z
https://terkel.jp/archives/2012/09/google-web-fonts-ie-bug/
<p><a href="http://www.google.com/webfonts"><strong>Google Web Fonts</strong></a> のウェブフォントには IE 8 以下でちょっとしたバグがある。このサイトでもずっと放置してたのをようやく直しました…</p>
<pre><code class="language-html"><head>
...
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700">
...
</head>
</code></pre>
<p>たとえば上記のように書けば、<a href="http://www.google.com/webfonts/specimen/Open+Sans">Open Sans</a> のウェイト 400 (ノーマル) と 700 (ボールド)、そしてそれぞれのイタリックの計 4 書体が読み込まれる。あとは CSS でふつうに <code>h1 { font-family: "Open Sans", sans-serif; font-weight: bold; }</code> みたいな感じで指定が可能。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/google-web-fonts-ie9.png" />
<figcaption>Fig 1: Open Sans on IE 9</figcaption>
</figure>
<p>これは IE9 でのレンダリング例。小文字の a や e あたりを見るとわかるとおり、ボールドやイタリックは機械的に太らせたり傾けたりしたものではなく、それぞれデザインされた字形を持っている。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/google-web-fonts-ie8.png" />
<figcaption>Fig 2: Open Sans on IE 8</figcaption>
</figure>
<p>しかし同じ CSS でも IE 8 で見ると、イタリックはノーマルをそのまま傾けただけ、ボールドも二重にしたノーマルをずらして重ねたような、いわゆる <a href="http://www.alistapart.com/articles/say-no-to-faux-bold/">にせのボールドとイタリック</a> になってしまう。利用できるはずの「本物」のイタリックやボールドが呼び出されず、ノーマルしか使えないという状態。IE 7 と 6 も同様。</p>
<p>この問題はけっこう前から話題になっていたらしくて、解決策もある。</p>
<ul>
<li><a href="http://code.google.com/p/googlefontdirectory/issues/detail?id=9">Issue 9 - googlefontdirectory - Loading both BOLD and REGULAR font in IE8 does not work - Download Google Web Fonts - Google Project Hosting</a></li>
<li><a href="http://www.smashingmagazine.com/2012/07/11/avoiding-faux-weights-styles-google-web-fonts/">Avoiding Faux Weights And Styles With Google Web Fonts | Smashing Magazine</a></li>
</ul>
<p>複数のウェイトやスタイルをひとつの <code>link</code> 要素で指定するのではなく、以下のように個別の <code>link</code> に分割してリクエストすると、IE 8 以下でもそれぞれちゃんと使える。</p>
<pre><code class="language-html"><head>
...
<link href="http://fonts.googleapis.com/css?family=Open+Sans:400" rel="stylesheet">
<link href="http://fonts.googleapis.com/css?family=Open+Sans:400italic" rel="stylesheet">
<link href="http://fonts.googleapis.com/css?family=Open+Sans:700" rel="stylesheet">
<link href="http://fonts.googleapis.com/css?family=Open+Sans:700italic" rel="stylesheet">
...
</head>
</code></pre>
<p>ただリクエストが増えてしまうのは嬉しくないので、いったん一括で指定したあと、問題のある IE 8 以下を対象に条件コメントで分岐させる、という回避策がとりあえずは有効。</p>
<pre><code class="language-html"><head>
...
<link href="http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700" rel="stylesheet">
<!--[if lt IE 9]>
<link href="http://fonts.googleapis.com/css?family=Open+Sans:400italic" rel="stylesheet">
<link href="http://fonts.googleapis.com/css?family=Open+Sans:700" rel="stylesheet">
<link href="http://fonts.googleapis.com/css?family=Open+Sans:700italic" rel="stylesheet">
<![endif]-->
...
</head>
</code></pre>
<p>上記の例では、IE 8 以下でも最初の <code>link</code> で 400 は有効になっているので、残りの 3 書体を改めて個別に指定している。同じファミリーの複数のウェイトとスタイルを一度にリクエストした場合に起きる問題なので、複数のファミリーを指定する場合や、ノーマルを使用せずボールドやイタリックのみの場合など、組み合わせによって必要な記述が変わってくる。検証しましょう。</p>
<pre><code class="language-html"><head>
...
<link href="http://fonts.googleapis.com/css?family=Crimson+Text:700|Open+Sans:400,700" rel="stylesheet">
<!--[if lt IE 9]>
<link href="http://fonts.googleapis.com/css?family=Open+Sans:700" rel="stylesheet">
<![endif]-->
...
</head>
</code></pre>
<p><code>link</code> じゃなく <code>@import</code> を使った場合も同じバグがあり、やはりリクエストを分割することで回避できる。このサイトでは管理のしやすさから <code>@import</code> を使ってたんだけど、これを機に <code>link</code> に変更した。</p>
text-rendering: optimizeLegibility
2012-09-04T00:00:00Z
https://terkel.jp/archives/2012/09/text-rendering-optimizelegibility/
<p>WordPress の次期デフォルト・テーマ、<a href="http://theme.wordpress.com/themes/twentytwelve/">Twenty Twelve</a> の CSS を見ていたら、<code>body</code> 要素に <code>text-rendering: optimizeLegibility</code> という見慣れないプロパティが指定されていたのでちょっと調べてみました。</p>
<ul>
<li><a href="http://www.w3.org/TR/SVG11/painting.html#TextRenderingProperty">The ‘text-rendering’ property – SVG 1.1 (Second Edition)</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/CSS/text-rendering">text-rendering | Mozilla Developer Network</a></li>
<li><a href="http://aestheticallyloyal.com/public/optimize-legibility/">Cross-browser kerning-pairs & ligatures</a></li>
<li><a href="http://trentwalton.com/2010/06/29/css-text-rendering/">CSS Text-Rendering | Trent Walton</a></li>
</ul>
<p><strong><code>text-rendering</code></strong> プロパティは CSS ではなく SVG の仕様に定義されています。現在のところ利用できるブラウザは Firefox、Chrome、Safari。指定できる値は</p>
<ul>
<li><code>auto</code> (初期値)</li>
<li><code>optimizeSpeed</code></li>
<li><code>optimizeLegibility</code></li>
<li><code>geometricPrecision</code></li>
<li><code>inherit</code></li>
</ul>
<p>ですが、現状では <code>auto</code> や <code>geometricPrecision</code> の挙動がブラウザによって異なるようです。</p>
<p>このうち <code>optimizeSpeed</code> と <code>geometricPrecision</code> は違いがよくわからなかったのですが、<strong><code>optimizeLegibility</code></strong> はカーニングと合字 (リガチャ) をうまい具合に調整してくれるもので、現実世界でもけっこう使えそうです。ただフォントがカーニングや合字のデータを持っていなければ指定しても何も起こりません。和文フォントでは、メイリオと MS 系ゴシック・明朝は効果がないですが、ヒラギノ角ゴ・明朝は軽くカーニングが調整されます。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/text-rendering-optimizelegibility-3.png" />
<figcaption>ヒラギノ角ゴ ProN における `text-rendering: optimizeLegibility` の効果の比較。上から無効時、有効時、およびそれらを重ねたもの (赤が有効時)。検証環境は Mac OS X 10.6 + Chrome 21</figcaption>
</figure>
<p>上記の記事によると、Firefox では <code>font-size</code> が 20px 以上 (一般的な見出しを想定していると思われる) の場合はデフォルトで <code>optimizeLegibility</code> が適用されるとのことですが、Firefox 15 で見る限りどうもサイズに関係なくそうなってるみたいです。また環境やほかのプロパティとの食い合わせによっては不具合があるとの報告もありますが、ざっと確認したところこれといった問題はなさそうだったので、このサイトでも採用してみることにしました。</p>
<pre><code class="language-css">html {
font-family: "Open Sans", "Hiragino Kaku Gothic ProN", "Meiryo", sans-serif;
text-rendering: optimizeLegibility;
...
}
</code></pre>
Normalize.css をそのまま使うことにした
2012-09-06T00:00:00Z
https://terkel.jp/archives/2012/09/using-normalize-css/
<p><strong><a href="http://necolas.github.com/normalize.css/">Normalize.css</a></strong> は僕もプロジェクトによって部分的に取り入れてたんだけど、v2.0 になったのをきっかけに今後はどのプロジェクトでもまるごと採用していこうかと考えてる。たとえばこのサイトでは今までどうやっていたかというと、</p>
<pre><code class="language-scss">@mixin normalize-html {
font-family: sans-serif;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
@mixin normalize-body {
margin: 0;
}
html {
@include normalize-html;
font-family: $sans-serif;
overflow-y: scroll;
...
}
body {
@include normalize-body;
background-color: $white;
color: $black;
...
}
</code></pre>
<p>こんな風に Normalize.css をセレクタごとに Sass ミックスインに分解して、プロジェクトの SCSS の各セレクタに <code>@include</code> する、という面倒なことをしてた。v2.0 以前はとくに見出しやリストやフォームあたりでプロパティの上書きという無駄が発生しがちだったのでこういうアプローチを採ってたんだけど、どのスタイルを取り込んでるか把握するのがたいへんだし、どうしても二度手間感が拭えない。あとチームでメンテナンスする場合に「Normalize.css 使ってるよ」って一言で言えずコードを追ってもらう必要があるのも面倒。</p>
<p>その点、v2.0 は <a href="https://github.com/necolas/normalize.css/commit/7e014980b9155c8ef77b6d08c2ac352382a095b5">古いブラウザ用のコードがかなり削られた</a> ので内容がシンプルになり、無駄が発生しづらくなった。というわけで、最近のプロジェクトではまるごと使うことにした。具体的には、Normalize.css をリネームしてコメントを削除しただけの <a href="https://github.com/terkel/terkel.jp-scss/blob/master/_normalize.scss">_normalize.scss</a> という SCSS ファイルを用意してそのまま <code>@import</code> する。</p>
<p>いわゆる CSS リセットをかましたいようなプロジェクトでも、reset.css みたいなのを使うんじゃなくて、_normalize.scss を <code>@import</code> した上で、プロパティごとにリセットする <code>%</code> セレクタを用意して、これを必要に応じて <code>@extend</code> するという手を使ってみてる。</p>
<pre><code class="language-scss">@import "normalize" // import _normalize.scss
%reset-margin {
margin: 0;
}
%reset-padding {
padding: 0;
}
%reset-list-style {
list-style: none;
}
.site-logo {
@extend %reset-margin;
}
.primary-nav {
ul {
@extend %reset-margin;
@extend %reset-padding;
}
li {
@extend %reset-list-style;
}
}
</code></pre>
<p>ちなみに、Normalize.css が古いブラウザ (とくに IE 7 と 6) のサポートをやめたと言っても、内容に根本的な変更があったわけではなく、いくつかのスタイルを整理したのがアップデートの中心なので、古いブラウザをサポートするプロジェクトに使えないということはまったくない。今までどおり古いブラウザをサポートした <a href="http://necolas.github.com/normalize.css/1.0.1/normalize.css">v1.0.1</a> も提供されてるけど、無駄が発生しやすいので今となってはちょっと微妙。v2.0 をインクルードした上でプロジェクトごとに必要なスタイルを追加する方がいいと思う。古いブラウザのサポートをやめたというより、外に追い出して製作者に委ねた、と捉えるとよさそう。</p>
幅の狭い画面向けの等幅フォントに M+ 1m を採用
2012-09-10T00:00:00Z
https://terkel.jp/archives/2012/09/mplus-1m-for-narrow-screen/
<p>このサイトでは記事にソースコードを掲載することが多いけど、スマートフォンなど幅の狭い画面では折り返しが増えて読みづらくなってしまう。そこで幅の狭い等幅フォントに変えれば多少は読みやすくなるかと考え、<strong><a href="http://mplus-fonts.sourceforge.jp/">M+ Fonts</a></strong> の <a href="http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/design/index.html#mplus_1m">M+ 1m</a> をウェブフォントとして利用させていただくことにした。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/mplus-1m-for-narrow-screen.png" />
<figcaption>M+ 1m (約 12px) を幅 320px のスマートフォンで表示したところ</figcaption>
</figure>
<p>残念ながら今のところ <a href="http://www.google.com/webfonts">Google Web Fonts</a> にはないので、<a href="http://www.fontsquirrel.com/fonts/M-1m">Font Squirrel</a> からダウンロードしたフォントをサーバに上げて <code>@font-face</code> で参照。5 つのウェイトが用意されてるけど、ここで使うのは Regular と Bold のみ。表示域の幅がある程度狭い場合にのみ適用されるよう、メディアクエリで切り替えてる。</p>
<pre><code class="language-css">code,
samp,
kbd {
font-family: "Menlo", "Consolas", monospace;
}
@media screen and (max-width: 32em) {
code,
samp,
kbd {
font-family: "M+ 1m", monospace;
}
}
</code></pre>
<p>結果にはかなり満足してるけど、読み込むウェブフォントが増えてきちゃったのでなんか最適化を検討します…</p>
CSS ボタンのグラデーションとボーダーをグレースケールの RGBA で
2012-11-14T00:00:00Z
https://terkel.jp/archives/2012/11/gradients-and-borders-using-grayscale-rgba/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/css-button-1.png" />
</figure>
<p>CSS でボタンを作るとき、背景のグラデーションとボーダーをグレースケールの RGBA にしたものをもとにすると、背景色やフォントを変えるだけでバリエーションが作れるので便利です。</p>
<pre><code class="language-css">button {
background-image: linear-gradient(rgba(255, 255, 255, 0.1), rgba(0, 0, 0, 0.1));
background-origin: border-box;
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 0.25em;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), inset 0 1px rgba(255, 255, 255, 0.1);
cursor: pointer;
display: inline-block;
line-height: 1.5;
padding: 0.25em 1em;
text-align: center;
white-space: nowrap;
}
</code></pre>
<p>基本になるボタンはだいたいこんな感じです。背景は半透明の白から黒へのグラデーションにし、ボーダーも半透明の黒にします。この基本ボタンをもとに、背景色や前景色などを書き加えるだけで色のバリエーションが作れます。</p>
<pre><code class="language-css">button.default {
background-color: white;
color: black;
}
button.submit {
background-color: #00c000;
color: white;
}
button.delete {
background-color: #c00000;
color: white;
}
</code></pre>
<p>見落としがちなのが <a href="http://www.w3.org/TR/css3-background/#the-background-origin"><code>background-origin</code> プロパティ</a> です。この初期値は <code>padding-box</code> で、そのままだとグラデーションの開始と終了の位置がボーダーの内辺になります。ボーダーを単色で塗りつぶすならそれでもいいんですが、このコード例のようにボーダーの不透明度を下げてグラデーションを透過させるとちょっと不自然です (<a href="https://terkel.jp/archives/2012/11/gradients-and-borders-using-grayscale-rgba/#fig-2">Fig 2</a>)。</p>
<figure id="fig-2">
<img decoding="async" alt="" src="https://terkel.jp/img/css-button-2.png" />
<figcaption>Fig 2: <code>background-origin: padding-box;</code> (初期値)</figcaption>
</figure>
<p>そこでこれに <code>border-box</code> を指定すると、背景配置範囲をボーダーの外辺にすることができます。ボーダーが RGBA なら背景に沿ってグラデーションするので、より自然な感じになると思います (<a href="https://terkel.jp/archives/2012/11/gradients-and-borders-using-grayscale-rgba/#fig-3">Fig 3</a>)。このあたりの背景関連プロパティについては <a href="http://unformedbuilding.com/articles/learn-about-css3-background/">CSS3 での背景指定方法のまとめ | Unformed Building</a> が詳しくまとまっていてわかりやすいです。</p>
<figure id="fig-3">
<img decoding="async" alt="" src="https://terkel.jp/img/css-button-3.png" />
<figcaption>Fig 3: <code>background-origin: border-box;</code></figcaption>
</figure>
<p>コード例はかなりはしょった CSS で書きましたが、実際には Sass のプレースホルダー・セレクターを使うとより便利です。ご参考までに jsFiddle で簡単な拡張例もあわせてデモを作ってみました。GitHub や Twitter Bootstrap あたりに見られるような、最近よくある感じを取り入れたつもり。</p>
<ul>
<li>Demo: <a href="http://jsfiddle.net/terkel/ap8vT/">CSS Buttons - jsFiddle</a></li>
</ul>
<p>ボタンを例に書きましたが、それだけに限らずグラデーションを使う場面で広く利用できるテクニックです。これを僕は <a href="http://hail2u.net/blog/webdesign/css-gradients-technique-1.html">hail2u.net の記事</a> などで知ったんですが、あまり浸透していない気がするので、<a href="https://speakerdeck.com/ken_c_lo/zurui-design">ズルいデザイン</a> に触発されたのもあり、書いてみた次第です。</p>
Sass のミックスインをローカルな名前で呼ぶ
2012-11-19T00:00:00Z
https://terkel.jp/archives/2012/11/sass-mixin-local-name/
<p>Sass でライブラリをプロジェクトに組み込む場合など、ミックスインを「ローカル」な名前で呼ぶようにしておくと便利なことがある。</p>
<pre><code class="language-scss">// ミックスインの実装
@mixin awesome_gradient ($angle, $color-stops...) {
$prefixes: webkit, moz, o;
// ...
}
// ローカルなミックスインの定義
@mixin linear-gradient ($args...) {
@include awesome_gradient($args);
}
// ローカルなミックスインをインクルード
.foo {
@include linear-gradient(180deg, rgba(255, 255, 255, 0.5), rgba(0, 0, 0, 0.5));
}
</code></pre>
<p>ここで <code>.foo</code> は <code>linear-gradient</code> というミックスインをインクルードしているけど、そのミックスインはローカルな名前を提供しているだけで、実際には <code>awesome_gradient</code> を呼んでいる。一見すると無駄だけど、これがどんな場合に便利かというと、たとえばライブラリのミックスインを利用してるけどやっぱ別のに差し替えたい、みたいなときにラク。</p>
<pre><code class="language-scss">// 別のミックスインの実装
@mixin yetAnotherLinearGradient ($first, $rest...) {
// ...
}
// ローカルな名前はそのまま
@mixin linear-gradient ($args...) {
@include yetAnotherLinearGradient($args);
// @include awesome_gradient($args);
}
</code></pre>
<p>このように、ミックスインの実装は <code>awesome_gradient</code> から <code>yetAnotherLinearGradient</code> に差し替えたけど、ローカルな名前は <code>linear-gradient</code> のままなので、ミックスインをインクルードしている箇所では修正の必要がない。</p>
<p>重要なのはローカルのミックスインを定義するときに <code>$args...</code> という可変長引数 (<a href="http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#variable_arguments">Variable arguments</a>) を使うことで、これによってミックスイン間で引数の形式が異なってもある程度は吸収できる。もっともミックスインの設計がまったく異なるような場合にはインクルードしてる箇所も修正しないといけないけど。</p>
<p>またこの記事のもうひとつのメッセージとして、<a href="http://t-ashula.hateblo.jp/entry/2012/08/27/145535">linear-gradient の混沌</a> から僕を救ってくれるクールなミックスインないですか、というのもあります。</p>
Hybridity
2012-12-03T00:00:00Z
https://terkel.jp/archives/2012/12/hybridity/
<p>今週の土曜日、友人のレコード店 <a href="http://www.rubbergard.jp/">Rubbergard Record</a> がオーガナイズする <a href="http://www.rubbergard.jp/hybridity"><strong>Hybridity</strong></a> というパーティがあるんですが、その告知ページを作るという仕事をしました。イヴェントの内容は、僕はこっち方面のシーンには明るくないのであれなんですが、その筋では知る人ぞ知る方々が出演するらしく、とくにブラジル音楽が好きなら楽しめると思います。お暇ならぜひ!</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/hybridity.png" />
</figure>
<p>デザインはウェブフォントを使ってポスター風の表現を試してみました。このサイトでも全面で採用している <a href="http://www.google.com/webfonts/specimen/Open+Sans">Open Sans</a> と <a href="http://www.google.com/webfonts/specimen/Open+Sans+Condensed">Open Sans Condensed</a> のウェイトとサイズの組み合わせでなんとかそれっぽく。文字サイズをコンテンツ幅に合わせるためには <a href="http://fittextjs.com/">FitText</a>、タイトルのカーニングの調整用には <a href="http://letteringjs.com/">Lettering.js</a> という jQuery プラグインを使っています。たいした文字量ではないので Lettering.js は必ずしも必要じゃないんですが、使ってみたかったので。</p>
<p>背景画像を全画面で表示するのは <code>body</code> 要素に <code>background-attachment: fixed</code> と <code>backgournd-size: cover</code> でいけるかと思ったんですが、iOS で <code>background-attachment</code> が思った挙動にならず、空の <code>div</code> を <code>position: fixed</code> で配置するという方法を採りました。</p>
<p>時間もなかったので、緻密な計算より勢い重視でぶっ込むという方向で攻めました。久々に好き勝手やらせてもらえていい気分転換にもなったし、わりかし満足してます。</p>
<p>こういった「仕事しました!」っていう記事を書くのすごく久しぶりな気がする…</p>
画像の最大幅を calc() で制御する
2012-12-16T00:00:00Z
https://terkel.jp/archives/2012/12/control-image-width-with-calc/
<p>画像の幅をコンテンツに合わせてフレキシブルにしたい場合、親要素の幅を超えないようにするには CSS の <code>max-width</code> プロパティに <code>100%</code> を指定する。</p>
<pre><code class="language-css">img {
max-width: 100%;
border: 1px solid silver;
padding: 0.25em;
}
</code></pre>
<p>ただ、画像にパディングやボーダーを持たせた場合、その分が親要素の幅より大きくなってしまうことがある (Fig 1)。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/img-max-width.png" />
<figcaption>Fig 1: パディングとボーダーを持つ画像に `max-width: 100%;` を指定すると、親要素の幅を越えてしまうことがある</figcaption>
</figure>
<p>これをつねに親要素に収めるようにするには、<code>box-sizing</code> プロパティを利用して画像の幅がパディングとボーダー込みで算出されるようにする、という手がある。</p>
<pre><code class="language-css">img {
max-width: 100%;
border: 1px solid silver;
padding: 0.25em;
box-sizing: border-box;
}
</code></pre>
<p>これでも上手くいんくんだけど、<code>img</code> 要素の <code>width</code> と <code>height</code> 属性もこの <code>box-sizing</code> の影響を受けるため、マークアップで指定した値と実際に表示される大きさが違ってしまってちょっと面倒。たとえば、いわゆる Retina ディスプレイを考慮して縦横が 2 倍の画像を <code>width</code>/<code>height</code> で半分の大きさに縮小する、みたいな場面で計算が狂ってくる。</p>
<p>そこで、画像の <code>max-width</code> の値として <a href="http://www.w3.org/TR/css3-values/#calc-notation"><strong><code>calc()</code></strong></a> を利用してみる。</p>
<pre><code class="language-css">img {
max-width: calc(100% - 1px * 2 - 0.25em * 2);
border: 1px solid silver;
padding: 0.25em;
}
</code></pre>
<p>親要素の幅から画像の左右のパディングとボーダーの大きさを引き算したものが画像の最大幅になる。このように % と em と px という異なる単位を一緒にしてもちゃんと計算してくれる。これならマークアップで <code>width</code> と <code>height</code> を指定しても、親要素の幅が充分にあればそのとおりの大きさで表示され、足りなければパディングとボーダーの分も含めて親要素の幅を超えることはない。</p>
<p><code>calc()</code> は IE9 を含めすでに <a href="http://caniuse.com/calc">けっこうサポートされてる</a> けど、フォールバックとしてはレイアウトが破綻しない程度にざっくり計算した値も入れておく。ベンダー接頭辞として <code>-moz-</code> はたぶんもう要らないけど <code>-webkit-</code> はまだ要る。あと Android と Opera、よろしくお願いします。</p>
<pre><code class="language-css">img {
max-width: 96%;
max-width: -webkit-calc(100% - 1px * 2 - 0.25em * 2);
max-width: -moz-calc(100% - 1px * 2 - 0.25em * 2);
max-width: calc(100% - 1px * 2 - 0.25em * 2);
border: 1px solid silver;
padding: 0.25em;
}
</code></pre>
<p>こういうのは Sass でなんとかなりそうな気がちらっとするけど、Sass はあくまで静的な CSS を書き出すものなので、<code>calc()</code> のようにクライアント側で動的に演算するようなものはそもそも無理。ミックスインを作るとしてもせいぜいベンダー接頭辞を付与するタイプのものしかできないはず。その場合も、単位が混ざってる時点でエラーになってしまうため、式を文字列として渡す必要がある。</p>
<pre><code class="language-scss">@mixin calc ($prop, $expr) {
$prefixes: webkit, moz;
@each $prefix in $prefixes {
#{ $prop }: -#{ $prefix }-calc(#{ $expr });
}
#{ $prop }: calc(#{ $expr });
}
img {
@include calc(max-width, "100% - 1px * 2 - 0.25em * 2");
}
</code></pre>
<p><code>calc()</code> をちゃんと使ったのはじつは今回がはじめてだったんだけど、いままであきらめてたのがあっさり実現できてちょっと感動した。</p>
ハヤカワ・ポケット・ミステリのデザイン
2012-12-17T00:00:00Z
https://terkel.jp/archives/2012/12/design-of-hayakawa-pocket-mystery/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/hayakawa.jpg" />
</figure>
<p><strong>ハヤカワ・ポケット・ミステリ</strong>、通称「ポケミス」は 1953 年から現在まで刊行が続いている翻訳ミステリのシリーズ。黄色い小口と抽象画の装画による特徴ある装幀を目にしたことのある人は多いと思う。その装幀を手がけていた勝呂忠氏が 2010 年に亡くなり、『<a href="http://www.amazon.co.jp/dp/4150309841?tag=terkel-22">虐殺器官</a>』や『<a href="http://www.amazon.co.jp/dp/4150503761?tag=terkel-22">これからの「正義」の話をしよう</a>』などの仕事で知られる装幀家の <a href="http://mitobeisao.com/"><strong>水戸部功</strong></a> 氏がその跡を継ぎ、デザインも一新された。</p>
<p>ここに並べたのはそのリニューアル後の作品。タイポグラフィを中心に据えたデザインは書店で大いに目を引く。おそらくペンギン・ブックスの <a href="http://www.penguin.co.uk/greatideas">Great Ideas シリーズ</a> などを意識されてるのかなとか思うけど、ここでそのデザイン手法などについてどうこう言うつもりはないしそれができるとも思ってなくて、ただ好きなので並べてみたかっただけ。もし僕がいつかまかり間違って本を書くようなことがあればこの方に装幀をお願いしたいなー (妄言)。</p>
JavaScript のビットマスクによるフラグの管理
2012-12-23T00:00:00Z
https://terkel.jp/archives/2012/12/javascript-bitmask/
<p>JavaScript のビットマスクをはじめて使った。というかビット演算子というものに触れるのがそもそもはじめて。最初は何が何やらわからなかったけど、以下のページなどを参考にしつつなんとかやってみた。</p>
<ul>
<li><a href="https://developer.mozilla.org/ja/docs/JavaScript/Reference/Operators/Bitwise_Operators">ビット演算子 - JavaScript | MDN</a></li>
<li><a href="http://d.hatena.ne.jp/piglovesyou/20120621/1340237658">ビットマスクによるフラグ - piglovesyouの日記</a></li>
</ul>
<p>状況としては、ユーザー設定のフラグをビットマスクで管理していて、それを API を通じて <code>GET</code>/<code>POST</code> する、という感じ。ここでは例として、アプリケーションのユーザー設定で、各種ソーシャル系サービスと連携するかどうかみたいなデータを管理する場合を想定する。</p>
<p>まず、各フラグのデータを 1、2、4、8… という整数値で定義しておく。こういったデータは定数として扱うのでキーを大文字にすることが多い、らしい。</p>
<pre><code class="language-javascript">var social = {
TWITTER: 1,
FACEBOOK: 2,
GOOGLE_PLUS: 4,
TUMBLR: 8
};
</code></pre>
<p>HTML ではこれらのフラグに対応したチェックボックスを用意し、カスタムデータ属性でフラグの値を埋め込む。これは <a href="http://underscorejs.org/">Underscore.js</a> のテンプレートを使った例で、<code><%= ... %></code> の部分が数値に置き換わって出力される。</p>
<pre><code class="language-html"><label>
<input type="checkbox" data-flag="<%= social.TWITTER %>">
Twitter
</label>
<label>
<input type="checkbox" data-flag="<%= social.FACEBOOK %>">
Facebook
</label>
<label>
<input type="checkbox" data-flag="<%= social.GOOGLE_PLUS %>">
Google+
</label>
<label>
<input type="checkbox" data-flag="<%= social.TUMBLR %>">
Tumblr
</label>
</code></pre>
<p>テンプレートがロードされたら、API から取得したフラグと各チェックボックスのカスタムデータ属性の値を <code>&</code> 演算子で判定し、アリなら <code>checked</code> にする。この例では 1 つ目と 4 つ目がオンになる。</p>
<pre><code class="language-javascript">var flags = 9; // API から取得したフラグ
$('input[type="checkbox"]').each(function () {
$(this).attr('checked', !!(flags & $(this).data('flag')));
});
</code></pre>
<p>データを <code>POST</code> するときは、オンになってるチェックボックスを抜き出して、<code>|</code> 演算子でフラグを立てる (という言い方でいいんだろうか?)。なんかループしなくてもできるやり方がありそうな予感がするけど思いつかない。</p>
<pre><code class="language-javascript">var flags = 0;
$('input[type="checkbox"]:checked').each(function () {
flags |= $(this).data('flag');
});
</code></pre>
<p>ビット演算子、『<a href="http://www.amazon.co.jp/dp/4873115736?tag=terkel-22">サイ本</a>』では 1 ページ半ほどの扱いで「読み飛ばしても問題ありません」って言ってるし、『<a href="http://www.amazon.co.jp/dp/4873113911?tag=terkel-22">The Good Parts</a>』だと「悪いパーツ」に入ってるし、まったく意識したこともなかったけど、やっぱ使うときは使いますね。たしかに一見して何をやってるかわかんなくて、どうやら動いてるもののいまいち不安。結果、「考えた人頭いいなー」といういつもの馬鹿みたいな感想が浮かびました。</p>
小数の桁数と丸め方を制御する Sass 関数
2012-12-25T00:00:00Z
https://terkel.jp/archives/2012/12/decimal-digits-and-rounding-sass-function/
<p>Sass の数値で出力されるのは小数点以下 5 桁までで、6 桁めが四捨五入される (Sass 3.2 の <a href="http://sass-lang.com/docs/yardoc/Sass/Script/Number.html#precision-class_method">デフォルト設定</a> の場合)。つまり、<code>0.333333...</code> は <code>0.33333</code> に、<code>0.666666...</code> は <code>0.66667</code> に丸められる。でもたとえば <code>16px/12px</code> の結果として <code>1.33333</code> ではなく <code>1.34</code> がほしい、というような場面もある。数値を丸める関数として <a href="http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#round-instance_method"><code>round()</code></a>、<a href="http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#ceil-instance_method"><code>ceil()</code></a>、<a href="http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#floor-instance_method"><code>floor()</code></a> が用意されてるけど、いずれも小数部分を丸めて整数を返すもので、任意の桁を操作するということはできない。というわけで、小数点以下の桁数と丸めを制御する <strong><code>round-decimal()</code></strong>、<strong><code>ceil-decimal()</code></strong>、<strong><code>floor-decimal()</code></strong> という関数を作ってみた。</p>
<pre><code class="language-scss">// Round (四捨五入)
@function round-decimal ($number, $digits: 0) {
@return to-fixed($number, $digits, 'round');
}
// Ceil (切り上げ)
@function ceil-decimal ($number, $digits: 0) {
@return to-fixed($number, $digits, 'ceil');
}
// Floor (切り捨て)
@function floor-decimal ($number, $digits: 0) {
@return to-fixed($number, $digits, 'floor');
}
@function to-fixed ($number, $digits: 0, $round: 'round') {
$n: 1;
// $number must be a number
@if type-of($number) != number {
@warn '#{ $number } is not a number.';
@return $number;
}
// $digits must be a unitless number
@if type-of($digits) != number {
@warn '#{ $digits } is not a number.';
@return $number;
} @else if not unitless($digits) {
@warn '#{ $digits } has a unit.';
@return $number;
}
@for $i from 1 through $digits {
$n: $n * 10;
}
@if $round == 'round' {
@return round($number * $n) / $n;
} @else if $round == 'ceil' {
@return ceil($number * $n) / $n;
} @else if $round == 'floor' {
@return floor($number * $n) / $n;
} @else {
@warn '#{ $round } is undefined keyword.';
@return $number;
}
}
// round-decimal(0.333) => 0
// round-decimal(0.333, 1) => 0.3
// round-decimal(0.333, 2) => 0.33
// round-decimal(0.666) => 1
// round-decimal(0.666, 1) => 0.7
// round-decimal(0.666, 2) => 0.67
// ceil-decimal(0.333) => 1
// ceil-decimal(0.333, 1) => 0.4
// ceil-decimal(0.333, 2) => 0.34
// ceil-decimal(0.666) => 1
// ceil-decimal(0.666, 1) => 0.7
// ceil-decimal(0.666, 2) => 0.67
// floor-decimal(0.333) => 0
// floor-decimal(0.333, 1) => 0.3
// floor-decimal(0.333, 2) => 0.33
// floor-decimal(0.666) => 0
// floor-decimal(0.666, 1) => 0.6
// floor-decimal(0.666, 2) => 0.66
</code></pre>
<p>いずれも引数は丸めたい数値と小数点以下の桁数 (デフォルトは <code>0</code>)で、関数の実体は <code>to-fixed()</code> という、JavaScript の <a href="https://developer.mozilla.org/ja/docs/JavaScript/Reference/Global_Objects/Number/toFixed"><code>toFixed()</code></a> をイメージした関数 (ちょっと違うけど)。たとえば <code>ceil-decimal(0.3333, 2)</code> なら、</p>
<pre><code class="language-scss">@return ceil(0.3333 * 100) / 100
</code></pre>
<p>ということになるので、33.33 を切り上げた整数 34 の 1/100、つまり <code>0.34</code> が返る。</p>
<p><a href="https://gist.github.com/4373420">Gist</a> にも上げときました。関数名が適切かどうかの添削を誰か。</p>
<h2>Changes</h2>
<p>January 12, 2013 – ソースコード中、<code>to-fixed()</code> 関数のエラー処理と条件分岐を修正</p>
最近の仕事
2012-12-31T00:00:00Z
https://terkel.jp/archives/2012/12/recent-work/
<p>近況報告。</p>
<p>今年の 9 月中旬頃から、<a href="http://www.aqworks.com/">AQ</a> でウェブ・アプリケーションを作るプロジェクトに参加しています。フロントエンド全般を担当していますが、とくに JavaScript と格闘し続けた数か月でした。</p>
<p>僕の今までの仕事はおもにウェブサイトの HTML と CSS を書くことが中心で、JavaScript は UI にちょっとしたインタラクションを加えるような、いわゆる jQuery プラグインっぽいものが多く、今回のようにアプリケーションのためにがっちりとスクリプトを書くのは初めての経験です。プロジェクトのはじめは「ウェブ・アプリケーション」というものがそもそも理解できず、ふだんどおりサイトを作るノリではじめたところ早々に行き詰まり、どうやら MVC とかいうものが必要らしいということで <a href="http://backbonejs.org/">Backbone.js</a> にたどり着き、毎日ググりまくりながら見よう見まねで試行錯誤、といった感じが今も続いています。こんな僕を呼んでくれた AQ のメンバーには本当に感謝しているし、毎日つまずきながらもなんとかやれているのもチームのおかげです (とくにトモミさんとアルバン、本当にありがとう!)。</p>
<p>また AQ はメンバーもパートナーも海外出身の方が多く、職場でのコミュニケーションは英語が中心です。僕はほとんどしゃべれませんが、めちゃくちゃな英語ながらも勢いで押し、なんとかコミュニケートできています (と思っています)。プロジェクトの内容はもちろんのこと、この環境も大いに刺激になりました。</p>
<p>といった具合に若干無理めのプロジェクトに挑んだ今年後半ですが、言うまでもなく得たものは少なくありません。それは新しい技術や考え方に触れたということだけではなく、自分が今後どういったことをやっていきたいかが少しずつ明確になってきたことも大きいです。これは来年からの仕事で少しずつ実現していければと考えています。</p>
<p>プロダクトのリリースはもう少し先の話で、今後も継続して参加する予定です。しばらく飲みに行ったりする余裕もありませんでしたが、年明けにはちょっと落ち着きそうなのでどうぞよろしくお願いいたします。</p>
<p>それでは皆さん、良いお年を!</p>
Sass のカスタム関数の書き方
2013-01-06T00:00:00Z
https://terkel.jp/archives/2013/01/sass-custom-function-patterns/
<p>Sass は <a href="http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html">ネイティブ関数</a> のほかに、<a href="http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#function_directives"><code>@function</code> ディレクティブ</a> を使ってカスタム関数を自由に定義することができます。僕もより共有や再利用のしやすいものを作るべく試行錯誤していますが、ここではそのうち最近試しているいくつかのパターンについて書いてみました。ご意見求む。</p>
<h2>接頭辞</h2>
<p><code>attr()</code> や <code>calc()</code> など CSS のネイティブ関数や <code>percentage()</code> や <code>type-of()</code> といった Sass のネイティブ関数と名前が衝突するのを防ぐため、カスタム関数の関数名に接頭辞をつけることを検討しています。現行の CSS/Sass だけではなく将来追加される新しいネイティブ関数も考慮するとやはり何らかの対策をしておきたいところで、接頭辞は現実的な解であるように思います。Sass リファレンスの <a href="http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#function_directives">関数ディレクティブの項</a> でも以下のように接頭辞の採用を勧めています:</p>
<blockquote cite="http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#function_directives" lang="en">
<p>It is recommended that you prefix your functions to avoid naming conflicts and so that readers of your stylesheets know they are not part of Sass or CSS. For example, if you work for ACME Corp, you might have named the function above <code>-acme-grid-width</code>.</p>
</blockquote>
<p>もしライブラリのようなかたちで公開するものなら、例に挙げられているようにプロジェクト名を接頭辞にするとよさそうです。たとえば <code>compass-grid-width()</code> とか <code>bourbon-grid-width()</code> とか。もしくは <a href="https://github.com/necolas/idiomatic-css#preprocessors-additional-format-considerations">Principles of writing consistent, idiomatic CSS</a> で提案されているように <code>x-</code> が汎用的でいいかなと思うんですが、どうでしょう?</p>
<pre><code class="language-scss">@function x-sprit-unit ($number) {
// ...
}
@function x-convert-to-rem ($number) {
// ...
}
</code></pre>
<h2>エラー処理</h2>
<p>渡された引数の型や単位などをチェックし、もし想定したものでない場合は戻り値を変更したり警告のメッセージを出力したりしています。例として数値から単位を取り除く関数を考えてみましょう (なおこの関数は <a href="http://stackoverflow.com/a/12335841">Stack Overflow</a> や <a href="http://jsdo.it/kosei27/hqio">jsdo.it</a> などを参考にしました)。</p>
<pre><code class="language-scss">@function x-strip-unit ($number) {
@return $number / ($number * 0 + 1);
}
</code></pre>
<p>この関数は引数として数値が渡されることを想定しているので、もし文字列が渡されるとエラーとなり、コンパイルに失敗します。そこで引数の型が数値かどうかチェックし、もし真なら本来の処理、偽なら <a href="http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#id9"><code>@warn</code> ディレクティブ</a> で警告し、引数を処理せずそのまま返すようにしてみます:</p>
<pre><code class="language-scss">@function x-strip-unit ($number) {
@if type-of($number) == number {
// 通常の処理
@return $number / ($number * 0 + 1);
} @else {
// エラー処理
@warn '#{ $number } is not a number.';
@return $number;
}
}
</code></pre>
<p>これでもいいんですが、<code>@return</code> ディレクティブは実行されると処理が関数の呼び出し元に戻る (つまり関数の残りは実行されない) ので、以下のように書くこともできます:</p>
<pre><code class="language-scss">@function x-strip-unit ($number) {
@if type-of($number) != number {
// エラー処理
@warn '#{ $number } is not a number.';
@return $number;
}
// 通常の処理
@return $number / ($number * 0 + 1);
}
</code></pre>
<p>複数の引数を多重にチェックする必要がある場合などはとくに、このようにエラー処理を前半にまとめるとコードの見通しが良くなります。</p>
<p>エラーの場合にどういった値を返すべきかは関数によって違ってくるでしょう。任意の引数をそのまま返すか、<code>null</code> を返すか、あるいは想定される値と見なして通常の処理をするか (たとえば単位の省略を許容するなど)、といったパターンが考えられます。</p>
<h2>コメント</h2>
<p>その関数がいったい何なのかについてコメントを残しておくと、チームのメンバーや未来の自分に感謝してもらえるのでおすすめです。書式はなんでもいいのですが、ほかのプロジェクトで使いまわすことなどを考えると、ある程度スタンダードに添っているといいかなと思い、JavaScript でわりと使われているらしい <a href="http://yui.github.com/yuidoc/">YUIDoc</a> や <a href="http://code.google.com/p/jsdoc-toolkit/">JsDoc Toolkit</a> あたりを真似たものを試してみてます。</p>
<pre><code class="language-scss">// Strip unit from number
// @function x-strip-unit
// @param {Number} $number number to strip unit
// @return {Number} unitless number
// @example
// x-strip-unit(-16px) => -16
// x-strip-unit(0.5em) => 0.5
// x-strip-unit(0.5cm + 10mm) => 1.5
@function x-strip-unit ($number) {
// ...
}
</code></pre>
<p>機能についての簡単な説明に続けて関数名を示し、引数の型と識別子、戻り値の型、あと記述例などが書いてあるといいと思います。なおこれらのコメントは開発のためのものでコンパイル後には必要ないというか残ってるとおかしいので、<code>/* */</code> 形式ではなく <code>//</code> 形式で。</p>
<p>もちろんこのコメントからドキュメンテーションが自動生成できると面白いんですが、そこまではできてないです。Ruby とか Node とかよくわかんないので… <a href="https://github.com/eoneill/sassdoc">sassdoc</a> ってプロジェクトもあるみたいですがどうなんでしょうね。でもコメントを残すだけでも充分有意義なはずです。</p>
<p>また Sass のドキュメンテーションとともに、CSS のスタイルガイドというものもちゃんとやんなきゃとずっと思いつつやれていないので、合わせて考えたいところですね (新年の抱負)。</p>
NIR for Retina Images
2013-02-18T00:00:00Z
https://terkel.jp/archives/2013/02/nir-for-retina-images/
<p>擬似要素と <code>content</code> プロパティを利用した画像置換テクニックの <a href="http://nicolasgallagher.com/css-image-replacement-with-pseudo-elements/">NIR</a> (Nash Image replacement) と、いわゆる Retina ディスプレイ向けの高解像度画像 (<code>[email protected]</code> みたいなやつ) を組み合わせる方法について。まずは NIR についておさらい:</p>
<pre><code class="language-css">.nir {
overflow: hidden;
width: 160px;
height: 50px;
*background: url(sprites.png) no-repeat 0 -25px;
*text-indent: -9999px;
}
.nir:before {
content: url(sprites.png);
display: inline-block;
font-size: 0;
line-height: 0;
margin-left: 0;
margin-top: -25px;
}
</code></pre>
<p>要素の幅と高さと <code>overflow: hidden</code> を指定した上で、<code>:before</code> 擬似要素の <code>content</code> プロパティで画像を生成し、テキストをボックスのそとに追い出して見えなくする、というテクニック。スプライト画像の場合は左上からの座標を <code>margin-left</code> と <code>margin-top</code> で指定すれば対応できる。擬似要素をサポートしない IE7 以下では背景画像と <code>text-indent</code> による昔ながらの画像置換でフォールバック。</p>
<p>これを 2 倍のサイズで書き出した高解像度の画像でやるにはちょっと工夫が必要になる。というのも、画像をブラウザで半分に縮小して表示する必要があるわけだけど、<code>content</code> プロパティで生成した画像のサイズは <code>width</code>/<code>height</code> プロパティなどではコントロールできないからだ。背景画像なら <code>background-size</code> が使えるけどもちろんそれも無理。そこで <a href="http://www.w3.org/TR/css3-transforms/">CSS Transforms</a> の <code>scale()</code> 関数を使う:</p>
<pre><code class="language-css">.nir {
overflow: hidden;
width: 160px;
height: 50px;
}
.nir:before {
content: url([email protected]);
display: inline-block;
font-size: 0;
line-height: 0;
margin-left: 0;
margin-top: -25px;
-webkit-transform: scale(0.5);
-ms-transform: scale(0.5);
transform: scale(0.5);
-webkit-transform-origin: 0 0;
-ms-transform-origin: 0 0;
transform-origin: 0 0;
}
.no-csstransforms .retina-nir {
background: url(sprites.png) no-repeat 0 -25px;
text-indent: -9999px;
}
.no-csstransforms .retina-nir:before {
display: none;
}
</code></pre>
<p>このように <code>transform</code> プロパティに <code>scale(0.5)</code> を指定することで画像が半分のサイズで表示される。ちなみに <code>background-size</code> プロパティではこのように画像のサイズを基準にした相対的な指定はできず、画像の実際のサイズを元にした数値を CSS に反映させる必要があるけど、これはシンプルに比率を渡せるのでその点でも便利。</p>
<p>見落としがちなのが <code>transform-origin</code> プロパティで、この初期値が <code>50% 50%</code> であるため、画像の左上を基点に座標を指定するためには <code>0 0</code> を指定する必要がある。</p>
<p>フォールバックとしては transform が使えるかどうかを基準にする必要があるので、<a href="http://modernizr.com/">Modernizr</a> を利用して、もしサポートしていなければ擬似要素は利用せず「等倍」の画像を背景として表示している。具体的には IE8 以下がその対象。もちろんできれば CSS だけで判別したいけどちょっと思いつかなかった。</p>
<p>これを Sass のミックスインにするとこんな感じ:</p>
<pre><code class="language-scss">// NIR for Retina image
@mixin retina-nir (
$x: 0,
$y: 0,
$width: null,
$height: null,
$path: "/img/sprites",
$mod: "@2x",
$ext: ".png",
$ratio: 2
) {
@if $x > 0 { $x: -$x; }
@if $y > 0 { $y: -$y; }
overflow: hidden;
@if $width {
width: if(type-of($width) == number and unit($width) != '%', $width/$ratio, $width);
}
@if $height {
height: if(type-of($height) == number and unit($height) != '%', $height/$ratio, $height);
}
&:before {
content: url($path + $mod + $ext);
display: inline-block;
font-size: 0;
line-height: 0;
margin-left: $x/$ratio;
margin-top: $y/$ratio;
@include transform(scale(1/$ratio));
@include transform-origin(0 0);
}
.no-csstransforms & {
background: url($path + $ext) no-repeat $x/$ratio $y/$ratio;
text-indent: -9999px;
&:before {
display: none;
}
}
}
// transform
@mixin transform ($transform-function) {
$prefixes: webkit, ms;
@each $prefix in $prefixes {
-#{ $prefix }-transform: $transform-function;
}
transform: $transform-function;
}
// transform-origin
@mixin transform-origin ($origin) {
$prefixes: webkit, ms;
@each $prefix in $prefixes {
-#{ $prefix }-transform-origin: $origin;
}
transform-origin: $origin;
}
// usage
.nir {
@include retina-nir($y: -50px, $width: 320px, $height: 100px);
}
</code></pre>
<p>実際の作業では Retina サイズの画像をもとに CSS を書くことになると思うので、サイズや位置の引数は縮小した結果ではなく高解像度画像の実際のサイズを基準にした数値を渡し、それぞれ 2 で割るようにしてある (パーセント値の場合を除く)。座標に正の数値を渡した場合に負に変換するのはおせっかいな気もするけど、個人的によく間違うので入れた。transform 関係はほかでも使うので別ミックスインに分けてある。</p>
<p>もちろん、画像置換に限らず CSS generated content には同じ手が使える。</p>
接頭辞つきのクラス名にマッチする CSS セレクター
2013-03-05T00:00:00Z
https://terkel.jp/archives/2013/03/css-selector-matches-prefixed-class/
<p><a href="http://cferdinandi.github.com/kraken/">Kraken</a> というフロントエンドのフレームワークのコードを見ていたら、なるほどと感心する CSS セレクターの書き方を見つけた。<code>grid-one</code>、<code>grid-two</code> みたいな接頭辞つきのクラス名にマッチするセレクターで、こんな感じ:</p>
<pre><code class="language-css">[class^="grid-"],
[class*=" grid-"] {
/* ... */
}
</code></pre>
<p>単純に考えると <code>[class*="grid-"]</code> でいけそうな気がするけど、それだと <code>foo-grid-</code> みたいに頭に余計なものがついていてもマッチしてしまう。そこでホワイトスペースを接頭辞の前に置いて <code>[class*=" grid-"]</code> とすることでそれを避けている。すると今度は <code>class="grid-one"</code> みたいに <code>class</code> 属性の先頭で頭にホワイトスペースがない場合にマッチしないので、<code>[class^="grid-"]</code> という前方一致のルールを追加。</p>
<p>ひょっとすると <code>[class|="grid"]</code> でスマートに解決できそう、とか思うけど、それだと接頭辞ではない <code>grid</code> クラスもマッチしてしまうし、複数のクラスがあった場合に先頭のものしかマッチしない。<code>|</code> は基本的に言語コード用と考えたほうが良さそう。</p>
<p>この接頭辞パターンの <code>^</code> を <code>$</code> にしてホワイトスペースとハイフンの位置を入れ替えれば接尾辞にマッチするパターンも作れる。</p>
<pre><code class="language-css">[class$="-item"],
[class*="-item "] {
/* ... */
}
</code></pre>
<p>簡単なデモも書いてみた。</p>
<ul>
<li><a href="http://codepen.io/terkel/pen/ywEth">CSS selector matches class prefix/suffix - CodePen</a></li>
</ul>
<p>こういう正規表現みたいなの日本語で説明するのすごく面倒…</p>
MathSass
2013-04-14T00:00:00Z
https://terkel.jp/archives/2013/04/mathsass/
<p>CSS で角度を扱う機会が増えてきたので、三角関数を中心にいくつかの数学関数を Sass 関数として実装してみてる。「三角関数を中心に」とかさらっと書いてるけど、書いてる本人はタンジェントとか高校で習ってないと言い張る程度の理解なので注意。書いてるうちに芋づる式に増えて手に負えなくなってきたところで GitHub に公開することにした。</p>
<ul>
<li><a href="https://github.com/terkel/mathsass">terkel/mathsass · GitHub</a></li>
</ul>
<p>ほんとは Ruby のモジュールで書けば簡単かつ精度も高いだろうし、将来 Sass のネイティブに実装されれば用なしになるわけだけど、勉強になるのでやってて満足度は高い。</p>
<p>これ系の Sass 実装でまとまったものは <a href="https://github.com/adambom/Sass-Math">adambom/Sass-Math</a> と <a href="https://github.com/Team-Sass/Sassy-math">Team-Sass/Sassy-math</a> ぐらいしか見つけられなかったし、これらの中でもものによってバグってるっぽいのもあったので、ほかに <a href="http://blog.livedoor.jp/dankogai/archives/51518565.html">404 Blog Not Found:javascript - Mathを再発明してみた</a> や『<a href="http://www.amazon.co.jp/dp/4874084141?tag=terkel-22">C言語による最新アルゴリズム事典</a>』などを参考にした。</p>
<p>今のところの具体的な利用シーンとしては「幅と高さから角度を求める」とか「幅と角度から高さを求める」といったところなので、とりあえずこれで足りてるものの、せっかくなので <code>log()</code> とかもあると格好がつくのかなというのはある。いつ使うのかはさっぱりわからないけど。</p>
<p>あとはテストをちゃんと書きたいんだけど、それぞれの関数で典型的な数値というか、この場合にこの値が得られれば実装として合格、みたいなのがわからないので書けずにいる。答え合わせはブラウザーの JavaScript コンソールで <code>Math.sqrt(2)</code> とかやっておー合ってる合ってるみたいな進め方なのでかなり不安。</p>
<p>そんなわけで math 好きな皆さんのご参加をお待ちしております。</p>
<p>次は行列に挑戦だ!</p>
Ruby で Sass のカスタム関数を書く
2013-05-25T00:00:00Z
https://terkel.jp/archives/2013/05/custom-sass-functions-using-ruby/
<p>Sass で関数を書く方法は 2 つあります。ひとつは Sass の <a href="http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#function_directives"><code>@function</code> ディレクティブ</a> を使って Sass ファイル内に定義する方法。</p>
<pre><code class="language-scss">$grid-width: 40px;
$gutter-width: 10px;
@function grid-width ($n) {
@return $n * $grid-width + ($n - 1) * $gutter-width;
}
</code></pre>
<p>簡単かつカジュアルに書ける反面、当然ながら Sass のネイティブ関数やディレクティブの制限を受けるので、できないことも多いです。とくに Sass は文字列系の関数があまり用意されておらず、不満を感じることも少なくありません。</p>
<p>もうひとつの方法は、<a href="http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#adding_custom_functions"><strong>Ruby でカスタム関数を書いて Sass を拡張する</strong></a> という方法です。Ruby の知識が必要で、かつ Sass ファイルに直接定義するのとは違って別ファイルから読み込む必要があったり、少しハードルが高いのも確かですが、Sass だけでは難しい複雑な処理を書けます。</p>
<p>(ちなみに、以前このブログの記事で <code>@function</code> による関数を「カスタム関数」と書いたことがありましたが、おそらくそっちはただの関数で、Ruby の方をカスタム関数と呼んだ方が良さそうです)</p>
<p>というわけで、Ruby は『<a href="http://www.amazon.co.jp/dp/4873113679?tag=terkel-22">初めての Ruby</a>』(おすすめ!) をざっと眺めた程度の理解しかありませんが、カスタム関数を書いてみました。</p>
<p>今回書いたのは <code>escape()</code> という関数です。おもに <code>content</code> プロパティで使うことを想定していて、文字列を渡すと <code>\</code> と Unicode のコードポイントでエスケープしてくれる、というものです (ちなみに CSS における文字のエスケープについては <a href="http://mathiasbynens.be/notes/css-escapes">CSS character escape sequences · Mathias Bynens</a> が良くまとまってます)。たとえば、</p>
<pre><code class="language-scss">.hello {
&:before {
content: escape("ヾ(๑╹◡╹)ノ");
}
}
</code></pre>
<p>これが、</p>
<pre><code class="language-css">.hello:before {
content: "\30FE\28\E51\2579\25E1\2579\29\FF89";
}
</code></pre>
<p>こうなります。</p>
<p>これを Sass の <code>@function</code> でやろうとすると、現状ではおそらく巨大な Unicode のテーブルを擬似連想配列っぽいリストに入れて回す、みたいなことになって、あまり実用的じゃありません。やはりここは Ruby でいきたい。そこで、<a href="http://prog4designer.github.io/"><strong>P4D</strong></a> という、プログラマーとデザイナーが集まって何か作ったり相談したりする会があるんですが、そこにお邪魔してルビィストの <a href="http://satococoa.github.io/">@satococoa</a> にこういうの作りたいんですけど… とぶつけ、マンツーマンで教えていただきつつ出来上がった (というかほぼ @satococoa が書いた) のがこれです:</p>
<pre><code class="language-ruby">module Sass::Script::Functions
def escape(string)
assert_type string, :String
Sass::Script::String.new(string.value.codepoints.map{ |i|
'\\' + i.to_s(16).upcase
}.join(''), :string)
end
declare :escape, :args => [:string]
end
</code></pre>
<p>コードは Sass のドキュメンテーションにある例をもとにしました。</p>
<p>はまったのが <code>string.value</code> の部分で、この <code>.value</code> を抜かして <code>string.codepoints</code> としても動きません。<a href="http://sass-lang.com/docs/yardoc/Sass/Script/String.html#value-instance_method">Sass のドキュメンテーション</a> にあるように、<code>String#value</code> メソッドによって文字列が Ruby でいじれるかたちになるらしいです。</p>
<p>あと Ruby の <code>String#codepoints</code> を使っているため、Ruby 1.8 系統では動きません。Mac の Ruby はいまも 1.8 がデフォルトらしいので注意。僕も <a href="http://qiita.com/items/9dd797f42e7bea674705" title="OS X で rbenv を使って ruby 1.9.3 or 2.0.0 の環境を作る #Ruby #開発環境 #AdventCalendar - Qiita [キータ]">Qiita の記事</a> を見ながら 1.9.3 にしました。</p>
<p><code>Sass::Script::String.new()</code> に渡してる 2 つめの引数 <code>:string</code> は <a href="http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#quote-instance_method"><code>quote()</code></a> 関数のソースにあったのをそのまま持ってきたもので、文字列が <code>"</code> で囲まれて返ってくるみたいです。</p>
<p>で、使い方。まず上記 Ruby コードを <code>functions.rb</code> などとして、プロジェクトの適当なディレクトリに置きます。そして watch するときに、</p>
<pre><code>$ cd /Users/me/Projects/my-project
$ sass --watch ./sass:./css -t compact -r ./sass/functions.rb
</code></pre>
<p>というように、<code>-r</code> オプション (<code>--require</code> のショートカット) でファイルへのパスを渡します。こうするとそのファイルを読み込んでくれて、あとは Sass ファイルのどこでも <code>escape()</code> 関数が使えるようになります。ちなみに、パスの先頭の <code>./</code> を抜いてディレクトリ名から指定するとなぜかだめっぽいです。</p>
<p>さらに別のカスタム関数があれば、この <code>module Sass::Script::Functions</code> と <code>end</code> の間に突っ込んでいけばそれぞれ動くみたいです (「みたいです」とか「らしいです」とか「っぽいです」とかばっかりで申し訳ないですが…)。</p>
<pre><code class="language-ruby">module Sass::Script::Functions
def escape(string)
# ...
def yet_another_awesome_function(number)
# ...
end
</code></pre>
<p>こんな感じで便利関数をまとめておけばプロジェクト間で使いまわすことも簡単です。この <code>functions.rb</code> を、もし中身が空っぽでもプロジェクトごとの Sass ディレクトリに必ず置き、watch 時には require するようにする、という運用にしてもいいかなと思ってます。扱いとしては WordPress の <code>functions.php</code> みたいな感じ。</p>
<p>Ruby のパワーを借りればほんとに色んなことができそうなので、夢が広がる一方、どこまでやっていいんだろうとか、運用がちょっと面倒くさそうとか、バグっても直せなくて泣いちゃうかもとか、素直に Compass 使えやとか、色々と懸念もありますが。</p>
<p>あと、じつは <code>escape()</code> 関数は <a href="http://blog.hull.io/post/46243434040/introducing-sass-getunicode">似たようなプラグイン</a> がすでにあったんだけど、そちらは引数の 1 文字目しか見てないのでちょっと違う。やっぱこの手のはマルチバイト圏に暮らす僕たちがこそ頑張りたいですねー。</p>
<p>ヾ(๑╹◡╹)ノ Happy styling!</p>
Google Chrome Frame の開発が終了
2013-06-30T00:00:00Z
https://terkel.jp/archives/2013/06/rip-google-chrome-frame/
<p><a href="http://blog.chromium.org/2013/06/retiring-chrome-frame.html">Googe Chrome Frame の開発終了</a> が発表されました。2014 年 1 月以降はアップデートとサポートもおこなわれないそうです。</p>
<p>HTML に Chrome Frame 用のコードが残っていても、ただちに問題になるということはないと思いますが、これから新たに作るサイトに埋め込む理由はあまりないですし、公開しているサイトで手を入れることが可能なら修正しておくと良いと思います。</p>
<pre><code class="language-html"><!--[if lt IE 9]>
<p class="ie-prompt">お使いのブラウザはバージョンが古いため、サイトを快適にご利用いただけないかもしれません。<a href="http://browsehappy.com/">最新のブラウザにアップグレード</a> するか、<a href="http://www.google.com/chromeframe/?redirect=true">Google Chrome Frame をインストール</a> してください。<</p>
<![endif]-->
</code></pre>
<p>たとえばこのサイトではこのように、古い IE 向けに Chrome Frame のインストールを促すプロンプトを出していました。こういった場合、Chrome Frame へのリンクを消し、代わりに <a href="http://browsehappy.com/">Browse Happy</a> や <a href="http://www.whatbrowser.org/">What Browsers?</a> などに誘導すると良いでしょう。</p>
<pre><code class="language-html"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
</code></pre>
<p>また、このように <code>X-UA-Compatible</code> に Chrome Frame を有効にする指定がある場合は、<code>chrome=1</code> パラメーターを削除します。</p>
<pre><code class="language-html"><meta http-equiv="X-UA-Compatible" content="IE=edge">
</code></pre>
静的な Google マップを JavaScript API で差し替える
2013-07-06T00:00:00Z
https://terkel.jp/archives/2013/07/google-static-maps-and-javascript-api/
<p><a href="https://developers.google.com/maps/documentation/javascript/">Google Maps JavaScript API</a> で Google マップを埋め込む場合、当然のことながら JavaScript が有効でない環境では何も起こらず真っ白になってしまう。これを回避するため、まず <a href="https://developers.google.com/maps/documentation/staticmaps/">Google Static Maps API</a> を利用して HTML に静的な画像のマップを埋め込み、そのパラメーターを読み出して JavaScript API に渡して、動的マップで静的マップを差し替える、とやるとうまい具合に解決できそうと思ってやってみた。</p>
<pre><code class="language-html"><div id="map-container">
<img src="http://maps.googleapis.com/maps/api/staticmap?markers=35.6604005,139.7290428&zoom=14&size=480x320&sensor=false" alt="...">
</div>
</code></pre>
<p>まず HTML には <code>img</code> 要素でマップを画像として配置する。静的マップには JavaScript は不要で、このように <code>src</code> 属性でパラメーターを渡すだけで利用できる。位置は座標の代わりに住所でも指定できるし、マーカーやパスなどけっこうカスタマイズもできる。<code>alt</code> には地図の用途に応じて、たとえば駅からの道順などを入れましょう。</p>
<p>で、この <code>src</code> のパラメーターをパースして JavaScript API に渡す。まずは API の読み込み。</p>
<pre><code class="language-html"><script src="http://maps.google.com/maps/api/js?language=ja&sensor=false"></script>
</code></pre>
<p>そして静的マップからのパラメーターの読み出しとマップの生成。</p>
<pre><code class="language-javascript">function initGoogeMap () {
var mapContainer = document.getElementById('map-container'),
mapImageSrc = mapContainer.getElementsByTagName('img')[0].getAttribute('src'),
mapParams = decodeURIComponent(mapImageSrc.split('?')[1]).split('&'),
mapData = {},
latLng,
mapOptions,
map,
marker,
markerLatLng,
i,
len,
pair;
for (i = 0, len = mapParams.length; i < len; i++) {
pair = mapParams[i].split('=');
mapData[pair[0]] = pair[1];
}
markerLatLng = mapData.markers? mapData.markers.split(','): null;
latLng = mapData.center? mapData.center.split(','): markerLatLng;
mapOptions = {
center: new google.maps.LatLng(latLng[0], latLng[1]),
zoom: +mapData.zoom || 16
};
map = new google.maps.Map(mapContainer, mapOptions);
if (mapData.markers) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(markerLatLng[0], markerLatLng[1]),
map: map
});
}
}
window.onload = initGoogeMap;
</code></pre>
<p>ちょっと雑な気もするけど、<code>center</code> または <code>markers</code> の座標と <code>zoom</code> だけを想定した例だとだいたいこんな感じだと思う。これで <code><div id="map-container"></code> の中身が JavaScript API で書き換えられるので、静的マップは削除される。パラメーターの内容によってはもうちょっと複雑になると思うけど、やることは同じで、静的マップの <code>src</code> 属性をパースして JavaScript API に渡すだけ。</p>
<p>これで、JavaScrpt 無効時には静的な画像のマップ、有効時にはインタラクティブなやつ、という出し分けができる。</p>
IE8 で擬似要素のスタイルの動的な更新ができない
2013-07-27T00:00:00Z
https://terkel.jp/archives/2013/07/redraw-pseudo-element-style-ie8/
<p>JavaScript で要素のクラス属性を操作してスタイルを変更するような場合、IE8 には <code>:before</code>/<code>:after</code> 擬似要素のスタイルが再描画されないというバグがある。</p>
<pre><code class="language-html"><p>
<a href="#" class="selected">One</a>
<a href="#">Two</a>
<a href="#">Three</a>
<a href="#">Four</a>
</p>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script>
$('p').each(function () {
var $links = $(this).find('a'),
i = $links.filter('.selected').eq(0).index(),
len = $links.length;
function selectItem () {
i = (len - i > 1)? i + 1: 0;
$links.removeClass('selected');
$links.eq(i).addClass('selected');
}
setInterval(selectItem, 3000);
});
</script>
</code></pre>
<p>たとえばこんなふうに、一定時間ごとに <code>selected</code> というクラスを持つ要素が切り替わるようなスクリプトがあって、その要素の <code>:before</code> 擬似要素にスタイルを書く、という場合。</p>
<pre><code class="language-css">a:before {
background-color: silver;
content: "";
display: inline-block;
height: 1em;
width: 1em;
}
a.selected {
background-color: yellow;
}
a.selected:before {
background-color: green; /* not working in IE8 */
}
</code></pre>
<p>グリーンのボックスを持ったリンクが 3 秒ごとに切り替わっていくはずだけど、IE8 では <code>:before</code> で生成したボックスのスタイルが更新されず、初期状態のグレーのまま変化しない。</p>
<p>これを更新させるには、<code>content</code> プロパティの値になんらかの変更を加える必要がある。</p>
<pre><code class="language-css">a:before {
background-color: silver;
content: "";
}
a.selected:before {
background-color: green;
content: " ";
}
</code></pre>
<p>このように空文字列から空白文字に変更するか、</p>
<pre><code class="language-css">a:before {
background-color: silver;
content: "";
}
a.selected:before {
background-color: green;
content: "" "";
}
</code></pre>
<p>あるいは空文字列を追加するのでもいい。</p>
<ul>
<li><a href="https://terkel.jp/demo/pseudo-element-ie8.html">Demo: IE8 で擬似要素のスタイルの動的な更新ができない</a></li>
</ul>
<p><a href="http://stackoverflow.com/a/8852418">Stack Overflow の回答</a> が参考になったけど、サンプルがちょっとわかりづらかった。</p>
<p>IE8 には <a href="http://www.pixelastic.com/blog/255:ie8-ghost-pseudo-elements"><code>:hover:before</code> (または <code>:hover:after</code>) のスタイルが適用されない</a> というバグがあって、<code>:hover</code> になんらかのスタイルを指定することで回避できるけど、この <code>content</code> 上書きパターンでもいける。スクリプトによる属性の更新とホバーやフォーカスなどが重なると挙動があやしくなることもあるけど、おおむね機能してるっぽいし、正直これ以上あまり深追いしたくない…</p>
MathSass v0.9.1
2013-09-16T00:00:00Z
https://terkel.jp/archives/2013/09/mathsass-v0-9-1/
<p>Sass の数学関数ライブラリ、<a href="https://github.com/terkel/mathsass">MathSass</a> を少しアップデートした。</p>
<ul>
<li><a href="https://github.com/terkel/mathsass">terkel/mathsass · GitHub</a></li>
</ul>
<p>おもな変更は <code>log()</code> の実装で、これにより <code>pow()</code> の指数に小数が使えるようになった。また <code>log()</code> に必要な <code>frexp()</code> と <code>ldexp()</code>、定数 <code>$LN2</code> と <code>$SQRT2</code> も追加。</p>
<p>今回も <a href="http://blog.livedoor.jp/dankogai/archives/51518565.html">404 Blog Not Found:javascript - Mathを再発明してみた</a> の JavaScript 実装を参考にした、というよりほぼ JS を Sass に翻訳しただけです。dankogai さんありがとうございます。</p>
<p>あと小さなアップデートとして <code>atan2($y, $x)</code> の <code>$x</code> が負のゼロ (-0) の場合の結果を修正した。Sass でゼロが正か負かを判別するには <code>1/-0.0 == 1/0</code> という式が必要みたいで、引数に渡すときは <code>-0</code> ではなく <code>-0.0</code> とする必要がある。</p>
<pre><code class="language-scss"> -0 == 0 // true
-0.0 == 0 // true
1/-0 == 1/0 // true
1/-0.0 == 1/0 // false
</code></pre>
<p>Compass を使えば <code>pow()</code> の指数に小数使うとかふつうにできるんだけど、なるべくあれを使いたくないという人は僕だけではないだろうし、頭の体操にもなるし、というふうに自分を納得させつつ作業した。</p>
<p>そして今回もちゃんとした数学の知識がないまま突き進んでるので、どうやら期待した値が得られているようだけど自分が何をやっているのかはよくわかっていないという状態で、まじで誰かに添削してほしいです…</p>
v5
2014-01-01T00:00:00Z
https://terkel.jp/archives/2014/01/v5/
<p>久々にこのサイトをリデザインしました。5 代目のテーマです。</p>
<p>もっとも変えたかったところはページのヘッダー部分で、ここをすっきりさせて、記事タイトルが前面に出るようにしたかった。結果、ロゴは <a href="http://www.google.com/fonts/specimen/Open+Sans">Open Sans</a> のイタリックにし、ナビゲーションはフッターに移動しました。ただ about ページへのリンクはページ前半にあった方がいいような気もするので、そのへんはもう少し変えるかも。</p>
<p>いままであった検索フォーム、広告、ソーシャル系などは改めて再検討する予定で、いったん削除しました。そのほかマークアップ、とくに Microdata ももうちょっと見直します。</p>
<p>タイポグラフィ的には、Open Sans とヒラギノ角ゴ、メイリオの組み合わせというベースは従来どおり。ソースコードは <a href="http://www.google.com/fonts/specimen/Ubuntu+Mono">Ubuntu Mono</a>、引用はヒラギノ明朝と游明朝にしてみました。スペーシングなどはあまり変えてないです。</p>
<p>あと気づかれなさそうな変更点として、<code>title</code> 要素の記事タイトルとブログ名の区切りを en dash から middle dot (<code>&#xB7;</code>) に変えました。最近の好み。</p>
<p>Sass のソースコードは <a href="https://github.com/terkel/terkel.jp-stylesheets">GitHub のリポジトリ</a> で引き続き公開しています。このリポジトリ、いままでは最初に公開したっきりあまり更新してこなかったんですが、最近はかなり日常的に Git を使うようにもなってきたので、もう少し頑張ります。</p>
<p>ここ数か月わずらっていた「デザインのダサさが気になってブログを更新したくない」という症状が少し落ち着いたので、今年は書くよ!</p>
横に水平線のあるテキスト
2014-01-09T00:00:00Z
https://terkel.jp/archives/2014/01/text-with-horizontal-line/
<figure class="-small">
<img decoding="async" alt="" src="https://terkel.jp/img/[email protected]" width="640" height="240" />
<figcaption>図1:横に水平線のあるテキストの例</figcaption>
</figure>
<p>おもに見出しなどで見かける、テキストの左右 (またはそのどちらか) に水平線を配置したスタイル。これを CSS で実現する方法について考えてみました。</p>
<ul>
<li><a href="https://terkel.jp/demo/text-with-horizontal-line.html">Demo: 横に水平線のあるテキスト</a></li>
</ul>
<h2>重ねて隠すパターン</h2>
<p>まず最初は、1 本の水平線を幅いっぱいに配置した上で、テキストに重なる部分を隠す、という方法です。</p>
<pre><code class="language-html"><h2><span>Hello</span></h2>
</code></pre>
<p>マークアップはこのように二重の要素が必要です。外側の <code>h2</code> 要素の擬似要素で水平線を作り、内側の <code>span</code> 要素に背景色を指定してテキスト部分を隠します。</p>
<pre><code class="language-css">h2 {
position: relative;
text-align: center;
}
h2:before {
border-top: 1px solid;
content: "";
position: absolute;
top: 50%;
left: 0;
width: 100%;
}
h2 span {
background-color: white;
display: inline-block;
padding: 0 0.5em;
}
</code></pre>
<p>コードもさほど複雑ではなく、悪くないように思えます。しかし背景が単色である必要があり、画像の場合には使えません。また単色の場合でも、祖先要素と同じ色をその都度指定する必要があり、使いまわす上でやや難があります。もちろんマークアップを二重にしなければいけない点もマイナスです。</p>
<h2>はみ出させて隠すパターン</h2>
<p>次は、内側の要素の擬似要素で大きなサイズの水平線を作り、外側の要素ではみ出した部分を隠す方法。マークアップは重ねて隠すパターンと同じく二重になっている必要があります。</p>
<pre><code class="language-css">h2 {
overflow: hidden;
text-align: center;
}
h2 span {
display: inline-block;
padding: 0 0.5em;
position: relative;
}
h2 span:before,
h2 span:after {
border-top: 1px solid;
content: "";
position: absolute;
top: 50%;
width: 99em;
}
h2 span:before {
right: 100%;
}
h2 span:after {
left: 100%;
}
</code></pre>
<p>水平線は内側の <code>span</code> 要素の <code>:before</code> と <code>:after</code> 擬似要素を左右に配置して表現します。これらに <code>99em</code> など充分な幅を持たせ、はみ出した分は外側の <code>h2</code> 要素に指定した <code>overflow: hidden</code> により切り取ります。もちろん擬似要素の幅は <code>999%</code> とか <code>9999px</code> とかでもいいです。</p>
<p>重ねて隠すパターンと比べると、コードはやや複雑なものの、背景のスタイルを問わないという利点があります。しかし外側の要素に指定する <code>overflow</code> プロパティにはマージンの相殺やドロップシャドウの描画などで子要素への副作用があり、できれば利用を避けたいところです。また擬似要素の幅にいわゆるマジック・ナンバーというか、論理的ではない値を指定しなければいけない点に気持ち悪さもあります。二重のマークアップがいまいちなのは重ねて隠すパターンと同じ。</p>
<h2>Flexbox パターン</h2>
<p>最後は <a href="http://dev.w3.org/csswg/css-flexbox/" title="CSS Flexible Box Layout Module Level 1"><strong>flexbox</strong></a> (flexible box) を利用したパターンです。</p>
<pre><code class="language-html"><h2>Hello</h2>
</code></pre>
<p>マークアップはこのとおり 1 つの要素でいいです。</p>
<pre><code class="language-css">h2 {
display: flex;
align-items: center;
text-align: center; /* for no-flexbox browsers */
}
h2:before,
h2:after {
border-top: 1px solid;
content: "";
display: inline; /* for IE */
flex-grow: 1;
}
h2:before {
margin-right: 0.5em;
}
h2:after {
margin-left: 0.5em;
}
</code></pre>
<p>(CSS の flexbox 関連プロパティは、現時点では多くの環境でベンダー接頭辞が必要ですが、このコード例では記述を省略しています。ベンダー接頭辞を含むコードは <a href="https://terkel.jp/demo/text-with-horizontal-line.html">デモ</a> で確認してみてください)</p>
<p>まず <code>display: flex</code> によって <code>h2</code> 要素が「flex コンテナー」になり、その子要素が「flex アイテム」になります。水平線を表現するのは <code>h2</code> 要素の <code>:before</code> と <code>:after</code> 擬似要素です。「flex コンテナーの直接の子要素であるテキストは匿名の flex アイテムに包まれる」という仕様なので、「左の水平線」「テキスト」「右の水平線」という 3 つの flex アイテムが並ぶことになります。</p>
<p><code>align-items</code> は flex アイテムの並ぶ方向に対して垂直方向のアラインメントを指定するプロパティです。この値を <code>center</code> とすることでテキストと水平線が上下中央に配置されます。また <code>flex-grow: 1</code> によって、左右の余ったスペースを埋めるかたちで水平線が広がります。なお、IE10 と 11 では擬似要素の <code>display</code> プロパティに <code>inline</code> <code>block</code> <code>inline-block</code> のいずれかを指定しないと表示されないという現象があり、あわせて指定しています。</p>
<p>この flexbox パターンは多くの点で前の 2 パターンより優れています。まず、祖先要素と同じスタイルを繰り返す必要もなく、子要素のスタイルに影響を与えることもない、ほかの要素から独立した可搬性の高いスタイルである点。そして、本来は必要のない部分を描画をした上で隠すといった遠回りなアプローチではなく、「テキストの左右にコンテンツ幅いっぱいの水平線がある」という本来のデザイン意図をそのまま論理的にコードで表現できている点。</p>
<p>余分なマークアップを必要としないところも大きな利点ですが、それはセマンティクス上の理由もさることながら、こういったスタイルの可搬性や論理的な表現のためにも重要だと思います。</p>
<p>flexbox の仕様は二転三転している上、ブラウザーの実装状況も複雑ですが、こういったほかへの影響の少ないちょっとした装飾から少しずつ採用を進めてみるのもいいんじゃないかと思います。</p>
Bed: Expanded Edition
2014-01-26T00:00:00Z
https://terkel.jp/archives/2014/01/bed-expanded-edition/
<figure class="-small">
<img decoding="async" alt="Five Thirty – Bed: Expanded Edition" src="https://terkel.jp/img/bed.png" width="500" height="500" />
</figure>
<p>ファイヴ・サーティ(Five Thirty)が1991年にリリースした唯一のアルバム、<a href="http://www.amazon.co.jp/gp/product/B00EYUIQM6/ref=as_li_ss_tl?ie=UTF8&camp=247&creative=7399&creativeASIN=B00EYUIQM6&linkCode=as2&tag=terkel-22">“Bed”のエクスパンデッド・エディション</a>が出た。リマスターされたアルバムとシングル収録曲、BBCでのライヴ音源4曲、そして未発表のデモ音源6曲を収録したCD 2枚組。</p>
<p>で、このリマスター音源の出来がとにかくひどい。リンク張っといてなんだけど、はっきり言って買っちゃいけないレベル。まずとにかく曲間のつなぎがめちゃくちゃで、イントロの数秒が削除されちゃってたり、本来はクロスフェードの曲がなぜかいったんフェードアウトしてたり。盤起こしと思われるひどい音質の曲もある。これ担当者は絶対に完成品をプレイバックしてないと思う。なんかのソフトにぶっ込んでプリセットのエフェクトかけたのをそのまま出したみたいな感じ。</p>
<p>そういうわけで買う理由があるとするならライヴ音源とデモ音源なんだけど、こっちも正直あまりぱっとしない。BBCの音源はとくにライヴならではのスリリングな演奏とかスタ録と大きく異なるアレンジが聴けるとかでもなく、あまり面白みが感じられなかった。未発表曲のデモには悪くないのもあるけど、あまり練られていないジャムっぽい曲も多い。ラスト・シングル“You”に収録された‘Cuddly Drug’や‘Slow Train into the Ocean’みたいなクオリティを期待してただけに、ちょっと残念。</p>
<p>また、公式にリリースされた音源のうち本作に収録されていないものもいくつかある。</p>
<p>まず、East/Westからデビューする以前、1985年にOther Recordsから出したEP “Catcher in the Rye”の4曲。内容はかなりヘボいんだけど微笑ましいというか。このEPの曲はすべてコンピ盤<a href="http://www.amazon.co.jp/gp/product/B000024LP0/ref=as_li_ss_tl?ie=UTF8&camp=247&creative=7399&creativeASIN=B000024LP0&linkCode=as2&tag=terkel-22">The Cutting Edge</a>に収録されている。</p>
<p>それから1990年にMidnight Musicから出た“Alvin Lives (in Leeds)”というコンピ盤に、ジョージ・ハリソンの‘My Sweet Lord’のカヴァーが収録されているけど、これも未収録。ヴォーカルはポールで、原曲に近いアコースティックな感じではじまって後半はギターがワウワウ言うという、まあ彼ららしい出来。これはCDも出てるんだけどAmazonのカタログには載ってないっぽい。</p>
<p>同じく1990年の“Happy Daze Volume Two”というコンピには‘Something’s Got to Give’の別ヴァージョンが収録されてるんだけど、どうやらこのCDはどれも不良盤らしく、全編にノイズが入っててまともに聴けない。</p>
<p>“Bed”のCDは当時から音がショボい印象があったけど、今回のひどいリイシューを経験して改めて聴いてみると、音圧が低いだけで必ずしも音が悪いわけではないと感じた。1990年頃のCDはどれも音が悪い、リマスター万歳! という思い込みは捨てることにしました。</p>
Cargo Cult CSS の日本語訳
2014-02-14T00:00:00Z
https://terkel.jp/archives/2014/02/translation-of-cargo-cult-css/
<p>昨年の 11 月に書かれた <a href="http://www.kapowaz.net/articles/cargo-cult-css" title="kapowaz: Cargo Cult CSS">Cargo Cult CSS</a> という記事を<a href="http://terkel.github.io/cargo-cult-css/" title="カーゴ・カルト CSS">日本語に翻訳して公開しました</a>。本当は昨年中に公開するつもりが、行き詰まったり放置期間を挟んだりしてるうちにずいぶん時間が経ってしまった。</p>
<p>内容は読んでいただくとわかるとおり、昨今の CSS フレームワークのあり方をかなり厳しく批判するもの。記事中では「カーゴ・カルト」というキーワード自体については説明していないけど、<a href="http://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%BC%E3%82%B4%E3%83%BB%E3%82%AB%E3%83%AB%E3%83%88" title="カーゴ・カルト - Wikipedia">Wikipedia</a> などを読めばつかめると思う。また記事からリンクしている <a href="http://neurotheory.columbia.edu/~ken/cargo_cult.html">“Cargo Cult Science” - by Richard Feynman</a> というドキュメントは、『<a href="http://www.amazon.co.jp/gp/product/4006030053/ref=as_li_ss_tl?ie=UTF8&camp=247&creative=7399&creativeASIN=4006030053&linkCode=as2&tag=terkel-22" title="Amazon.co.jp: ご冗談でしょう、ファインマンさん〈上〉 (岩波現代文庫): リチャード P. ファインマン, Richard P. Feynman, 大貫 昌子: 本">ご冗談でしょう、ファインマンさん</a>』で有名な物理学者リチャード・フィリップス・ファインマンがカリフォルニア工科大学の卒業式で述べた式辞で、<a href="http://www.amazon.co.jp/gp/product/4006030061/ref=as_li_ss_tl?ie=UTF8&camp=247&creative=7399&creativeASIN=4006030061&linkCode=as2&tag=terkel-22" title="Amazon.co.jp: ご冗談でしょう、ファインマンさん〈下〉 (岩波現代文庫): リチャード P. ファインマン, Richard P. Feynman, 大貫 昌子: 本">同書の下巻</a>で日本語訳が読めます。</p>
<p>英語のドキュメントの日本語訳の公開はずっとやりたいと思っていたものの今回がはじめてでした。簡単ではないし時間がかかるけど、じっくり推敲すればちょっとずつ良くなっていくのが感じられてけっこう楽しいです。今後も機会があればやっていきたいと思ってます。</p>
<p>ちなみに翻訳については『<a href="http://www.amazon.co.jp/gp/product/4480081976/ref=as_li_ss_tl?ie=UTF8&camp=247&creative=7399&creativeASIN=4480081976&linkCode=as2&tag=terkel-22" title="Amazon.co.jp: 英文翻訳術 (ちくま学芸文庫): 安西 徹雄: 本">英文翻訳術</a>』の多大な影響を受けています。個人的に本当に目から鱗の内容で、自分も翻訳をやってみようと考えるきっかけになった本です。</p>
文書の先頭へのリンク
2014-03-02T00:00:00Z
https://terkel.jp/archives/2014/03/top-of-the-document/
<p>文書の特定箇所をターゲットとするハイパーリンク、いわゆる「ページ内リンク」で、<code><a href="#top">Top of the Page</a></code> のように <code>top</code> というフラグメント識別子を指定すると、それは文書の先頭へのリンクになります。このとき <code>top</code> という名前を持った要素がページの先頭に存在する必要はありません (もし存在すればその要素へのリンクになる)。</p>
<p>…という<a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#scroll-to-fragid" title="6.6.9 Navigating to a fragment identifier — HTML Standard">仕様</a>があることを、つい最近 <a href="https://developer.mozilla.org/ja/docs/Web/HTML/Element/a#attr-href" title="a 要素 - HTML | MDN">MDN</a> 経由ではじめて知りました。どうやらもともと一部のブラウザーの独自仕様だったものが HTML5 において仕様に定められた、という経緯のようです。</p>
<p>文書の先頭へのリンクの実装方法としては、コンテンツ全体をラップする <code>#wrapper</code> や <code>#container</code>、あるいは文書の最上部に位置する <code>#header</code> といったフラグメントへのリンクというかたちで実現する例がよく見られます。しかしこれらの手法は、結果的には目的を果たせているように見えるものの、マークアップとしてはあくまで「コンテンツ全体」や「ヘッダー」へのリンクであり、「文書の先頭」へのリンクという本来の意図とは異なるものです。その点、<code>top</code> フラグメント識別子を使うと、そのリンクが文書の先頭へナビゲートすることを目的としたものである、ということを明示できます。</p>
<p>一方で、フラグメント識別子として <code>top</code> というキーワードが予約語のような扱いになってしまう (もし文書中に名前として使えば先頭に戻るリンクが機能しなくなる) のはいまいちです。そう考えると、<code><a href="#">Top of the Page</a></code> という空のフラグメント識別子へのリンク (これも <code>top</code> と同様の動作をすると仕様に記されている) を使うか、あるいは <code>button</code> 要素に JavaScript でスクロール処理を持たせる、という方法がいいかなあという気がします。</p>
グラデーションとテキスト・シャドウによるリンクの下線
2014-04-06T00:00:00Z
https://terkel.jp/archives/2014/04/link-underline/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/link-underline.png" width="640" height="200" />
</figure>
<p><a href="https://medium.com/designing-medium/7c03a9274f9">Crafting link underlines on Medium</a> などで紹介されている、リンクの下線をグラデーションの背景とテキスト・シャドウで表現する手法をこのサイトでも試してみました。やろうとしているのは、下線の色、位置、サイズのコントロールと、ディセンダーと直接まじわらずグリフをまたぎ越すような表現。</p>
<pre><code class="language-css">a {
background: linear-gradient(#e00000 50%, transparent 50%) 0 1.25em repeat-x;
background-size: 1px 2px;
text-shadow:
0 1px white,
0 -1px white,
1px 0 white,
1px 1px white,
1px -1px white,
-1px 0 white,
-1px 1px white,
-1px -1px white;
}
@media print, (-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 1.25dppx) {
a {
background-size: 1px 1px;
}
}
.backgroundsize.cssgradients a {
text-decoration: none;
}
</code></pre>
<p>まず、下線の色と <code>transparent</code> で塗り分けた垂直方向のグラデーションを用意し、水平方向に繰り返します。垂直方向の位置は <code>background-position</code> で指定するわけですが、その基準はフォントやブラウザーによって異なり、かなり微妙な調整が必要。太さは <code>background-size</code> でコントロールでき、画像なので高 DPI の環境では 1px より細くすることも可能です。</p>
<p>ディセンダーと重なる部分は、ボディの背景と同じ色の <code>text-shadow</code> を 8 方向に配置して表現します。そのため背景が写真などの場合は使えません。</p>
<p>なお、このスタイルは CSS グラデーションと <code>background-size</code> がともにサポートされている必要があるので、<a href="http://modernizr.com/">Modernizr</a> で機能判定をした上でデフォルトの下線を消すようにしています。</p>
<ul>
<li><a href="https://terkel.jp/demo/link-underline.html">Demo: グラデーションとテキスト・シャドウによるリンクの下線</a></li>
</ul>
<p>和文まじりの場合はとくに位置の調整が面倒なので、どんな場面にも気軽に使えるというものではないですが、テキスト主体のサイトの本文などでは検討してもいいかなと思いました。</p>
アイコンの実装方法
2014-06-24T00:00:00Z
https://terkel.jp/archives/2014/06/how-to-implement-icons/
<p>ウェブページにおけるアイコンの実装方法はさまざまです。マークアップに <code>img</code> 要素を配置する方法もあるし、CSS から背景画像やアイコン・フォントを使う方法もあります。そういった中からどの方法を採用すべきかを判断するには、HTML Standard の <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/edits.html#alt">Requirements for providing text to act as an alternative for images</a> にあるとおり、「そのアイコンの意味を伝えるテキストが付随するかどうか」を考える必要があります。</p>
<h2>テキストが付随しないアイコン</h2>
<figure class="-small">
<img decoding="async" alt="" src="https://terkel.jp/img/implementing-icons-1.png" width="640" height="360" />
</figure>
<p>家のアイコンだけでホームページへのリンクを表す場合など、ラベルとしてのテキストが存在しないアイコンは、自分自身でその意味を伝える必要があります。こういったアイコンの実装方法は限られていて、ほぼ 1 つしかありません。<code>alt</code> 属性に代替テキストとしてラベルを指定した <code>img</code> 要素をマークアップに配置する方法です。</p>
<pre><code class="language-html"><a href="/">
<img alt="Home" src="icon-home.png">
</a>
</code></pre>
<p>CSS による背景画像やアイコン・フォントで表現する方法もありますが、その画像やフォントが意図どおりに読み込まれなかった場合に意味がまったく伝わらなくなってしまいます。必ず、適切な <code>alt</code> 属性をともなった <code>img</code> 要素をマークアップに配置すべきです。</p>
<p>なお、HTML 文書にアイコン画像を埋め込む方法としては、<code>img</code> 要素のほかにインラインの <code>svg</code> 要素も考えられます。ここでは詳しく触れませんが、その場合、<a href="http://www.w3.org/TR/SVG11/access.html#SVGAccessibilityGuidelines"><code>title</code> や <code>desc</code> といった要素による代替テキスト</a>のほか、<a href="http://defghi1977-onblog.blogspot.jp/2013/01/svg_21.html"><code>foreignObject</code> 要素などによるフォールバック</a>も考慮する必要があるでしょう。</p>
<h2>テキストが付随するアイコン</h2>
<figure class="-small">
<img decoding="async" alt="" src="https://terkel.jp/img/implementing-icons-2.png" width="640" height="360" />
</figure>
<p>家のアイコンのすぐ下に Home という文字列があるような、その周囲にラベルとしてのテキストがあるアイコンはどうでしょうか。この場合、ユーザーに意味を伝える目的はテキストが果たしており、アイコンの役割はテキストを補助することであると言えます。そのため、アイコンの実装方法の自由度は高いです。</p>
<p>まず、マークアップに画像を埋め込む方法。この場合、代替テキストは空文字列である必要があります。</p>
<pre><code class="language-html"><a href="/">
<img alt="" src="icon-home.png">
Home
</a>
</code></pre>
<p>CSS を利用するなら、擬似要素とスプライト画像による方法が手軽です。マークアップにはテキスト以外に追加の要素や属性は必要ありません。</p>
<pre><code class="language-html"><style>
a[href="/"]:before {
background: url(sprites.png) no-repeat 0 -160px;
content: "";
display: inline-block;
height: 32px;
width: 32px;
}
</style>
<a href="/">
Home
</a>
</code></pre>
<p>アイコン・フォントも利用できますが、スクリーン・リーダーを考慮した追加のマークアップなど、<a href="http://hail2u.net/documents/bulletproof-icon-fonts.html">安全でアクセシブルな実装</a>を実現するにはそれなりの手間がかかります。</p>
<pre><code class="language-html"><style>
.icon-home:before {
font-family: "icomoon";
content: "\e608";
}
</style>
<a href="/">
<span class="icon-home" aria-hidden="true"></span>
Home
</a>
</code></pre>
<p>これら CSS を利用した実装は、マークアップに画像を埋め込む手法に比べ、パフォーマンスやメンテナビリティに優れています。しかし、画像やアイコン・フォントが利用できない環境ではアイコンは表示されないため、あくまでラベルとしてのテキストが付随する場合にのみ採用すべき方法です。</p>
<h2>レスポンシブなラベル</h2>
<p>いわゆるレスポンシブ・デザインでは、こういったアイコンに付随するテキストの有無を、画面のサイズなどによって切り替えたい場合があります。画面が狭いときはアイコンのみで、十分に広ければテキストも表示、というように。</p>
<p>結論から言うと、これを HTML と CSS だけで実装するとどうしても問題の生じる可能性があるため、JavaScript によって DOM を操作するのがより良い実装と考えます。以下、それぞれについて検証してみます。</p>
<h3>CSS でテキストの表示を切り替える</h3>
<p>テキストが表示されていない状態を考慮し、マークアップには <code>alt</code> 属性にラベルを指定した <code>img</code> 要素を配置します。ラベルとなるテキストは <code>data-*</code> 属性などに保存しておき、メディア・クエリに応じて擬似要素と <code>content</code> プロパティで表示を切り替える、というのが CSS による実装パターンです。</p>
<pre><code class="language-html"><style>
@media (min-width: 481px) {
[data-label-text]:after {
content: attr(data-label-text);
}
}
</style>
<a href="/">
<img alt="Home" src="icon-home.png">
<span aria-hidden="true" data-label-text="Home"></span>
</a>
</code></pre>
<p>マークアップの <code>alt</code> 属性と CSS の生成内容で同じテキストが重複することになり、スクリーン・リーダーのユーザーを混乱させる可能性がありますが、この問題は <code>aria-hidden</code> 属性を持った要素を利用することで回避できます。</p>
<p>しかし、視覚系ブラウザーで画像が読み込まれなかった場合、同じテキストが繰り返し表示されてしまいます (この例では Home Home という表示になる)。</p>
<p>逆に、<code>img</code> 要素の <code>alt</code> 属性を空文字列とし、マークアップにあらかじめ含めたテキストの表示を CSS で切り替えるという実装でも、視覚系ブラウザーで画像が読み込まれなかった場合になにも表示されなくなってしまい、やはり問題があります。</p>
<p>このように、HTML と CSS だけによるアプローチでは、画像が利用できない環境に対応しきれません。</p>
<h3>JavaScript で DOM を書き換える</h3>
<p>理想的な実装は、画面が狭いときは <code>alt</code> 属性の指定された <code>img</code> 要素のみ、広いときは <code>alt</code> が空文字列の <code>img</code> とテキスト、というふうにマークアップを切り替える、ということになります。</p>
<pre><code class="language-html"><!-- 画面が狭いときは alt ありの img のみ -->
<a href="/">
<img alt="Home" src="icon-home.png">
<span class="text"></span>
</a>
<!-- 画面が広いときは alt が空の img とテキスト -->
<a href="/">
<img alt="" src="icon-home.png">
<span class="text">Home</span>
</a>
</code></pre>
<p>そこで以下のような JavaScript を考えてみました。</p>
<pre><code class="language-html"><!-- matchMedia() polyfill - https://github.com/paulirish/matchMedia.js -->
<script src="matchMedia.js"></script>
<script src="matchMedia.addListener.js"></script>
<script>
/**
* Show/hide icon labels using media queries.
*
* @param {Object} images NodeList of icon images
* @param {String} mqString Media query string
* @param {Boolean} [fallback] Show label text for no-media-queries browsers
* @example
* var navIcons = document.querySelectorAll('nav img');
* responsiveIconLabel(navIcons, '(min-width: 801px)', true);
*/
function responsiveIconLabel (images, mqString, fallback) {
var mqSupported = window.matchMedia && window.matchMedia('only all').matches,
textTemplate = document.createElement('span'),
mql,
mqListeners = [],
i,
len;
textTemplate.className = 'text';
for (i = 0, len = images.length; i < len; i++) {
(function (img) {
var alt = img.alt,
txt = textTemplate.cloneNode(false);
img.parentNode.insertBefore(txt, img.nextSibling);
if (mqSupported) {
mqListeners.push(swapAltText);
} else if (fallback) {
swapAltText(true);
}
function swapAltText (match) {
if (match) {
img.alt = '';
txt.innerHTML = alt;
} else {
img.alt = alt;
txt.innerHTML = '';
}
}
})(images[i]);
}
if (mqSupported) {
mql = window.matchMedia(mqString);
mql.addListener(updateIconLabel);
updateIconLabel(mql);
}
function updateIconLabel (mql) {
var i,
len,
match = mql.matches;
for (i = 0, len = images.length; i < len; i++) {
mqListeners[i](match);
}
}
}
</script>
</code></pre>
<p>使い方は、まずマークアップとして <code>alt</code> 属性にラベルのテキストを指定した <code>img</code> 要素を用意します。</p>
<pre><code class="language-html"><a href="/">
<img alt="Home" src="icon-home.png" class="icon-home">
</a>
</code></pre>
<p>アイコンの画像と、テキストを表示するメディア・クエリ文字列を引数にして、<code>responsiveIconLabel</code> 関数を呼び出します。3 つめの引数ではメディア・クエリをサポートしない環境でテキストを表示するかどうかを指定しています。</p>
<pre><code class="language-javascript">var homeIcon = document.querySelectorAll('.icon-home');
responsiveIconLabel(homeIcon, '(min-width: 801px)', true);
</code></pre>
<p><code>MediaQueryList</code> オブジェクトの <code>matches</code> プロパティにより、指定したメディア・クエリにマッチしていれば <code>img</code> の <code>alt</code> を空にして、代わりにテキストを表示します。これは <code>addListener</code> メソッドにより、メディア・クエリの結果が変更されるたびに更新されます。</p>
<pre><code class="language-html"><a href="/">
<img alt="" src="icon-home.png" class="icon-home">
<span class="text">Home</span>
</a>
</code></pre>
<p>なお <a href="https://developer.mozilla.org/ja/docs/Web/API/window.matchMedia"><code>window.matchMedia</code></a> をサポートしない環境のために <a href="https://github.com/paulirish/matchMedia.js"><code>matchMedia()</code> polyfill</a> を読み込んでいます。</p>
<ul>
<li><a href="https://terkel.jp/demo/responsive-icon-label/demo.html">Demo</a></li>
<li><a href="https://gist.github.com/terkel/a093696931fa38f55ae6">Source</a></li>
</ul>
MathSass v0.9.3
2014-07-05T00:00:00Z
https://terkel.jp/archives/2014/07/mathsass-v0-9-3/
<p>しばらく放置してた <a href="https://github.com/terkel/mathsass">MathSass</a> プロジェクトに、<a href="https://github.com/terkel/mathsass/pull/3">Ruby gem 化するプルリクエスト</a> をもらったのでマージした。Ruby gem よくわからないので言われるがままにパブリッシュしたところ、gem の名前が大文字まじりになっており、ちょっと失敗したと思っている。</p>
<p>同時に <a href="http://sassmeister.com/">SassMeister</a> でサポートしてもらえるようにイシューを立てたらその日のうちに採用してもらえた。</p>
<p>その前には <a href="https://github.com/terkel/mathsass/pull/1">npm、Bower、Travis、Grunt、Bootcamp をサポートするプルリクエスト</a> というのももらっていて、意外と気に入ってくれる人がいるようでうれしい。</p>
selector-replace() の利用
2014-07-16T00:00:00Z
https://terkel.jp/archives/2014/07/selector-replace/
<p>近々リリース予定の <a href="https://github.com/sass/sass/blob/2f6ec0044e13407357a04a655684b921bf84b03a/doc-src/SASS_CHANGELOG.md#340-unreleased">Sass 3.4.0</a> では、<code>&</code> が SassScript で使えるようになるほか、セレクター関連の関数が大きく充実する。SassMeister ではすでに使えるので <a href="http://sassmeister.com/gist/ad06a0fe37fe7eb4676c">いくつか試してみた</a> けど、セレクターを置換する<b><code>selector-replace()</code> 関数</b>がかなり便利そう。</p>
<p>使用例としてはまず、ネストしたセレクターで、ルートと直近のセレクターの間に別のセレクターを挿入する、というのが考えられる。</p>
<pre><code class="language-scss">.outer {
color: red;
.inner {
color: green;
@at-root {
#{ selector-replace(&, '.outer', '.outer .foo') } {
color: blue;
}
}
}
}
</code></pre>
<p><code>&</code> で親セレクター <code>.outer .inner</code> を参照し、そのうち <code>.outer</code> を <code>.outer .foo</code> に置換することで、親セレクターの「間」に新たなセレクターを割り込ませるようなかたちになる。</p>
<pre><code class="language-css">.outer {
color: red;
}
.outer .inner {
color: green;
}
.outer .foo .inner {
color: blue;
}
</code></pre>
<p>もうひとつ、汎用的なクラス・セレクターを定義したブロックの中で、要素タイプによる絞り込みができる。</p>
<pre><code class="language-scss">.bar {
.button {
border: 1px solid;
@at-root {
#{ selector-replace(&, ".button", "a.button") } {
text-decoration: none;
}
}
}
}
</code></pre>
<p><code>.button</code> という要素を問わないセレクターを定義し、その中で要素タイプが <code>a</code> だった場合に絞り込んだスタイルを書ける。</p>
<pre><code class="language-css">.bar .button {
border: 1px solid;
}
.bar a.button {
text-decoration: none;
}
</code></pre>
<p>ぱっと思いついたのはこんなところ。どちらの例も、今までだとルートから書き直す必要があったので、けっこう便利になる気がする。</p>
<p>ただ、まだ検証しきれてないけど、単純な置換ではなく <code>@extend</code> と同様のロジックらしく、直感に反する結果になることもある。最初の例で言うと、<code>selector-replace(&, '.outer', '.outer .foo')</code> ではなく <code>selector-replace(&, '.inner', '.foo .inner')</code> とすると、以下の出力になる。</p>
<pre><code class="language-css">.outer .foo .inner,
.foo .outer .inner {
color: blue;
}
</code></pre>
<p><code>@extend</code> 同様、ちょっと理解しづらいので、気をつけないとすぐ複雑になると思う。</p>
<p><a href="http://sass-lang.com/documentation/file.SASS_REFERENCE.html#at-root"><code>@at-root</code></a> はどうやって使えばいいのかいまいちわからなかったけど、これでようやく活用できそう。</p>
Srcset and sizes の日本語訳
2014-09-09T00:00:00Z
https://terkel.jp/archives/2014/09/srcset-sizes/
<p>レスポンシブ画像の新しいアプローチである <code>srcset</code> と <code>sizes</code> 属性の入門記事 <a href="http://ericportis.com/posts/2014/srcset-sizes/">Srcset and sizes</a> を日本語に翻訳し、<a href="http://terkel.github.io/srcset-sizes/">srcset と sizes</a> として公開しました。</p>
<figure>
<img decoding="async" alt="srcset と sizes" src="https://terkel.jp/img/srcset-sizes.png" width="1536" height="1024" />
</figure>
<p>絵本風のイラストレーションと平易な文章のためとっつきやすそうに見えるものの、内容はかなりややこしいです。というか「レスポンシブ画像がいかにややこしいか」がテーマのようなもので、僕も最初に読んだときはすんなり理解できませんでした。またレスポンシブ・レイアウトをある程度理解していることを前提としているし、ビューポートや画面密度といったキーワード、<code>vw</code> 単位といったものはとくに説明されずに話が進むので、わりかしハードルは低くないです。しかし、いま HTML を書いているひとの多くが直面しているであろうレスポンシブ画像の問題について、入門記事としてうってつけなのは間違いないと思います。とくに、製作者とブラウザーで画像の描画について知っていることが食い違っているというあたりはわかりやすくていいです。</p>
<p>記事中の画像は、<a href="http://scottjehl.github.io/picturefill/">Picturefill</a> ライブラリのちからを借りて、実際に <code>srcset</code> と <code>sizes</code> を使っています。Picturefill はいくつかのプロジェクトで使ってみましたが、じゅうぶん実用に耐えるという感触です。</p>
<p>イラストレーションの言葉も日本語に訳されていますが、これは著者のエリックさんがみずから描いてくれたものです。翻訳の許諾を求めるために連絡したところ、快諾してくれたうえ、「おれ、ハイスクール時代に日本語ちょっとやってたし、絵も描き直すよ!」と申し出てくれました。サンキュー、エリック!</p>
和欧混植の条件分岐
2014-09-26T00:00:00Z
https://terkel.jp/archives/2014/09/conditional-font-families/
<p>CSS によるフォントの和欧混植は、たいがいの場合、<code>font-family</code> プロパティを使ったシンプルな実装で間に合う。ファミリ名をカンマ区切りのリストとして指定すれば、ユーザーのローカル環境に応じて利用可能なフォントが適切に選択される。</p>
<pre><code class="language-css">html {
font-family:
"Helvetica Neue", "Arial",
"Hiragino Kaku Gothic ProN", "Meiryo",
sans-serif;
}
</code></pre>
<p>しかし、こういったシンプルなアプローチでは実現できないケースもある。「特定の和文フォントが利用可能な場合に、特定の欧文フォントと組み合わせて利用したい」というのがそれ。たとえば、「ヒラギノ明朝か游明朝のいずれかが利用できるなら Times と組み合わせて使いたいが、どちらの明朝体も利用できないなら Helvetica とゴシック体の組み合わせを使いたい」とか。これを実現するには、なんらかの方法でユーザーのローカル環境で利用できる和文フォントを検出し、その結果に応じて欧文フォントを指定する、という条件分岐が必要になる。</p>
<p>任意のフォントがローカルにインストールされているかどうかを検出するには、<a href="https://plus.google.com/113463921353776506005/posts/Yf1xtgKchFm">グリフの幅が 0 のフォントを利用する手法</a>が良さそうだったので、僕も <a href="https://github.com/terkel/fontdetect">FontDetect</a> という簡単なライブラリを書いてみた。やっているのは、</p>
<ol>
<li>幅が 0 の A だけのフォントを作り、Data URI で CSS に埋め込む</li>
<li>A のテキストをダミーとして HTML に挿入し、1 のフォントを指定する</li>
<li>目的のフォントファミリを指定し、幅が 0 より大きくなれば true</li>
</ol>
<p>という流れで、最終的にその結果をModernizr みたいに <code>html</code> 要素のクラス属性に書き込んでいる。</p>
<pre><code class="language-javascript">FontDetect.test('mincho', ['Hiragino Mincho ProN', 'Yu Mincho', 'YuMincho']);
</code></pre>
<p>この場合、ヒラギノ明朝か游明朝のいずれかが利用できれば <code>mincho</code>、なければ <code>no-mincho</code> というクラス名が <code>html</code> 要素に追加されるので、これをもとに CSS を書き分ければいい。</p>
<pre><code class="language-css">html {
font-family:
"Helvetica Neue", "Arial",
"Hiragino Kaku Gothic ProN", "Meiryo",
sans-serif;
}
html.mincho {
font-family:
"Times", "Times New Roman",
"Hiragino Mincho ProN", "Yu Mincho", "YuMincho",
serif;
}
</code></pre>
<p>ウェブフォントの時代になり、こと欧文フォントについては、ユーザーのローカル環境を以前ほどには気にかけることが少なくなった。和文ウェブフォントはまだ気軽に使える状況ではないけど、一方で Windows と Mac に游書体が搭載されたり、源ノ角ゴシックがリリースされたりなど、ローカルでの高品位な和文フォントの選択肢は増えてきている。こういった、ウェブでの和欧混植にまつわる新しい状況を、より効果的に利用する方法のひとつとして考えてみた。</p>
擬似要素を利用したベースライン・グリッド
2014-11-08T00:00:00Z
https://terkel.jp/archives/2014/11/baseline-grid-pseudo-elements/
<figure class="-small">
<img decoding="async" alt="" src="https://terkel.jp/img/baseline-grid-1.png" width="512" height="448" />
<figcaption>Fig 1: 擬似要素を利用してテキストをベースライン・グリッドに揃える</figcaption>
</figure>
<p>CSS でテキストをベースライン・グリッドに揃えるとなると、ベースラインの高さに応じて上下のパディングやマージンを調整するアプローチがよく見受けられますが、あまり実用的なものとは言いがたかったと思います。</p>
<pre><code class="language-css">p {
padding-top: 0.30116em;
padding-bottom: 0.19884em;
/* ... */
}
</code></pre>
<p>しかし、<code>::before</code> と <code>::after</code> 擬似要素を利用すると、かんたんにベースライン・グリッドに合わせることができます (Fig 1)。</p>
<pre><code class="language-css">/* Vertical rhythm unit: 0.5rem */
p {
line-height: 1.5rem;
margin: 0.5rem 0;
}
p::before,
p::after {
content: "";
display: inline-block;
height: 1.5rem; /* same as line-height */
}
p::before {
vertical-align: 0;
}
p::after {
vertical-align: -1rem; /* margin-bottom - line-height */
}
</code></pre>
<p>まず最初に、ページを通じて基準になる高さの「単位」を決めます。ここでいう単位は CSS の length の unit ではなく、ページの「縦のリズム」を構成する最小単位のことです。0.5 rem などがわかりやすくて良いと思います。</p>
<p>ボックスの <code>line-height</code> と上下のマージン、パディングは、つねにこの単位の整数倍で指定します。この時点でボックス自体はベースライン・グリッド上に乗りますが、ベースラインの位置は通常のフローのまま (Fig 2)。</p>
<figure class="-small">
<img decoding="async" alt="" src="https://terkel.jp/img/baseline-grid-2.png" width="512" height="448" />
<figcaption>Fig 2: 通常のフローでの配置</figcaption>
</figure>
<p>最初の行の先頭にある <code>::before</code> 擬似要素が <code>inline-block</code> としてベースライン上に配置されていて、かつ <code>line-height</code> と等しい高さを持つので、行ボックスが上方向に押し広げられるかたちで、最初の行のベースラインがグリッドに合います。</p>
<p>2 行目以降も、<code>line-height</code> が「単位」の整数倍であるため、ベースラインはつねにグリッド上に来ることになります。</p>
<p>そして最後の行の末尾にある <code>::after</code> の <code>vertical-align</code> に「単位」の負の整数倍を指定して行ボックスを下方向に押し広げるのに加え、下マージンまたはパディングもやはり「単位」の整数倍とすることで、後続するボックスの上辺をグリッドに揃えることができます。</p>
<p>なお、<code>::before</code> と <code>::after</code> には幅を指定する必要がなく、横方向のレイアウトには影響を与えません。ただし、リスト項目をインライン化したリスト要素 (<code>ol</code>、<code>ul</code>、<code>dl</code>) などでマークアップに改行があると、行頭にスペースが生じる場合があります。これはリスト項目のマークアップの改行を除去したり閉じタグを省略したりすれば回避できます。</p>
<p>もしテーブル要素などでボーダーがあってリズムがずれる場合は、擬似要素の <code>vertical-align</code> をボーダー幅の分だけ調整します (ただし、テーブル要素はボーダーのスタイリングにブラウザーごとの細かな違いがけっこうあり、完璧に揃えるのは難しいかも)。</p>
<pre><code class="language-css">th,
td {
border-bottom: 1px solid silver;
line-height: 1rem;
/* ... */
}
th::before, th::after,
td::before, td::after {
content: "";
display: inline-block;
height: 1rem;
}
th:before,
td:before {
vertical-align: -1px;
}
th::after,
td::after {
vertical-align: -0.5rem;
}
</code></pre>
<p><a href="https://terkel.jp/demo/baseline-grid.html">かんたんなデモ</a> も用意しました。G キーでガイドラインをトグルできます。</p>
<ul>
<li><a href="https://terkel.jp/demo/baseline-grid.html">Demo: CSS baseline grid using pseudo elements</a></li>
</ul>
<p>この擬似要素を使ったアプローチの難点として、<code>::before</code> と <code>::after</code> の両方をつねに必要としてしまうところが挙げられます。もしこれらをほかのスタイルに利用している場合はマークアップを追加するしかないです。</p>
<p>また、画像までベースライン・グリッドに揃えるのはおそらく CSS だけでは無理で、<code>vertical-align</code> を <code>middle</code> などにしたうえで、JavaScript で高さを単位の整数倍に調整するなどのアプローチが必要だと思います。</p>
<p>こういったレイアウトは、やりはじめるとパラノイアックに追求したくなりがちですが、やはりやりすぎはよくないです。すべての要素を完全にベースライン・グリッドに合わせるのは、かなりシンプルなページでも難しいし、もしそれができたとしても、その結果として読みやすいものになるかどうかはまた別なので。</p>
CSS コンポーネント試案
2014-12-07T00:00:00Z
https://terkel.jp/archives/2014/12/css-components/
<p><a href="http://less.carbonfairy.org/post/104312752301">pixivのCSSで使われるクラス名ルール</a>を読んで、僕もここ最近 CSS のコンポーネント設計について似たようなことを考えていたので書いてみる。いまのところ試案で、実際のプロジェクトで実践したことはまだない。</p>
<p>ここでいう「コンポーネント」とは独立したスタイルのブロックの意味で、たとえばヘッダーのナビゲーションとか画像のスライダーとかブログ記事のボディとかを指す。このアプローチの狙いとしては前出の記事とほぼ同じで、これらコンポーネントの「ルート」を明確にし、コンポーネント名が衝突しないようにすること。また管理や共有を考え、特殊な命名規則や不自然なマークアップなどはなるべく避けたいというのもある。Sass などの CSS プリプロセッサーを使う前提だけど、なくてもある程度は使える。</p>
<p>まずマークアップでは、コンポーネントのルートとなる要素に、クラス名と同時に <code>data-component</code> という属性を指定する。コンポーネントのルートもその子孫要素も、クラス名に特別な命名規則は設けない。</p>
<pre><code class="language-html"><div class="imageSlider" data-component>
<div class="viewport"> ... </div>
<div class="nav"> ... </div>
</div>
</code></pre>
<p>CSS セレクターはつねにコンポーネントをルートにして書き、かつクラス名だけではなく、必ず <code>[data-component]</code> という属性セレクターも指定する。</p>
<pre><code class="language-scss">// _imageSlider.scss
.imageSlider[data-component] {
overflow: hidden;
...
.viewport { ... }
.nav { ... }
}
</code></pre>
<p>そして、すべてのコンポーネントをそれぞれ個別のパーシャルとし、ファイル名はそのコンポーネントのクラス名とする。たとえば <code>.imageSlider</code> のスタイルは <code>_imageSlider.scss</code> というファイルに定義する。これらのパーシャルを同一ディレクトリに格納すれば、コンポーネントを追加するときにコンポーネント名の衝突を防ぐことができる。</p>
<pre><code class="language-scss">// main.scss
@import "component/heroUnit";
@import "component/imageSlider";
@import ...
</code></pre>
<p>コンポーネント名の衝突さえ防げれば、コンポーネント内のセレクターとして要素型 (<code>ul</code> とか <code>em</code> とか) や「素朴な」クラス名 (<code>.title</code> とか <code>.description</code> とか) も使いやすくなる。これらコンポーネント内のセレクターの衝突まで完璧に防ぐのは難しいけど、これは <code>:not()</code> 擬似クラスと <code>></code> 結合子を使えばできなくはない。</p>
<pre><code class="language-css">.imageSlider[data-compnent] :not([data-component]) ul,
.imageSlider[data-compnent] > ul {
list-style-type: none;
...
}
</code></pre>
<p>こう書けば子孫コンポーネントへの望まない継承を避けられるけど、さすがにすべてのコンポーネントに対してここまでやるのはちょっとやりすぎの感がある。入れ子になる可能性のあるコンポーネントについて個別に対応した方がいいかもしれない。</p>
<p>僕は CSS が壊れやすいものということは承知しているつもりだけど、かといってカスケーディングと継承を忌避したりするようなことはしたくないと思っている。ふつうのセレクターを使ってふつうの CSS が書きたい。またマークアップは簡潔にしたいという気持ちも依然として強いし、<code>class</code> 属性に過剰な役割を追わせるのも気が進まない。というようなことを考えながら、ここらへんが落としどころとして良さそうなのではないかと思いはじめているのがこのアプローチ。</p>
#767676
2015-03-22T00:00:00Z
https://terkel.jp/archives/2015/03/767676/
<p>僕はウェブデザインでグレーのテキストを使うとき、背景色が白(<code>#ffffff</code>)なら、前景色を<strong><code>#767676</code></strong>かそれより暗くするようにしています。これがWCAG 2.0の達成基準「<a href="http://waic.jp/docs/WCAG20/Overview.html#visual-audio-contrast-contrast">最低限のコントラスト(レベルAA)</a>」を満たすもっとも明るいグレーだからです。</p>
<p>ちなみに、背景色が黒(<code>#000000</code>)のとき上記達成基準を満たすもっとも暗いグレーは<code>#757575</code>です。つまり、<code>#767676</code>または<code>#757575</code>のテキストは、背景が白でも黒でも最低限のコントラストを確保できます。またこれらの背景色と前景色を入れ替えても同様で、<code>#767676</code>または<code>#757575</code>の背景ならテキストが<code>#ffffff</code>でも<code>#000000</code>でもOKです。</p>
<p>フォントのサイズやウェイトによってはこの限りではないし、背景色が真っ白や真っ黒でない場合はツールなどを使って検証する必要がありますが、とりあえずこの<code>#767676</code>という値を覚えておくとけっこう便利です。</p>
<ul>
<li><a href="http://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast">Web Content Accessibility Guidelines (WCAG) 2.0</a>(邦訳:<a href="http://waic.jp/docs/WCAG20/Overview.html#visual-audio-contrast-contrast">ウェブ・コンテンツ・アクセシビリティ・ガイドライン (WCAG) 2.0</a>)</li>
<li><a href="http://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html">Understanding Success Criterion 1.4.3 | Understanding WCAG 2.0</a>(邦訳:<a href="http://waic.jp/docs/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html">達成基準 1.4.3 を理解する | WCAG 2.0解説書</a>)</li>
<li><a href="http://snook.ca/technical/colour_contrast/colour.html#fg=767676,bg=FFFFFF">Colour Contrast Check - snook.ca</a></li>
</ul>
游とMerriweather
2015-04-30T00:00:00Z
https://terkel.jp/archives/2015/04/yu-and-merriweather/
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/merriweather-yu.png" width="1440" height="640" />
</figure>
<p>少し前にこのサイトのデザインをちょっと変えて、「本文は明朝、ただし見出しや強調などはゴシック」というスタイルにしています。と言っても、本文が明朝で表示されるのは<strong>游明朝体</strong>か<strong>ヒラギノ明朝体</strong>が使える場合だけで、それ以外の環境ではゴシックになるはずです。</p>
<p>欧文書体は和文の従属欧文ではなく<a href="https://ebensorkin.wordpress.com/"><strong>Merriweather</strong></a>です。セリフとサンセリフのファミリーがあることと、エックスハイトが高く和文との相性が良いことから選びました。ウェイトは和文とのバランスから400ではなく300を使っています。Merriweatherは<a href="https://fonts.google.com/specimen/Merriweather">Google Fonts</a>や<a href="https://typekit.com/fonts/merriweather">Typekit</a>、<a href="https://www.fontsquirrel.com/fonts/merriweather">Font Squirrel</a>などで入手できます。</p>
<p>CSSの指定としては、まずデフォルトがMerriweather Sansとゴシック体の組み合わせ。そして游明朝体またはヒラギノ明朝体が使えるかどうかをJavaScriptで検出し、もし使えれば本文でMerriweather(serif)と組み合わせます。ただし、見出しやテーブル、ボールドになる部分などはサンセリフとゴシックです。明朝体が使えるかどうかの検出には、<a href="https://github.com/terkel/fontdetect">FontDetect</a>という自作のライブラリを利用しています。明朝が使える場合は<code>html</code>要素に<code>mincho</code>というクラス名がつくので、これでスタイルを分岐させます。</p>
<pre><code class="language-scss">$font-family-serif: "Merriweather";
$font-family-sans: "Merriweather Sans";
$font-family-mincho: "Yu Mincho", "YuMincho", "Hiragino Mincho ProN";
$font-family-gothic: "Yu Gothic", "YuGothic", "Hiragino Kaku Gothic ProN", "Meiryo";
html {
font-family: $font-family-sans, $font-family-gothic, sans-serif;
}
.mainBody {
.mincho & {
font-family: $font-family-serif, $font-family-mincho, serif;
h2, h3, h4, h5, h6,
blockquote, dt, figure,
em, strong, dfn, i, b,
table {
font-family: $font-family-sans, $font-family-gothic, sans-serif;
}
}
}
</code></pre>
<p>けっこう気に入ってます。</p>
ペンケース
2015-06-06T00:00:00Z
https://terkel.jp/archives/2015/06/pen-case/
<figure class="-small">
<img decoding="async" alt="" src="https://terkel.jp/img/pen-case.jpg" width="1280" height="1280" />
</figure>
<p>こないだはじめてTOEICを受験したんだけど、当日の持ち物を準備してるとき、まともなシャーペンやペンケースを持ってないことに気づいて、ちゃんと買うことにした。</p>
<p>シャーペンは製図用が良いらしいと聞いて、ぺんてるの<a href="http://amzn.to/2tAe4aP">グラフギア500</a>にしてみた。がっしりしてるし適度に重くて書きやすい。店頭でいくつか試したけど、<a href="http://amzn.to/2sx7yg0">グラフギア1000</a>は重心が高い気がしたし、<a href="http://amzn.to/2utSu47">ステッドラー925</a>はちょっと軽い気がした。ここ数年、自前の筆記具はLamyのSafari万年筆と、ほぼ日手帳のおまけについてくるジェットストリームの3色ボールペンぐらいしか使ってなくて、シャーペン買うのもたぶん20年ぶりとかだと思う。</p>
<p>ペンケースは<a href="http://www.builtny.com/">Built NY</a>の<a href="http://www.amazon.com/dp/B00FGJQQEO">Makeup Brush Case</a>というのがちょうど良さそうだったので取り寄せてみたらぴったりだった。Builtの製品はMacBookのスリーブを買って以来かなり好きで、小物入れのようなものとかKindleのスリーブとかも愛用してる。</p>
<p>中身がシャーペンと消しゴムだけなのはさびしいので、定規とかスティックのりとかちょっとずつ買い揃えてる。いままで文具にそこまでの関心はなかったんだけど、なんか楽しくなってきた。</p>
input要素のline-height
2015-08-06T00:00:00Z
https://terkel.jp/archives/2015/08/input-element-line-height/
<p>FirefoxのUAスタイルシートでは<code>input</code>要素の<code>line-height</code>プロパティに<code>normal !important</code>という値が指定されていた。このため製作者が<code>line-height</code>をコントロールできず、フォーム部品のスタイリングが難しい原因のひとつになっていた。これは修正される見込みがなく、「<a href="http://hail2u.net/blog/webdesign/line-height-normal-bang-important.html">死ぬまで付き合うことになりそう</a>」とまで言われていたが、2014年6月にリリースされた Firefox 30で<code>!important</code>が削除され、上書きできるようになっていたらしい。</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/Firefox/Releases/30#CSS">Firefox 30 for developers - Mozilla | MDN</a></li>
<li><a href="https://developer.mozilla.org/en-US/Firefox/Releases/30/Site_Compatibility#line-height_is_now_applied_to_%3Cinput%3E">Site Compatibility for Firefox 30 - Mozilla | MDN</a></li>
</ul>
<p>長生きはするものだという感想。</p>
行の長さ
2015-08-30T00:00:00Z
https://terkel.jp/archives/2015/08/line-length/
<p>ウェブページの和文横組みの本文で、適切な行の長さはどのくらいか。もちろんこれは一概に言えるものではなく、内容、デバイス、書体、行間など、様々な要素に左右されます。しかし多くの場合、<strong>読みやすい行の長さは24字から40字程度で、長くても48字程度までにすると良い</strong>、というのが僕の意見です。これは僕の感覚もありますが、以下のようなガイドラインや実例を参考にしています。</p>
<p>まず欧文の場合、『<a href="http://amzn.to/2tw7VLT">The Elements of Typographic Style</a>』にある「45字から75字」というガイドラインがスタンダードとして広く受け入れられているらしく、ウェブ・デザインについての書籍やブログ記事でも多く参照されています。</p>
<blockquote cite="urn:ISBN:978-0-88179-212-6" lang="en">
<p>Anything from 45 to 75 characters is widely regarded as a satisfactory length of line for a single-column page set in a serifed text face in a text size. The 66-character line (counting both letters and spaces) is widely regarded as ideal. For Multiple-column work, a better average is 40 to 50 characters.</p>
<p>If the type is well set and printed, lines of 85 or 90 characters will pose no problem in discontinuous texts, such as bibliographies, or, with generous leading, in footnotes. But even with generous leading, a line that average more than 75 or 80 characters is likely to be too long for continuous reading.</p>
</blockquote>
<p>ウェブではWCAG 2.0にテキストブロックの幅についてのガイドラインがあり、行の長さが80字(CJKの場合は40字)を超えないように、としています(<a href="http://www.w3.org/TR/WCAG20/#visual-audio-contrast-visual-presentation">1.4.8 Visual Presentation</a>)。</p>
<blockquote cite="http://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-visual-presentation.html" lang="en">
<p>For people with some reading or vision disabilities, long lines of text can become a significant barrier. They have trouble keeping their place and following the flow of text. Having a narrow block of text makes it easier for them to continue on to the next line in a block. Lines should not exceed 80 characters or glyphs (40 if <abbr>CJK</abbr>), where glyphs are the element of writing in the writing system for the text.</p>
</blockquote>
<p>Kindle電子書籍リーダーには、文字のサイズやページの余白をコントロールする機能があります。手元の<a href="http://amzn.to/2swJwSb">Kindle Voyage</a>では、和文横組みの書籍を横画面モードで表示し、文字サイズとページ余白をともに最小にしたとき、1行は45字でした(ちなみに縦組み・縦画面では46文字)。</p>
<p>日本語で書かれたデザインの本でも和文横組みのガイドラインを探してみましたが、あまり見つけられていません。『<a href="http://amzn.to/2swveks">デザインの教室 手を動かして学ぶデザイントレーニング</a>』では20字から30字程度が読みやすいとし、15字は「少し短い」、40字は「あまり推奨できない」、50字は「限界を超えている」とのことです。『<a href="http://amzn.to/2t1qk2H">タイポグラフィの基本ルール</a>』では、30字から40字程度が最長、13字から15字程度を最短としています。</p>
<p>また、手元にあった<a href="http://www.oreilly.co.jp/">オライリー・ジャパン</a>の技術書のいくつかで実際の文字数をカウントしてみたところ、もっとも短いもので42字、長いものは48字でした。和書としてはやや長めの印象を受けます。</p>
<p>ちなみに、42字の『<a href="http://amzn.to/2twjH9b">メンテナブルJavaScript</a>』と48字の『<a href="http://amzn.to/2t1mqXr">JavaScript 第6版</a>』を比較すると、判型は同じであるため、文字サイズは当然後者の方が小さいのですが、ページあたりの行数はどちらも38でした。つまり行が長いほど行間が広くとられていることになります。これはウェブ・デザインでも同様で、行が多少長くても行間を広くすることで読みやすくできるし、逆にモバイルなどで行の長さが制限される場合は行間を詰めると良いです。</p>
<p>以上をざっくり総合して、読みやすい上限は40字程度かな、と考えました。個人的な感覚から言ってもだいたいそのくらいです。これを「45字から75字程度が読みやすいが、場合によっては90字程度もあり」という欧文のスタンダードに当てはめてみると、「24字から40字程度が最適、長くても48字程度まで」という和文横組みのガイドラインが導き出されます。実際には、内容やほかのデザイン要素を考慮して調整することになりますが、おおむねこのあたりを基準にして良さそうな気がします。</p>
庭
2015-10-31T00:00:00Z
https://terkel.jp/archives/2015/10/garden/
<p>千葉から東京へ引っ越してきてひと月ほどたつ。</p>
<p>新しい住まいには狭い庭があって、いまこれを書いている部屋からも障子のむこうに見える。とは言えまだなにも置いていないので、少し雑草の生えた地面と古いブロック塀しか見えない。殺風景なのでなにか緑を植えたい。</p>
<p>この庭をたまに猫が横切っていく。こちらに気づいても一瞥をくれるだけで通り過ぎ、隣家のエアコンの室外機の上に腰を落ち着けるのがいつものパターン。そしていつの間にかいなくなってる。見かけると少しうれしい。</p>
<p>こないだ、晴れて暖かかった日、縁側に腰掛けて靴の手入れをしているとき、ああここに住んで良かったなと思った。</p>
CSSカスタム・プロパティへの期待
2016-02-29T00:00:00Z
https://terkel.jp/archives/2016/02/im-excited-about-native-css-variables-too/
<p>“<a href="http://philipwalton.com/articles/why-im-excited-about-native-css-variables/">Why I’m Excited About Native CSS Variables</a>”という、CSSカスタム・プロパティ(CSS変数)を紹介する記事を日本語に翻訳し、「<a href="http://terkel.github.io/why-im-excited-about-native-css-variables/">僕がネイティブなCSS変数にわくわくする理由</a>」として公開した。元記事から3カ月近くたってしまい、旬を逃した感もあるけど、近々カスタム・プロパティがChromeとSafariの安定版でもサポートされるというタイミングなので、まあいいかと思って公開した。</p>
<p>僕はこの記事を読むまで、CSSカスタム・プロパティの存在は知っていたもののほとんど注意を払っておらず、当面はSassがあるしべつにいいやと思っていたという、まさに記事の想定読者の典型だったと言える。でもこれを読んで考えをあらためました。個人的には、Sassにはじめて触れたとき以来と言っていいくらいの驚きがあった。</p>
<p>記事の例にあるように、レスポンシブ・デザインやコンテクスチュアル・スタイリングなどにおいて威力を発揮するのは間違いないけど、僕がとくにうれしいのはレスポンシブなタイポグラフィが実現しやすくなるという点だ。現状ではメディアによってフォントサイズを変更するくらいは容易だけど、行間やスペーシング、見出しのバランスなど、サイズではなくプロポーションをレスポンシブにするのはものすごく骨が折れる。このサイトではなんとか頑張ろうとしてるけど、絶望的にめんどくさい。これがカスタム・プロパティによってようやく可能になるというか、カスタム・プロパティが利用できるようになるまではレスポンシブなタイポグラフィはあきらめたほうがいいんじゃないかと思いはじめている。</p>
<p>ただ実際問題としては、フォールバックを書くのがかなり大変というかどう書きゃいいんだというのがある。なにしろCSS設計の根幹をなすところなので、慎重にならざるを得ないというのもある。でもFirefoxではもうサポートされてるし、さっき書いたとおりChromeとSafariももうすぐ、そしてなにより多くの問題を解決する可能性を持った強力なフィーチャーなので、少しずつプロジェクトに取り入れていく方法を探ってみたい。</p>
<p>というわけで、僕もCSSカスタム・プロパティにわくわくしてます。少なくとも、CSSの未来を明るくしてくれるもののひとつだと思う。</p>
ウェブサイトでシステムフォント
2016-05-05T00:00:00Z
https://terkel.jp/archives/2016/05/system-fonts-on-website/
<p>GoogleのRobotoや、AppleのSan Franciscoなど、OSベンダーが独自のフォントを開発し、自社製品のUIにシステムフォントとして採用する、という事例が相次いでいます。これらのフォントは、プラットフォームの特性を考慮して最適化されたもの(あるいは最適なものとして選ばれたもの)と言え、かつ今後のOSのアップデートにともなってさらに改善されることも期待できます。また、ユーザーがそのシステムを操作するときにもっとも頻繁に触れる、つまりもっとも見慣れているフォントでもあります。というわけで、これらシステムフォントをウェブサイトのUIに採用するというのはかなり良いアイデアに思えます。</p>
<p>一方で、システムフォントはあくまでUIのためのもので、長い文章などには向かない場合もあるので、コンテンツ部分は別のフォントを指定すると良いかもしれません。たとえば<a href="https://medium.com/designing-medium/project-tnt-4b9b4ea97cda">Medium</a>などではそのようなアプローチをとっています。ただそういった場合、欧文なら本文にウェブフォントを採用することが多いですが、和文ではその方法にかなりのコストがかかります。ローカルのフォントを指定するにしてもスタックが複雑になりがちで、テストもたいへんです。そこで、<code>sans-serif</code>などのジェネリックな指定にとどめ、ユーザーエージェントの設定に委ねるという選択肢を検討しても良いと思います。つまり、UIはシステムに寄せて、コンテンツはユーザーに寄せる、という方向です。</p>
<pre><code class="language-css">/* For UI */
html {
font-family: -apple-system, BlinkMacSystemFont,
"Segoe UI", "Helvetica Neue",
"Hiragino Sans", "Hiragino Kaku Gothic ProN", "Meiryo",
sans-serif;
}
/* For content */
.ArticleBody {
font-family: sans-serif;
}
</code></pre>
<p>このコード例では、デフォルトはシステムフォントで、本文のみユーザーエージェントに応じたサンセリフ体で表示されることを意図しています。UbuntuやFirefox OSなんかも考えるともうちょっと追加する必要があるかもしれませんが、だいたいはこんな感じでカバーできると思います。以下、CSSでシステムフォントを指定する際のポイントをいくつか。</p>
<ul>
<li>MacとiOSでSan Franciscoを指定するには<code>-apple-system</code>というキーワードを使うが、MacのChromeのみ<code>BlinkMacSystemFont</code>キーワードが必要<a href="https://terkel.jp/archives/2016/05/system-fonts-on-website/#fn:1" id="fnref:1">1</a></li>
<li>MacのChromeとFirefoxでは<code>@font-family</code>の<code>src</code>ディスクリプタで<code>-apple-system</code>/<code>BlinkMacSystemFont</code>キーワードを利用できない</li>
<li>Mac Yosemite以前のためのフォールバックとしてHelvetica Neueを指定</li>
<li>MacでSan Franciscoとウェイトを合わせるためヒラギノ角ゴに優先してHiragino Sansを指定</li>
<li>Widnows 10の日本語システムフォントはYu Gothic UIだが、あまり評判が良くないらしいので、メイリオの方が良さそう</li>
<li>Android 6.0のシステムフォントはRobotoとNoto Sans CJK JPだが、<code>Roboto</code>と<code>Noto Sans CJK JP</code>というフォント名は無効で、<code>sans-serif</code>キーワードで指定<a href="https://terkel.jp/archives/2016/05/system-fonts-on-website/#fn:2" id="fnref:2">2</a></li>
</ul>
<p>ここ数年、ウェブフォントが普及したり、MacとWindowsに游書体という共通のフォントが搭載されたりなど、デザイナーの意識が「ことなる環境でも同じフォントで表示できる」という方向に向かいやすい状況だったように思います。しかし言うまでもなく、環境がことなれば最適なタイポグラフィもことなるし、またユーザーの好みが様々であることも依然として変わりません。ここで紹介したアプローチは、プロモーションやブランディングを目的としたサイトなど、UIも含めてページ全体の印象をコントロールしたいような場合はちょっと違うかも知れませんが、とくにアプリケーション寄りやメディア系のサイトなどでは、有力な候補のひとつになるのではないかと思います。</p>
<h2>脚注</h2>
<ol class="Footnotes">
<li id="fn:1"><a href="https://www.smashingmagazine.com/2015/11/using-system-ui-fonts-practical-guide/">Using System UI Fonts In Web Design: A Quick Practical Guide – Smashing Magazine</a> <a href="https://terkel.jp/archives/2016/05/system-fonts-on-website/#fnref:1">↩︎</a></li>
<li id="fn:2"><a href="https://github.com/android/platform_frameworks_base/blob/master/data/fonts/fonts.xml">platform_frameworks_base/fonts.xml at master · aosp-mirror/platform_frameworks_base · GitHub</a> <a href="https://terkel.jp/archives/2016/05/system-fonts-on-website/#fnref:2">↩︎</a></li>
</ol>
Mojik
2016-07-20T00:00:00Z
https://terkel.jp/archives/2016/07/mojik/
<p><a href="https://github.com/terkel/mojik"><strong>Mojik</strong></a>という、ウェブにおける和文の文字組みをコントロールするためのJavaScriptライブラリを公開しました。いまのところ、以下のパターンでの「アキ」を調整できます。</p>
<ul>
<li>連続する約物のアキ</li>
<li>行頭の始め括弧のアキ</li>
<li>欧文間のアキ</li>
</ul>
<p><code>Mojik.compose()</code>メソッドの引数にCSSセレクターを渡すと、マッチする要素から上記に該当する箇所を検出し、それぞれマークアップが挿入されるので、CSSでアキ量を調整します。以下のページに実際に動いているデモがあるので、ぜひ見てみてください。</p>
<ul>
<li><a href="http://terkel.github.io/mojik/">Mojikデモ</a></li>
</ul>
<p>ウェブページの本文やタイトルなどで使われることを想定しているので、HTMLタグがあっても問題なく動作することは必須条件でした。基本的に、まずHTML文字列をテキストとタグに分けて、正規表現でテキストの検索を繰り返す、という方法を採っています。ここらへんは<a href="https://github.com/kotarok/jQuery.waokon">kotarok/jQuery.waokon</a>などを参考にさせてもらいました。</p>
<p>そのほかとくに面倒だったのは、行頭始め括弧の検出です。括弧の位置を親要素と比較して、左端にあれば行頭と見なし左マージンに負数を指定する、というところまではいいのですが、マージンを調整した結果、場合によっては始め括弧が前の行の行末に収まってしまうことがあります。そこで、括弧の前に空の<code>span</code>要素を挿入し、括弧が行頭に来たときにはCSSの擬似要素で改行することで括弧を行頭に固定する、ということをしています。そしてもちろん、この処理はウィンドウのリサイズごとに再計算されます。</p>
<p>これを本格的に作り始めたのは、<a href="http://tama-san.com/yakuliga-font/">YakuLiga</a>と<a href="http://tama-san.com/yakucalt-font/">約猫</a>に触発されたことがきっかけでした。言うまでもなく、こういったことはブラウザーがうまいことやってくれればそれに越したことはないわけですが、それでもいまあるもので可能な限りなんとかしてみよう、という試みとして作ってみました。</p>
<p>バージョンはまだ0.1で、アクセシビリティやパフォーマンスのテストもできてないし、デフォルトのアキ量が適切かどうかなど自信のないところもあります。機能ももうちょっと充実させたくて、とくにオプションはうまいこと指定できるようにしたいです。というわけで、<a href="https://github.com/terkel/mojik/issues">issue</a>や<a href="https://github.com/terkel/mojik/pulls">pull request</a>は大歓迎です。お待ちしています。</p>
<ul>
<li><a href="https://github.com/terkel/mojik">Mojik on GitHub</a></li>
</ul>
リンクのURLを欄外に配置して印刷する
2017-07-05T00:00:00Z
https://terkel.jp/archives/2017/07/print-link-urls-as-sidenotes/
<p>印刷向けCSSの手法のひとつに、擬似要素と<code>attr()</code>関数を使ってリンクテキストの後ろにURLを挿入する、というものがあります。<a href="http://getbootstrap.com/">Bootstrap</a>や<a href="https://html5boilerplate.com/">HTML5 Boilerplate</a>などでも取り入れられているものです。</p>
<pre><code class="language-css">a[href]::after {
content: " (" attr(href) ")";
}
</code></pre>
<p>簡単かつ効果的ではありますが、挿入されるURLによってテキストが分断されてしまうので、どうしても本文が読みにくくなりがちです。URLが長い場合はとくに。</p>
<p>そこで、URLをページの欄外に配置し、番号を振ってリンクテキストと結び付ける、という「傍注」形式にすれば、本文が読みやすく、かつURLも必要に応じて参照できて良いのではないかと思います。</p>
<figure>
<img decoding="async" alt="" src="https://terkel.jp/img/sidenotes.png" width="1600" height="448" />
</figure>
<p>これはカウンターとフロートを利用した簡単なCSSで実現が可能です。<code>main</code>要素内のリンクを対象にする場合のコードのうち、必要最低限の部分を抜き出すと以下のようになります。</p>
<pre><code class="language-css">/* カウンターの初期化と余白の確保 */
main {
counter-reset: sidenote;
margin-right: 14rem;
}
/* カウンターのインクリメント */
main a[href] {
counter-increment: sidenote;
}
/* リンクテキストに番号を振る */
main a[href]::after {
content: counter(sidenote);
}
/* リンクURLを生成し欄外に配置 */
main a[href]::before {
content: counter(sidenote) ". " attr(href);
clear: right;
float: right;
margin-right: -14rem;
width: 12rem;
overflow-wrap: break-word;
}
</code></pre>
<p><code>a</code>要素ごとにインクリメントしたカウンターの数値を、<code>::after</code>と<code>::before</code>それぞれで利用するところがポイントです。<code>::after</code>でリンクテキストに番号を振り、<code>::before</code>で同じ番号とともにURLを生成します。生成したURLを欄外に配置するには、<code>main</code>のマージンまたはパディングで左右どちらかにスペースを作った上で、<code>float</code>でその方向に浮動化し、負のマージンで位置を調整します。またURLの折り返しを許容するために<code>overflow-wrap</code>プロパティも指定しています。</p>
<p>リンクのURLだけでなく<code>abbr</code>や<code>dfn</code>要素の<code>title</code>属性なども同様に表示できます。その場合、複数の要素で同じカウンターをインクリメントすることになります。</p>
<pre><code class="language-css">main a[href],
main abbr[title],
main dfn[title] {
counter-increment: sidenote;
}
main a[href]::after,
main abbr[title]::after,
main dfn[title]::after {
content: counter(sidenote);
}
main a[href]::before {
content: counter(sidenote) ". " attr(href);
}
main abbr[title]::before,
main dfn[title]::before {
content: counter(sidenote) ". " attr(title);
}
</code></pre>
<p>いまやウェブページを印刷したいという需要はかなり減ったように思いますし、印刷向けCSSというものが話題に上ることもあまりないですが、このサイトのCSSを久しぶりに書き直すうちに思いついたので書いてみました。</p>
Mojik v0.3.0
2017-07-12T00:00:00Z
https://terkel.jp/archives/2017/07/mojik-v0-3-0/
<p><a href="https://github.com/terkel/mojik">Mojik</a>のv0.3.0をリリースした。新しい機能として、連続したダッシュ(U+2014 EM DASHまたはU+2015 HORIZONTAL BAR)をつなげるという、いわゆる2倍ダッシュのオプションを追加した。つなげると言っても、実際にはCSSで2つのダッシュのうち一方を横に広げて、もう一方を隠す、という実装。ちなみに源ノ角ゴシック・源ノ明朝はダッシュが連続するとリガチャになる。そっちの方がスマートでいいので、この機能はデフォルトで無効にしてある。そのほかの変更は、印刷時にリフローするようにしたり、欧文扱いになってた米印を和文扱いにしたりとか。</p>
<p>最近このサイトで実際に採用してドッグフーディングするようにしたところ、色々とあらが見えてきた。昨年の夏頃からしばらく開発が滞ってたけど、もうちょっと本腰を入れるつもりです。</p>
Disco é Cultura
2017-09-04T00:00:00Z
https://terkel.jp/archives/2017/09/disco-e-cultura/
<figure class="-small">
<img decoding="async" alt="" src="https://terkel.jp/img/disco-e-cultura.png" width="1536" height="1536" />
</figure>
<p><a href="http://www.rubbergard.jp/disco-e-cultura/">Disco é Cultura</a>という、友人の<a href="http://www.rubbergard.jp/">ラバーガード・レコード</a>が主催するDJイベントのウェブサイト作りをお手伝いしました。なにしろ時間がなかったので作りはちょっと粗いんですが、CSS Gridをはじめて実戦で使えたのは良かったです。イベントは9月18日、場所は<a href="http://unice.jp/">代官山ユナイス</a>です。ご興味のある方はぜひ。</p>
San Franciscoと日本語フォント
2018-07-25T00:00:00Z
https://terkel.jp/archives/2018/07/san-francisco-and-japanese-font/
<p>CSSでSan Franciscoフォントを指定しようとすると、特定の状況で日本語フォントがHiragino Kaku Gothic Interfaceというフォントに固定され、日本語フォントが指定できなくなる、という問題があります。たとえば以下のようなCSSの場合、日本語がヒラギノ角ゴではなくHiragino Kaku Gothic Interfaceになります。</p>
<pre><code class="language-css">body {
font-family:
-apple-system, BlinkMacSystemFont,
"Hiragino Kaku Gothic ProN", sans-serif;
}
</code></pre>
<p>このHiragino Kaku Gothic Interface(正式名称不明)は、おそらくヒラギノ角ゴをSan Franciscoに調和するよう調整したものと思われます。一見ヒラギノ角ゴと見分けがつかないのですが、文字サイズがひとまわり小さいのが問題です。つまり、16pxを指定した文字の幅が16pxにならないないのです。</p>
<p>現時点で僕が把握している限り、SafariとChromeでこの現象が見られます。それぞれの発生条件について解説します。</p>
<h2>Safari</h2>
<p>SafariでSan Franciscoを表示するには<code>font-family</code>プロパティに<code>system-ui</code>もしくは<code>-apple-system</code>キーワードを指定します。しかしこれらのキーワードのいずれかを指定すると、和文フォントがHiragino Kaku Gothic Interfaceに固定されます。どうやらiOS 11、macOS 10.13(High Sierra)からの仕様のようです。</p>
<h2>Chrome</h2>
<p>ChromeでSan Franciscoを表示するには<code>font-family</code>プロパティに<code>BlinkMacSystemFont</code>キーワードを指定します。<code>lang</code>属性の値が<code>ja</code>か<code>zh</code>の場合は問題ないのですが、それ以外(<code>en</code>など)の場合、和文フォントがHiragino Kaku Gothic Interfaceに固定されます。たとえば、GitHubのサイトは<code>lang</code>が<code>en</code>なので、ChromeとSafariでは日本語のフォントサイズがFirefoxに比べてひとまわり小さく見えます。</p>
<h2>対策</h2>
<p>そもそも環境によって文字サイズが違って見えても気にならない、と言うならそのままでもいいでしょう。また、もしSan Franciscoを使う箇所に日本語がない、もしくはごく少ないという場合もあまり問題にならないかもしれません。ただ、日本語の本文などでSan Franciscoを指定している場合、実際に表示を比べるとその違いは明らかで、もしデザイナーが綿密に文字サイズを設計しているなら、許容できる範囲を超えているように思います。</p>
<p>解決策として、<code>unicode-range</code>を使って欧文にだけSan Franciscoが適用されるようにするという手もあります。</p>
<pre><code class="language-css">@font-face {
font-family: "SF Latin";
src: local(-apple-system);
unicode-range: U+0000-00FF;
}
body {
font-family: "SF Latin", sans-serif;
}
</code></pre>
<p>この方法はSafariには有効ですが、残念ながらFirefoxは<code>@font-face</code>ルールの<code>src</code>ディスクリプタで<code>-apple-system</code>が無効になってしまいます。環境がiOSに限られるならありかもしれません。</p>
<h2>結論</h2>
<p>個人的には、San Franciscoはとても優れたフォントだと思うので、ぜひウェブでも使いたいものの、少なくとも日本語のサイトでは採用を見送るのが無難と思っています。ちなみに代替としてはRobotoが使いやすくて好きです。</p>
<h2>参考資料</h2>
<ul>
<li><a href="https://qiita.com/a_t/items/18693be11bd87f98d212">ios11以前と以降での、-apple-systemの表示 - Qiita</a></li>
</ul>
Sassで角度の単位を変換
2018-09-04T00:00:00Z
https://terkel.jp/archives/2018/09/sass-angle-units/
<p>Sassで角度の単位を変換する関数を書いてた。</p>
<pre><code class="language-scss">$PI: 3.141592653589793;
@function convert-angle($angle, $to-unit) {
$from-unit: unit($angle);
$from-value: strip-unit($angle);
$factors: (
rad: 1,
deg: 180 / $PI,
grad: 200 / $PI,
turn: 0.5 / $PI
);
@if not map-has-key($factors, $from-unit) {
@warn '`#{$angle}` is not an <angle>.';
@return false;
}
@if not map-has-key($factors, $to-unit) {
@warn '`#{$to-unit}` is not a valid <angle> unit.';
@return false;
}
$rad-value: $from-value / map-get($factors, $from-unit);
@return $rad-value * map-get($factors, $to-unit) + $to-unit;
}
@function strip-unit ($number) {
@if unitless($number) {
@return $number;
} @else {
@return $number / ($number * 0 + 1);
}
}
</code></pre>
<p>単位を取り除いた上でいったん<code>rad</code>単位の値に変換し、さらにそこから指定の単位に変換する、という実装。</p>
<p>でも実は、知らなかったんだけど、Sassはネイティブで単位の異なる角度の演算ができる。</p>
<pre><code class="language-scss">@debug 180deg + 0.25turn + 100grad; // 360deg
</code></pre>
<p>演算結果は最初に登場した単位になる。これを応用して、値が0の角度を使えば単位の変換はごく簡単にできる。たとえば<code>deg</code>から<code>rad</code>へ変換するにはこう。</p>
<pre><code class="language-scss">@debug 0rad + 180deg; // 3.14159rad
</code></pre>
<p>つまり冒頭の関数はまったく不要。どうやら4年前のSass 3.4からの話のようで、<angle>と同じように<time>、<frequency>、<resolution>も単位の異なる演算ができる。半日無駄にした。</p>
従属欧文のイタリック
2019-04-20T00:00:00Z
https://terkel.jp/archives/2019/04/italic-in-japanese-fonts/
<p>和文フォントはイタリックの従属欧文が含まれないことがけっこうある。たとえばヒラギノ明朝や源ノ明朝にはイタリックの欧文がなく、CSSで<code>font-style: italic;</code>としても、ブラウザが擬似的に傾けるだけの、いわゆる「にせイタリック」になってしまう。そういった場合は欧文フォントを使うことになるが、ウェブでは欧文のサイズやウェイトを和文と調和するよう調整するのが難しいので、できれば従属欧文をそのまま使いたい。</p>
<p>最近はそういった要望に応えてくれるような、イタリックの従属欧文を持つ和文フォントが増えてきたようだ。ただ、CSSでイタリックを指定する方法はフォントによって異なり、<code>font-family</code>プロパティを使うものとOpenType機能を使うものがある。</p>
<p>WindowsのメイリオやAdobe Fontsの貂明朝・貂明朝テキストなどはシンプルで、<code>font-style</code>の値を<code>italic</code>とすれば、和文は傾かずに欧文だけがイタリックになる(というか通常の和文とイタリックの欧文を組み合わせたフォントが選択される)。イタリック体がファミリー内のいちフォントとして用意されているので、ウェブフォントサービスの書体リストなどを見たときにイタリックの存在がわかりやすい。</p>
<pre><code class="language-css">em, i {
font-style: italic;
}
</code></pre>
<p>一方、Macの游明朝体、Adobe Fontsの秀英明朝や凸版文久ゴシックなどは、OpenType機能のitalによるイタリックが使える。これらのフォントでは<code>font-style: italic;</code>を指定しても「にせイタリック」になってしまうため、まず<code>normal</code>で立体にした上で、<code>font-feature-settings</code>プロパティに<code>ital</code>キーワードを指定する。もちろんイタリックになるのは欧文だけで、和文は変化しない。</p>
<pre><code class="language-css">em, i {
font-style: normal;
font-feature-settings: "ital";
}
</code></pre>
<p>OpenType機能はフォントごとにどれが使えるのか分かりづらく、だいたい実際に試してみるまで気づかない。僕も游明朝体でitalが使えるのを今日はじめて知った。</p>
アスペクト比の異なる画像を同じ面積で表示する
2019-05-23T00:00:00Z
https://terkel.jp/archives/2019/05/display-images-in-the-same-area/
<p>ブログ記事の本文などで幅100%の画像を配置する場合、縦長の画像がやたらでかくなってしまったりなど、画像のアスペクト比によってその印象が大きく違ってしまうことがある。これをアスペクト比に関わらず大きさが揃って見えるようにしたい。それには各画像の面積が同じになるように幅をコントロールできればいいのではと考え、CSSでやってみた。</p>
<p>まず基準になる画像として、もっとも横長な画像のアスペクト比を決める。ここでは例として16 : 9とする。この16 : 9画像の幅を100%として、それ以外のアスペクト比の画像の相対的な幅を求めていく。</p>
<p>HTMLでは、各<code>img</code>要素の<code>style</code>属性に、アスペクト比を分数形式にしてカスタムプロパティとして指定する。</p>
<pre><code class="language-html"><img src="cat.jpg" style="--aspect-ratio: 16/9;">
<img src="dog.jpg" style="--aspect-ratio: 1/1;">
<img src="cow.jpg" style="--aspect-ratio: 2/3;">
</code></pre>
<p>次にCSSで、画像の面積とアスペクト比ををもとに幅を指定する。面積がSでアスペクト比がa : bの画像の幅xを求めるとすると、</p>
<pre><code>x * x/(a/b) = S
</code></pre>
<p>なので、すなわち</p>
<pre><code>x = √(S * (a/b))
</code></pre>
<p>となる。つまりCSSで平方根を求める必要がある。これには<code>var()</code>と<code>calc()</code>を使って「<a href="https://cpplover.blogspot.com/2010/11/blog-post_20.html" title="本の虫: 平方根のアルゴリズム">バビロニアン・メソッド</a>」と呼ばれるアルゴリズムを実装する。</p>
<pre><code class="language-css">img {
--w: 16;
--h: 9;
--s: calc(var(--w) * var(--h) * var(--aspect-ratio));
--x0: calc(var(--s) / 2);
--x1: calc((var(--x0) + var(--s) / var(--x0)) / 2);
--x2: calc((var(--x1) + var(--s) / var(--x1)) / 2);
--x3: calc((var(--x2) + var(--s) / var(--x2)) / 2);
--x4: calc((var(--x3) + var(--s) / var(--x3)) / 2);
--x5: calc((var(--x4) + var(--s) / var(--x4)) / 2);
--x6: calc((var(--x5) + var(--s) / var(--x5)) / 2);
width: calc(100% * var(--x6) / var(--w));
}
</code></pre>
<p><code>--w</code>と<code>--h</code>は基準の画像の相対的な幅と高さ。この面積と対象の画像のアスペクト比をかけ合わせた数値<code>--s</code>の平方根が、求める画像の相対的な幅になる。まず<code>--x0</code>でざっくりとした初期値を設定し、<code>--x1</code>以降の計算で精度を上げていく。だいたい5回もやればかなりの精度で求められるっぽい。ちなみに最初何も考えずに24回とかやってたらブラウザのタブが死んだ。</p>
<p>最後に、求められた平方根<code>--x6</code>は基準の16 : 9画像の幅に対する相対的な幅なので、これをパーセンテージ値にする。そしてこれが<a href="https://terkel.jp/demo/display-images-in-the-same-area.html">完成版のデモ</a>。</p>
<p>ただまあ、現実的にはこんな面倒なことはせず、利用する画像のアスペクト比をあらかじめ数パターン決めておいて、クラス名で指定するのが賢明と思われる。</p>
<pre><code class="language-css">img.aspect-16x9 { width: 100%; }
img.aspect-3x2 { width: 91.854% }
img.aspect-4x3 { width: 86.602%; }
img.aspect-1x1 { width: 75%; }
...
</code></pre>
<p>というかそもそも面積が同じなら同じ大きさに見えるかと言うとそういうことではなさそうな気もする。ほんとに印象を揃えたいなら、なんかそういう認知的なファクターみたいなものを加味するべきなのかも。</p>
font-feature-settingsとカスタムプロパティ
2019-11-22T00:00:00Z
https://terkel.jp/archives/2019/11/font-feature-settings-custom-properties/
<p><code>font-feature-sttings</code>プロパティは便利だけど、値の意図しない上書きが発生しやすいという扱いづらさがある。たとえば「ページ全体で<code>locl</code>を有効にした上で、<code>h1</code>要素では<code>palt</code>を有効にしたい」というようなとき、以下のようなCSSを書いてしまいがちだ。</p>
<pre><code class="language-css">body {
font-feature-settings: "locl" 1;
}
h1 {
font-feature-settings: "palt" 1;
}
</code></pre>
<p>しかしこのとき<code>h1</code>の<code>palt</code>機能タグは<code>body</code>から継承された<code>locl</code>機能タグに追加されるのではなく、これを上書きしてしまう。つまり<code>h1</code>では<code>locl</code>が無効になる。これは正しくは以下のように書かないといけない。</p>
<pre><code class="language-css">body {
font-feature-settings: "locl" 1;
}
h1 {
font-feature-settings: "locl" 1, "palt" 1;
}
</code></pre>
<p>このように、<code>font-feature-settings</code>プロパティを指定するときはどのような値が継承されているかをつねに把握し、そこに値を「重ねて」指定する必要がある。機能タグが2つとか3つとかのうちはまだいいけど、ちょっと複雑なことをしようとすればすぐに管理しきれなくなるだろう。</p>
<p>こういった煩雑さを回避する方法として、ユニバーサルセレクターとカスタムプロパティ(CSS変数)を利用する方法を考えてみた。</p>
<pre><code class="language-css">*,
*::before,
*::after {
font-feature-settings:
"locl" var(--locl, 1),
"palt" var(--palt, 0);
}
h1 {
--palt: 1;
}
</code></pre>
<p>まずプロジェクトで利用しているすべての機能タグをユニバーサルセレクターで列挙し、デフォルトで有効か無効か(<code>0</code>か<code>1</code>、または<code>on</code>か<code>off</code>)を<code>var()</code>関数のフォールバック値として定義しておく。その上で機能タグを有効(または無効)にしたいセレクターでカスタムプロパティを指定する。こうすることで、カスタムプロパティを指定したセレクター以外ではフォールバック値が適用されることになる。注意すべきなのは、機能タグを追加するときに該当のセレクターだけではなくユニバーサルセレクターにもデフォルト値とともに追加しないといけないという点。</p>
<p>そもそも<code>font-feature-settings</code>プロパティは低レベルAPIであり、可能な限り<code>font-variant</code>系プロパティを利用することが推奨されている。こういった値の継承にともなう扱いの難しさを考えても、それが望ましい。しかし一方で、とくにCJKについては<code>font-variant</code>系の仕様と実装が十分ではないという現状があり、<code>font-feature-settings</code>に頼らざるを得ない場面は少なからずある。その利用には慎重になるべきという前提のもと、思わぬバグを生まないための工夫として、このカスタムプロパティを使う手法はそれなりに有効な気がする。</p>
福岡2019
2019-12-31T00:00:00Z
https://terkel.jp/archives/2019/12/fukuoka-2019/
<p><time datetime="2019-11-16">先日</time>、「<a href="https://frontend-conf.fukuoka.jp/">フロントエンドカンファレンス福岡2019</a>」というイベントでお話をする機会をいただきました。僕のプレゼンテーションのタイトルは「<a href="https://standard.shiftbrain.com/blog/music-math-typography">音楽、数学、タイポグラフィ</a>」で、ウェブタイポグラフィを音楽と数学の視点を交えて考察するものです。</p>
<p>イベントの現場はとても雰囲気が良くて、こういった場があまり得意ではない僕も気後れせず参加することができました。打ち上げもすごく楽しかった。福岡に行ったのははじめてだったんですが、すごく暮らしやすそうなところという印象を持ちました。また行ってみたいです。</p>
<p>登壇依頼のメールを見返すと、運営の皆さんとしてはUIデザインについて話してほしかったようなんですが、結果としてあまりそういったものにはならず、自分の話したいことを話してしまいました。すみません。そのかわりイベントの「新しい視点を見つけよう」というテーマはけっこう意識していて、こういうものの見方もありますよ、という提示はできたんじゃないかと考えてます。</p>
<p>僕の話の内容は期せずして、ここ数年にわたって考えてきたことを総括するようなものになりました。イベントの本番前は、こんなわけのわからない話をいったい誰が聞くんだろう、と控室でふるえていたんですが、終わってみると思った以上に好評でほっとしました。また話した内容を書き起こして記事にしたところ、予想外に多くの方々に興味を持っていただけたようで驚いています。いままで自分がやってきたことはそんなに見当違いなものでもなかったのかなと、少し自信が持てたことが最大の収穫でした。本当に参加できて良かったと思います。声をかけてくれた運営の皆さん、どうもありがとうございました。</p>
読まれるために
2020-06-25T00:00:00Z
https://terkel.jp/archives/2020/06/to-be-read/
<figure>
<img alt="" src="https://terkel.jp/img/web-typography.jpg" width="1440" height="900" decoding="async" />
</figure>
<p>『<a href="https://www.hanmoto.com/bd/isbn/9784862464767">ウェブタイポグラフィ――美しく効果的でレスポンシブな欧文タイポグラフィの設計</a>』という本の監訳を担当しました。書店の店頭では<time datetime="2020-W26">今週</time>、<a href="https://www.amazon.co.jp/dp/4862464769?tag=terkel-22">Amazon.co.jp</a>などオンライン書店では<time datetime="2020-W27">来週</time>に発売される予定です。</p>
<p>原書である『Web Typography』は<time datetime="2017">2017年</time>にKickstarterでのクラウドファンディングを経て出版されました。僕も出資者のひとりとして本書を手にしたわけですが、当時も今も、ウェブタイポグラフィをこれだけのヴォリュームで網羅的に解説した本はまだないのではないでしょうか。</p>
<p>本書のテーマはタイポグラフィによって読み手の体験をより良いものにすることです。そのメッセージは何度も明快に繰り返されます。正直に言って多少まわりくどいところもある本ですが、それはすぐれたタイポグラフィを実現するために避けて通れない、複雑に絡み合う様々な事柄に真正面から取り組んだ結果であると思います。ですから、すぐに使えるテクニック集のようなものをお探しの方には、残念ながら本書は期待に沿うものではないかもしれません。しかしタイポグラフィの基本をじっくりと学んでみたいという方には、長く役に立つガイドブックとしておすすめできる本です。</p>
<p><br /></p>
<p>本書は3つの章から構成されています。</p>
<p>1章「読まれるための組版」では「行」を中心に組版を解説しています。まず行の組版からはじめるというのは、何よりも読み手の体験を重視するという本書らしい構成と言えます。相対的なサイズ体系をもとに、文字サイズ、行長、行間、行揃えについて検討します。ジャスティフィケーションとハイフネーションの解説にもかなりの紙幅を割いていて、本格的な欧文組版のガイドラインとしても実用に耐える内容です。</p>
<p>2章「タイポグラフィのディテール」では、スペースやアクセント記号、約物、合字、スモールキャップなど、まさに細かなディテールについて学びます。和文の中で欧文を扱うときの参考にもなるでしょう。また文字サイズのスケールについても実践的な考察がなされていますが、これは日本語の文献ではこれまであまりなかったものではないでしょうか。そして段落や引用、リスト、テーブルなど、ウェブページの本文を構成する主要な要素のデザイン手法のほか、バーティカルリズムやグリッド、マルチカラムなど、レイアウトに関しても触れています。もちろんこれらはすべてレスポンシブデザインを前提にしています。</p>
<p>3章「フォントの選択と使用」では、書体の歴史や活字のディテールを学びながら、本文や見出しなどそれぞれに適切なフォントを選ぶための考え方を紹介しています。様々な角度から書体を解剖した、デザイナーにインスピレーションを与えてくれる内容です。加えて、アンチエイリアスなど画面でのレンダリングの仕組みや、ウェブフォントなどについての解説も充実していて、あくまで現在のウェブタイポグラフィでの実践を重視しています。</p>
<p>また原書にはないページとして、和文組版についてごく簡単に解説したコラムと、索引を新たに収録しています(原書は索引がなくて読むのに苦労したんです)。</p>
<p><br /></p>
<p>本書の巻末には欧文の参考文献リストがありますが、ここに日本語版を作るにあたって参考にした日本語の文献を挙げておきます。本書でタイポグラフィに興味を持った方の読書ガイドになれば幸いです。</p>
<ul>
<li>小林章『<a href="https://www.amazon.co.jp/dp/4568502772?tag=terkel-22">欧文書体 その背景と使い方</a>』美術出版社、<time>2005</time></li>
<li>小宮山博史(編)『<a href="https://www.amazon.co.jp/dp/441661022X?tag=terkel-22">タイポグラフィの基礎</a>』誠文堂新光社、<time>2010</time></li>
<li>ヤン・チヒョルト『<a href="https://www.amazon.co.jp/dp/4306094316?tag=terkel-22">アシンメトリック・タイポグラフィ</a>』鹿島出版会、<time>2013</time></li>
<li>フレット・スメイヤーズ『<a href="https://www.musabi.co.jp/books/b463019/">カウンターパンチ</a>』武蔵野美術大学出版局、<time>2014</time></li>
<li>サイラス・ハイスミス『<a href="http://www.graphicsha.co.jp/detail.html?p=30126">欧文タイポグラフィの基本</a>』グラフィック社、<time>2014</time></li>
<li>ヨースト・ホフリ『<a href="https://bookdesign.theshop.jp/items/23653495">ディテール・イン・タイポグラフィ</a>』Book & Design、<time>2017</time></li>
<li>髙岡昌生『<a href="https://uyushorin.com/cgi-bin/herodb/heroskin.cgi?table=books&search=9784904596111&skin=book.shtm">増補改訂版 欧文組版 タイポグラフィの基礎とマナー</a>』烏有書林、<time>2019</time></li>
<li>スティーブン・コールズ『<a href="http://www.bnn.co.jp/books/10116/">図解で知る欧文フォント100</a>』ビー・エヌ・エヌ新社、<time>2019</time></li>
</ul>
<p>監訳という仕事は今回がはじめてでした。実際に取りかかってみると思っていたよりはるかに大変で、引き受けたことを何度か後悔しましたが、なんとか完成してほっとしています。</p>
<p>なかなか良い本が出来たと思います。ぜひ手にとってみてください。</p>
コラム幅を文字サイズの整数倍にする
2021-05-23T00:00:00Z
https://terkel.jp/archives/2021/05/em-based-grid/
<figure>
<img alt="" src="https://terkel.jp/img/em-based-grid.png" width="1086" height="544" decoding="async" />
</figure>
<p>日本語の組版ではコラム幅を文字サイズの整数倍にするのが基本だ。そうすれば全角等幅の活字を字間なく並べたとき、コラム幅と行長がぴったり合い、行末の位置が揃うことになる。ただしプロポーショナル文字(ラテン・アルファベットやアラビア数字など)や行頭行末の禁則の影響で行長にばらつきが出るので、その場合は調整が必要になる。</p>
<p>このコラム幅についての原則はウェブでも同様だと僕は考えている。ブラウザーではInDesignとは違って行ごとの緻密な調整はできないが、それでもやはり、コラム幅はなるべく文字サイズの整数倍にするのがよいと思う。そうしておけば、行長のばらつきが起こったとしても、その変化は「短くなる」方向でしか発生しない。コラムの右端を見たとき(横組みの場合)、おおむね縦に揃っているがときおりくぼんだ箇所が発生する、という格好になるわけだ。一方コラム幅が文字サイズの整数倍になっていないと、行長が意図した幅より長くも短くもなるので、行末が不揃いになりやすい。</p>
<p>CSSでコラム幅を文字サイズの整数倍にするには、任意のブロックの<code>width</code>プロパティに<code>em</code>単位の整数値を指定すればよい。1emはすなわち全角幅なので、指定した数値がそのまま1行の文字数になる。ただし幅を固定してしまうとそれより狭い画面に収まらないので、<code>min()</code>関数と<code>vw</code>単位などを使って最大幅を制限することも必要。以下の例では、広い画面では<code>main</code>の幅が全角36文字分、狭い画面ではビューポートの90%になる。</p>
<pre><code class="language-css">main {
width: min(36em, 90vw);
}
</code></pre>
<p>ただこのやり方では、<code>main</code>の幅が40em未満の場合(36em ÷ 0.9)、コラム幅は文字サイズの整数倍ではなく半端な幅になってしまう。たとえばビューポートの幅が550pxで、文字サイズが16pxだったとする。<code>main</code>の幅は495pxになり(550 × 0.9)、1行には30文字が収まるが、行末に15pxの余りが生じることになる(16 × 30 + 15 = 495)。この15pxの半端なスペースは、前述のとおり、行長のがたつきを招いてしまう。</p>
<p>こうした事態を避け、いかなるビューポート幅であってもコラム幅を意図どおりにコントロールする方法としては、単純にメディアクエリのブレイクポイントを複数用意するというのが考えられる。</p>
<pre><code class="language-css">@media (min-width: 20em) {
:root { --measure: 18em; }
}
@media (min-width: 22.5em) {
:root { --measure: 20em; }
}
@media (min-width: 25em) {
:root { --measure: 22em; }
}
...
@media (min-width: 45em) {
:root { --measure: 36em; }
}
main {
width: min(var(--measure, auto), 90vw);
}
</code></pre>
<p>ビューポート幅が20em以上ならコラム幅は18文字分、22.5emあれば20文字……というふうに、任意の間隔で複数のブレイクポイントを設定し、それぞれに対してコラム幅を定義していく。この方法ならビューポートに応じた緻密なコントロールが可能だし、じっさい意図通りに動作する。このサイトでも以前はこのようにしていた。しかしこれはきりがないというか、設計するのも維持するのもたいへんなうえ、特定のデヴァイスを想定したデザインになりがちという欠点もある。</p>
<p>そのかわりに、CSSグリッドの<code>repeat()</code>関数と<code>auto-fit</code>値を使うと、コラム幅をビューポートに対してリキッドにし、かつ文字サイズの整数倍に制限できる。メディアクエリは不要。以下の例では、<code>main</code>の子要素の幅が90vwもしくは36em以内でつねに文字サイズの整数倍になる。</p>
<pre><code class="language-css">main {
display: grid;
grid-template-columns: repeat(auto-fit, 1em);
justify-content: center;
margin-inline: auto;
width: min(36em, 90vw);
}
main > * {
grid-column: 1 / -1;
}
</code></pre>
<p>まず親要素のグリッドで1em単位のコラムをスペースが許す限り生成し(<code>grid-template-columns: repeat(auto-fit, 1em)</code>)、その子要素をグリッドの両端に合わせて配置する(<code>grid-column: 1 / -1</code>)。そうすることで子要素の幅を1em単位、つまり文字サイズの整数倍に制限している。<code>justify-content</code>とインライン方向のマージンは、ボックス全体を中央寄せにするためのものなので、左寄せにするなら不要。<code>repeat()</code>関数の<code>auto-fit</code>は<code>auto-fill</code>に変えても結果が変わらないように思うんだけど、この場合にはどっちを使うのが適切か確信が持てなかったので、ひとまず短く書ける<code>auto-fit</code>を採用している<ins cite="https://twitter.com/_yuheiy/status/1396430873877094409" datetime="2021-05-30"><small>(<code>auto-fit</code>と<code>auto-fill</code>のどちらが適切かについて、記事の公開後に<a href="https://twitter.com/_yuheiy/status/1396430873877094409">@_yuheiyの指摘</a>を受けた。今回の使い方ではどちらでも結果は変わらないが、<code>minmax()</code>関数を使ったときの挙動を考えると<code>auto-fill</code>の方がコードの意図が伝わりやすいのでは、とのこと。たしかに、ここでのグリッドの使い方は典型的なものではないこともあり、より結果がイメージしやすい方を選ぶというのは理にかなっていると思う。コード例では<code>auto-fit</code>を使ってますが、やっぱり<code>auto-fill</code>を使った方がよさそうです)</small></ins>。</p>
<p>この方法がとくに効果を発揮するのは、やはりスマホなど狭い画面においてだろう。左右に最低限のマージンを確保しつつ、コラム幅は文字サイズの整数倍でとりうる最大値にするということが、実際のデヴァイスのサイズを考慮せずとも可能になる。</p>
描写から構成へ
2021-11-28T00:00:00Z
https://terkel.jp/archives/2021/11/every-layout/
<p>ヘイドン・ピカリングとアンディ・ベルの共著『<a href="https://www.borndigital.co.jp/book/24538.html">Every Layout</a>』が日本語に翻訳された。光栄なことに僕も出版前のレビュワーのひとりとして、微力ながらお手伝いさせていただいている。</p>
<p>タイトルが示すとおり、本書はCSSによるウェブデザインのうち「レイアウト」の問題に焦点を絞ったものだ。レイアウトといってもページ全体のグリッドのことだけではなく、ボタンやアイコンのような小さな部品に至るまで、CSSが「ボックス」として扱うあらゆる要素を対象としている。</p>
<p>テーマの根底にあるのは「コンポジション」というコンセプトだ。CSSによってインターフェイス部品を形づくるとき、それらひとつひとつを独自の、独立したものとして捉えるのではなく、基本的で小さなレイアウトの組み合わせたコンポジションとして捉えるべきである、と著者は主張する。そしてそのように組み合わされる小さなレイアウトを「レイアウト・プリミティヴ」と名づけ、それらを再利用しやすい形で定義し、カタログとしてまとめている。</p>
<p>デザインにおけるコンポジション――日本語でいうところの「構成」とは、すでにある素材をただ組み上げることではない。構成には効率化や合理化といったものを超えた、より重要な意味がある。高安啓介は近代デザインにおける構成の概念について次のように述べている<small>(『<a href="https://www.msz.co.jp/book/detail/07902/">近代デザインの美学</a>』、みすず書房、2015年)</small>。</p>
<blockquote>
<p>近代デザインは、二十世紀のはじめに二つの流れが合流したところで見出されてきたものであり、二つの流れを含みながら発展してきた。その一つは、産業の流れで、そこでは、製品を装飾するよりも製品自体をいかに構成するかが強く意識された。もう一つは、美術の流れで、そこでは、対象を描写するよりも平面や立体それ自体をいかに構成するかが強く意識された。したがって、近代デザインにおいて構成はもっとも重要な理念だったといえる。</p>
</blockquote>
<p>装飾や描写から構成へ、という運動が近代デザインの中心にあったわけである。『Every Layout』が主張するコンポジション指向のCSSも、まさにこの流れを汲むものといっていい。では構成がそこまで重要な概念であるのはなぜか。高安は構成とは素材に対する外部からのコントロールであると同時に、素材による内部からの運動を引き出すための行為でもあると指摘する。</p>
<blockquote>
<p>構成とは何かをより掘り下げて考えてみるならば、構成とは素材をまとめあげる行為であるかぎり、素材にたいして何かを強いる行為であるにちがいない。誇張していうと、構成という行為には、支配がはらまれており、それゆえに、暴力がはらまれている。ただしそうみるときに、私たちは、内からの構成という理想をかかげることができる。すなわち、構成とはたしかに素材にたいして何かを強いる行為であるが、それでも、素材からの働きかけに応じながら、素材のなかから秩序をもたらす可能性にかけることはできる。そしてそれがもし成し遂げられたなら、支配という能動はなお維持されるにしても、素材にしたがうかぎり、模倣という受動がはらまれることになる。さらにまた、内からの構成がなしとげられたときには、作り上げられた形象の内部において、生きた交通がみとめられるはずである。すなわち、要素どうしの自由な相互作用がみとめられるはずである。</p>
</blockquote>
<p>「描写よりも構成を」というと、造形が無機質で無個性なものになるのではないかと懸念する向きもあるかもしれないが、そうではない。むしろコンテンツの力を最大限に引き出し、さらにはコンテンツどうしの相互作用を促すのが、構成というものの本来の意図である。『Every Layout』が提唱している、コンテンツ自身によって内在的にレイアウトを決定させるという手法も、レイアウトという行為は絶対の命令ではなく意図の提示であるべきという視点も、まさに高安のいう「内からの構成という理想」を実現するためのものにほかならない。</p>
<p>CSSの仕様と実装の進歩は目覚ましい。作り手にとってCSSは、ブラウザーにこと細かな指示を与えるためのものではなく、デザインの意図を表現するためのものになりつつある。『Every Layout』の実例の数々は、ブラウザーが備える優れたアルゴリズムをごくシンプルなCSSによって引き出せることの鮮やかな証明だ。</p>
<p>それが何であるかを描写するためのCSSから、それがどのような形であるべきかを示すためのCSSへ。本書はそんな新しい視点を与えてくれる一冊と言える。</p>
意外と読めた
2022-06-12T00:00:00Z
https://terkel.jp/archives/2022/06/reading-books/
<p>ここ最近は休日に仕事と関係のないことがしたくて、本を読んでいる。いつしか休日でも仕事について考えたり手を動かしたりすることが多くなって、これはちょっとよくないなと感じたので。もちろんいままでも本は読んでたけど、仕事につながる実用的なものばかり読むようになってきて、読書を楽しむという感じじゃなかった。それでも仕事が順調なときは別にいいんだけど、残念ながらいつでもすべてがうまくいくわけではないし。</p>
<p>いつだったか買ったけど読まずにいたトマス・ピンチョンの『V.』上下巻(小山太一/佐藤良明訳、新潮社、2011年)が本棚にあったので、手にとった。小説を読むこと自体がずいぶん久しぶりで、しかもピンチョンだし、はたして読めるだろうかと少し心配だったけど、意外と読めた。何日かかけて上巻を読み終わったところ。</p>
<p>『V.』がどんな本か説明するのはちょっと難しいんだけど、おかしくて、いろんな読み方ができる小説だと思った。なんというか、ただテクストがあって、ただそれを目で追うだけ、ということが面白くて、本を読む楽しさを思い出した感じ。</p>
即物的
2022-06-19T00:00:00Z
https://terkel.jp/archives/2022/06/sachlich/
<p>デザインについて書かれたものを読んでいると、たまに「即物的」という言葉に出くわすことがあります。たとえばヨゼフ・ミューラー゠ブロックマンの『グリッドシステム』(古賀稔章訳、ボーンデジタル、2019年)にも、こんなふうに何度か出てきます。</p>
<blockquote>
<p>これはデザイナーという職業に対する信念の表明なのである。つまり、デザイナーの仕事は、数学的思考に基づいて明白でわかりやすく、即物的かつ機能的でなければならず、また、美的な質を備えていなければならない、という信念である。</p>
</blockquote>
<p>僕は以前、この即物的という言葉をネガティヴな意味で捉えていました。深い考えのない短絡的な行動や、精神的な充足よりも物質的な豊かさを重んじる態度といった、あまり感心しないあり方を指すものだと。「即」の字が即席や即効といった言葉を連想させ、そこから手っ取り早い安易な手法のようなイメージにつながるのかもしれません。</p>
<p>もちろんそういった悪い意味で用いられることもありますが、しかし辞書を引いてみると必ずしもそういう言葉ではありません。即物的とは文字どおり「物に即して」、つまり観念的・抽象的・主観的にではなく、客観的に実際の事物を見ることをいいます。ですからデザインにおける即物的な態度とは、対象となる素材や媒体をあるがままにとらえるということであって、それはデザイナーとしてじつにまっとうな姿であるわけです。</p>
<p>僕が即物的という言葉をネガティヴな意味にしか捉えられていなかった背後には、具体的なものごとよりも抽象的な概念の方がより価値が高い、という思い込みがあるように思います。そしてそういう思い込みは僕だけのものではなくわりと一般的なもので、しかもそれがいろんなところに影響を及ぼしている気がします。どこで植えつけられるんでしょうね、こういうの。</p>
2020年版テーマ
2022-12-19T00:00:00Z
https://terkel.jp/archives/2022/12/theme-2020/
<p>このサイトでは現在、2020年の春頃にデザインしたスタイルを採用している。近ぢか新しいテーマに差し替える予定なので、今さらではあるけれど、この2020年版デザインの意図などを(思い出せる範囲で)書いておこうと思う。</p>
<figure>
<img alt="" src="https://terkel.jp/img/theme-2020-1.png" width="1728" height="1080" decoding="async" />
</figure>
<p>まず、すべてのテクストは同じ書体、同じ文字サイズ、同じ行送りにするというルールを設定している。書体は筑紫ゴシックのRとB、文字サイズは16pxで、行送りは28px。見出しやキャプションなど、ふつうなら異なる書体や文字サイズを使う要素でも、余白や行揃えなどを工夫することで表現した。これはうまくいっている部分もそうでない部分もあり、たとえば見出しの階層構造なんかはややわかりづらくなってしまったかもしれない。</p>
<p>なぜこんな制限を課すのかといえば、それはこのサイトをウェブ・デザインの実験や修練の場として捉えているためである。とはいえ読みやすさを考慮しないわけではもちろんなく、制限の中でいかに読みやすさを実現するかを意識している(少なくともそのつもり)。</p>
<figure>
<img alt="" src="https://terkel.jp/img/theme-2020-2.png" width="1728" height="1080" decoding="async" />
</figure>
<p>本文の行長は最大36字。本文ブロックは左寄せで、6字分のマージンを持たせている。中央ではなく左寄せの配置にしているのは、ブラウザーのエッジをデザインの要素として取り込むことで、段落や引用ブロックなどの字下げをより際立たせたいという意図がある。</p>
<p>段落の切れ目は空行ではなく字下げで表現している。見出しや図版の直後など、先行する段落がなければ字下げはせず、段落が連続する場合の2つめ以降の先頭行を2字下げるというルールである。下げ幅を1字ではなく2字としているのは、行末が不揃いになりがちだったり、始め括弧類の行頭天つきが実現できなかったりするウェブにおいて、1字下げでは段落の境界として弱いと考えたため。中国語の組版にならったというのもある。</p>
<figure>
<img alt="" src="https://terkel.jp/img/theme-2020-3.png" width="1728" height="1080" decoding="async" />
</figure>
<p>縦方向のグリッドはすべて行送り28pxの整数倍で構成。ヘッダーとタイトルの間やタイトルと本文の間、本文とフッターの間などの余白は、行送りにフィボナッチ数(1、2、3、5……)をかけたものになっている。</p>
<p>フッターの先頭には本文との区切りとして中点(・)を置いた。こういう部分にボーダーや画像ではなく約物を使うのが個人的な好み。ブログをデザインしていると、「記事本文はここで終わりですよ」ということを示すのが意外と難しくて、いつもけっこう悩んでしまう。</p>
<p><br /></p>
<p>ちなみにこういうデザインにしようと思ったのは、たしか<a href="https://www.printing-museum.org/">印刷博物館</a>の「世界のブックデザイン」展でなんかの本を見て触発されたからだった気がする。</p>
ナンバー・ナイン
2022-12-25T00:00:00Z
https://terkel.jp/archives/2022/12/number-nine/
<p>約3年ぶりにこのウェブサイトをリデザインした。Gitの履歴が整理されていないうえ記憶も定かではないが、おそらく9代目のテーマのはず。書体選定やタイポグラフィとグリッドの設計、文書構造などについて解説してみたい。</p>
<figure>
<img alt="このウェブサイトのブログ記事先頭部分のスクリーンショット" src="https://terkel.jp/img/theme-2023-1.png" width="1843" height="1152" decoding="async" />
</figure>
<p>本文書体は筑紫明朝のLBで、キャプションや小見出しは筑紫ゴシック。明朝体は横画が細いため、書体によってはスクリーンでかすれて読みづらくなってしまうことがある。とくにスマホやタブレットではサブピクセル・レンダリングの特性上、その傾向がより顕著だ。しかしこの筑紫明朝のLBというスタイルは全体的にストロークが太めにデザインされていることもあり、スクリーンにおいても可読性が高いと考え、本文書体として採用した。</p>
<p>本文の文字サイズは17.067px、行送り32pxで、これがページを構成するグリッドの基本単位となっている。各要素の文字サイズは本文を中心に調和数列を構成するよう設計していて、タイトルは本文の5 / 3、中見出しは5 / 4、小見出しとキャプション、フッターなどは5 / 6とした。</p>
<figure>
<table>
<thead>
<tr>
<th style="text-align:left"></th>
<th style="text-align:left">文字サイズ</th>
<th style="text-align:left">行送り</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">タイトル(<code>h1</code>)</td>
<td style="text-align:left">28.444px (5/3)</td>
<td style="text-align:left">40px</td>
</tr>
<tr>
<td style="text-align:left">中見出し(<code>h2</code>)</td>
<td style="text-align:left">21.333px (5/4)</td>
<td style="text-align:left">32px</td>
</tr>
<tr>
<td style="text-align:left">本文</td>
<td style="text-align:left">17.067px (1)</td>
<td style="text-align:left">32px</td>
</tr>
<tr>
<td style="text-align:left">小見出し(<code>h3</code>)</td>
<td style="text-align:left">14.222px (5/6)</td>
<td style="text-align:left">24px</td>
</tr>
<tr>
<td style="text-align:left">キャプション</td>
<td style="text-align:left">14.222px (5/6)</td>
<td style="text-align:left">24px</td>
</tr>
</tbody>
</table>
<figcaption>文字サイズのスケール(デスクトップ)</figcaption>
</figure>
<p>これら文字サイズと行送りを決定するにあたっては、まず本文の行送りを32pxとするところから出発している。これは現在のウェブ・デザインにおいて標準的な本文サイズである15pxから18px程度のテクストが読みやすく、かつ垂直方向のグリッドを構築するうえで取り扱いやすい数値として選択した。文字サイズはピクセル単位よりもプロポーションを重視し、行送りの8 / 15とした。その結果が17.067pxという数値である。</p>
<p>これらのサイズはすべてルート要素に対する相対値として指定している。幅の狭い画面ではルートの文字サイズをデフォルトの15 / 16に設定し、全体がひとまわり小さいスケールで表示されるようにした。</p>
<p>行長は最大36字。本文ブロックは左寄せで、6字分のマージン。CSSグリッドを使って、幅がつねに本文サイズの整数倍になるようにしている。段落先頭は2字下げ、ただし先行する段落がなければ字下げなし。リストや引用ブロック、コード・ブロックは全体を2字下げ。<code>body</code>要素上下のマージン8pxをデフォルトのまま残しているのは、<a href="https://www.miriamsuzanne.com/2022/07/04/body-margin-8px/">Mosaicブラウザーから続く伝統</a>に敬意をはらってのこと――というのはあとから考えた理屈だけれど、半分本気でもある。</p>
<figure>
<img alt="このウェブサイトの「著者について」ページのスクリーンショット" src="https://terkel.jp/img/theme-2023-2.png" width="1843" height="1152" decoding="async" />
</figure>
<p>ブログ個別ページでは<code>title</code>要素にサイト名を入れず、記事タイトルのみとした。<code>article</code>要素も廃し、<code>body</code>がそのまま記事のルートであるという、シンプルな構成になった。記事をサイトの中の個別ページとするのではなく、それぞれが独立したウェブページであると捉えなおそうと考えた結果である。</p>
<p>画面上端にはサイト名と記事の公開日を小さく配置している。これらの要素はブック・デザインでいうところの柱とノンブルとして捉え、本文に付随してその属性を示すものとして扱っている。書体は本文の等幅書体としても使っているLucasFontsのTheSansMono Condensedで、オールドスタイルの数字がノンブルにふさわしいと考えて採用した。</p>
<p>このあたりの文書構造を再考するにあたっては、Hail2uの「<a href="https://hail2u.net/blog/removing-article-element-from-blog-articles.html">雑記記事からarticle要素を削除</a>」や、ゆうへいの「<a href="https://yuheiy.com/2022-05-03-yuheiy.com-v6">yuheiy.com-v6</a>」といった記事、およびそれらサイトのソースコードも参考にさせてもらった。</p>
<figure>
<img alt="このウェブサイトのフッター部分の、ダーク・モード適用時のスクリーンショット。" src="https://terkel.jp/img/theme-2023-3.png" width="1843" height="1152" decoding="async" />
</figure>
<p>いわゆるダーク・モードにも対応した。明るいテーマでは<code>#ffffff</code>の背景に<code>#1c1d1f</code>のテクスト、暗いテーマでは背景を<code>#1c1d1f</code>、テクストを<code>#dfe1e2</code>としている。暖色系の組み合わせも試してみたものの、最終的には一般的なブラウザーやOSの色味に合わせ、ブルー寄りのグレースケールに落ちついた。</p>
<p>ファビコンも新たにSVGで作り、ボディと同様に色が反転するようにしてみた。</p>
<p><br /></p>
<p>今回のデザインは「自分がブログを読むならこういうデザインで読みたい」という考えを、かなりストレートにそのまま形にしたものと言える。その点ではなかなか満足している。一方でより個人サイトらしいサイトにしたいという狙いもあり、たとえばソーシャル・メディア関連のメタ要素を削除したのもその一環なのだけれど、そのあたりはまた別の機会にあらためて書きたい。</p>
千駄木から金沢へ
2023-02-02T00:00:00Z
https://terkel.jp/archives/2023/02/sendagi-kanazawa/
<p>東京の千駄木から石川の金沢へ引っ越すことになった。いまはその準備を少しずつ進めているところで、役所に書類を出したり、ガス会社に連絡したり、ギターやCDを処分したりしている。</p>
<p>千駄木は好きな町だった。治安が良くて、にぎやか過ぎず、どことなく文化的な雰囲気のあるところだ。千駄木という名前もいい。5年半ほど住んだけど、なかなか名残り惜しい思いがする。もしまた東京に住むことがあったら、やっぱりこのあたりで家を探すかもしれない。</p>
<p>ところで金沢に移り住むと言うと、北陸の冬は厳しいから覚悟したほうがいいと親切に教えてくれる人がある。天の邪鬼なので、そうした助言を僕はなんだか複雑な気持ちで聞く。ありがとう、うまくいくかわからないけど頑張ってみるよ、というのが半分。ほうっておいてくれ、これは僕の人生なんだから、というのが半分。</p>
いまのところとてもいい
2023-04-29T00:00:00Z
https://terkel.jp/archives/2023/04/so-far-so-good/
<p>金沢に引っ越してきて2か月になる。今のところ新しい暮らしにはとても満足している。</p>
<p>なにしろ近所で買える魚や野菜がどれもおいしい。それだけでも引っ越してよかったと感じる。行ってみたい寿司屋や居酒屋やなんかもたくさんあるけれど、家で食べるのが楽しいというのもあって、まだほとんど行けずにいる。だからもし金沢でおいしいお店を教えてほしいと言われても、残念ながらあまり気のきいた提案はできそうにない。</p>
<p>前に住んでいた東京の家はかなり古く(たしか築50年とかそのくらい)、間取りや設備などの面でかなりの不満があった。対して新しい住まいはそこそまで古くないふつうのマンションで、そういったストレスはほとんどない。なるほどこれが現代のふつうのマンションかと感心している。今の生活を快適と感じるのは、金沢という場所だけではなく住居によるところも大きい。</p>
<p>仕事はこれまでと変わらずリモートで、ただ年に数回は東京と福岡のオフィスに出社するつもりでいる。会社には働き方について柔軟に対応していただき、たいへん感謝しています。</p>
rlh単位
2023-12-23T00:00:00Z
https://terkel.jp/archives/2023/12/rlh-unit/
<p>11月リリースのFirefox 120でCSSの<code>rlh</code>単位がサポートされ、すべての主要なブラウザーで使えるようになった。</p>
<p><code>rlh</code>はルート要素の<code>line-height</code>に対する相対単位である。<code>html</code>要素で本文の文字サイズとともに行送りを定義しておけば、たとえば「引用ブロックは前後に1行分のアキをとり、全体の行頭を2文字分下げる」といった指定を以下のように書ける。</p>
<pre><code class="language-css">html {
font-size: 120%;
line-height: 1.875;
}
blockquote {
margin-block: 1rlh;
margin-inline: 2rem 0;
}
</code></pre>
<p>このように水平方向は文字サイズ基準の<code>rem</code>、垂直方向は行送り基準の<code>rlh</code>という単位の使い分けができ、タイポグラフィを中心に据えたレイアウトをよりシンプルに記述できるようになった。このサイトにもさっそく導入している。</p>
2024年の石井ゴシック
2024-12-01T00:00:00Z
https://terkel.jp/archives/2024/12/ishii-gothic-2024/
<p>先日リリースされた<a href="https://www.morisawa.co.jp/fonts/specimen/13373">石井ゴシック</a>が良い。このサイトでもさっそく全面的に採用した。とても気に入っている。</p>
<p>石井ゴシックはもともと、<a href="https://sha-ken.co.jp/">写研</a>が1930年代から70年代にかけて開発した、写真植字機用の書体である。90年代頃まで広く使われていたが、デジタル化されなかったために2000年代以降は目にする機会が減っていった。その後2020年代に入り、写研とモリサワ、字游工房の3社によって写研書体をOpenTypeフォントとして改刻するプロジェクトが発足。石井ゴシックは2024年に復活することとなった。</p>
<p>わたしは1970年代生まれなので、まさに写研の書体に触れて育った世代だが、しかしそれらの書体に特別な思い入れがあるわけではない。たとえば石井ゴシックで組まれた80年代の雑誌をいま見ても、そう言われてみれば見覚えがあるような気もする、という程度のものである。当時のわたしは活字や組版といったものにそこまで興味があったわけではないし、書体の違いを気に留めることもなかったはずだ。だから今回の石井ゴシックのリリースをわたしは、懐かしい書体との再会ではなく、ただ新しい書体の登場として受け止めた。そしてじつに魅力的な書体だと感じたのだ。</p>
<p>字面が小ぶりで、軽やかな読みやすさがある。とくに漢字の造形が絶妙。欧文グリフもなかなか可愛い。いわゆるオールドスタイル・ゴシックだが、ことさらにアナログでレトロな雰囲気を強調せず、あくまで現代の書体として使いやすいものが目指されている。これからのスタンダードなゴシック体として、たとえば游ゴシック体やこぶりなゴシックに代わる有力な選択肢になる書体だと思う。</p>
<p>写研書体のOpenType化計画はこれからも続き、最終的に100書体がリリースされる予定だという。個人的には石井丸ゴシックの改刻ファミリー化に期待している。</p>
ワイアード、サーカムオーラル、オープンバック
2024-12-21T00:00:00Z
https://terkel.jp/archives/2024/12/wired-circumaural-open-back/
<p>ヘッドフォンを買った。ゼンハイザーのちょっといいやつ。5年近く勤めた会社を辞めたところだったので、転職祝いとしてこのくらいの贅沢は許されるだろうと自分に言い聞かせて。</p>
<p>オーディオ機器と呼べるものを買うのはずいぶん久しぶりだ。最後にヘッドフォンを買ったのはいつだったかも思い出せない。おそらく前世紀のことだと思う。当時はかなり貧乏だったけど、音楽を聴くためのシステムにはそれなりのお金と手間をかけていた。アンプにスピーカー、ターンテーブル、CDプレイヤー、カセットデッキ。それが今ではもっぱらスマホとワイヤレス・イヤフォンの組み合わせになり、音質やなんかはあまり気にしなくなってしまった。</p>
<p>中学生の頃からか、ずっと音楽を聴きつづけてきた。映画をしばらく観ない時期があったり、読書の意欲がわかないことがあったりしても、音楽への興味を失うことだけはなかった。いつだって何かを聴いている。だったら音楽を聴くこと自体をもっと大事にしてもいいんじゃないか、とあらためて思う。</p>
<p>新しく買ったヘッドフォンは有線で据え置き型のDACに接続している。だから聴いているあいだはどこへも行けない。このつながれた感覚がなんだか嬉しい。</p>