Kindle で電子書籍を出してハマった点(HTML, CSS)
個人で Kindle の電子書籍を作る機会がありまして、普段ウェブページを作っている経験から HTML5, CSS3 の技術仕様をある程度知っていれば楽勝かと思いきや、思わぬところでハマった部分や分からない部分があったので、備忘録を兼ねて残しておきます。
参照したのはEPUB Packages 3.1の仕様とAmazon Kindle パブリッシング・ガイドライン(kindlegen.s3.amazonaws.com
)の2つです。
用意したファイルは以下の4種類です。
- OPFファイル(XML)
- 表紙画像
- 目次ファイル(XHTML)
- コンテンツファイル(XHTML, CSS, 画像など)
このうち、表紙画像は画像ファイルを用意してOPFファイルにそのリソース位置を一行記すだけですし、OPFファイルと目次ファイルもEPUB仕様書にコードサンプル付きが書かれているので、とくに難しい点はありませんでした。
以下はコンテンツファイルに関することです。
文字エンコーディング宣言
ウェブページを作る際、HTTPヘッダで
Content-Type: text/html; charset=utf-8
を出力していれば(X)HTML内に文字エンコーディングを記述する必要はありません。これがもっともシンプルかつ確実なわけです。
一方、何らかの事情で(X)HTML内に文字エンコーディングを記述する場合、これは大変複雑です。
まず、(X)HTML内に記述しなければならないケースとして
という条件があり、その上で
<meta charset="utf-8">
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<?xml version="1.0" encoding="utf-8"?>
の3種類の書き方があります。
3種類のうち好きな書き方を選んで良いわけではなくて、HTML文書(text/html
)かXHTML文書(application/xhtml+xml
)かによって効果のある記述が変わってきます。それを把握するには仕様の 4.2.5.4 節以外にも目を通さなければならないですし、また仕様だけでなくブラウザ側の挙動も知っておく必要があり[1]、初心者が使いこなすのは困難でしょう。
電子書籍の場合、複数の(X)HTMLファイルをEPUB形式(Kindleの場合は .mobi または .azk ファイル)に変換してオフラインでも読めるようになりますから、たぶんHTTPヘッダは関係なくて(X)HTMLファイル内の文字エンコーディング宣言を認識するんじゃないかと思います。
その辺の詳しい原理に関する記述は見つけられませんでしたが、Amazonのガイドライン「6.6 サポートされているその他のエンコード」にはこのように書かれています。
そして以下のコードが参考として書かれています。
<html>
<head>
…
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
…
<?xml version="1.0" encoding="UTF-8"?>
Kindleの場合、コンテンツのHTMLは text/html
形式で記述しても問題なさそうで、それなら <meta charset="utf-8">
でもいいような気がしますが、まあこのように書かれている以上、http-equiv
属性かXML宣言のどちらかにしておいた方が良いのかもしれません。
max-width
, max-height
が使えない
リキッドデザインのページでは、画像に対して
img {
max-width: 100%;
height: auto;
display: inline-block;
}
などと指定して、大きな画像が小さい画面ではみ出ないようにすることがよく行われますが、ガイドライン「16.3.1 無視されるHTML タグ」によると、 Kindle では max-width
, max-height
は効かないようです。「9.4.3 レスポンシブレイアウトの画像サイズ」では
と書かれているので、
<img src="" alt="" style="width: 100%"/>
とするのが良いようです。
で、全幅の画像はこれで良いのですが、困ったケースもあります。
例えば横幅200pxの画像を横並びにしたい場合、本来は以下のように書けば「大きな画面では200pxで表示、スマホ縦のような小さい画面では画面幅の50%で表示」となります。
<style type="text/css">
img {
max-width: 50%;
height: auto;
display: inline-block;
}
</style>
<img src="image1.png" alt="" width="200" height="200"/><!--
--><img src="image2.png" alt="" width="200" height="200"/>
ところが max-width
が使えないとなると
<img src="image1.png" alt="" style="width: 50%"/><!--
--><img src="image2.png" alt="" style="width: 50%"/>
とせざるを得ず、この場合大きな画面でも画面幅の50%で表示されますから、画像自体もそれなりに大きなサイズのものを用意しなければなりません。
これは max-width
で実装するのと同等の効果を持つ代替策が思いつきませんでしたので、容量増には目をつむって iPad Pro 12.9 インチなど大きなタブレットも想定したサイズの画像を用意することで対処しました。
type="text/css"
は必須
スタイルシートを記述する際、 link
要素、style
要素、style
属性のいずれかを使います。
HTML4 時代は style
要素の type
属性が必須(link
要素の方は任意)、また style
属性を使う際は HTTP ヘッダまたは meta
要素でデフォルトスタイルシート言語を指定する必要がありましたが、 HTML5 ではどちらも不要になりました。
ところが、 Kindle においては type
属性を書かないとスタイルシートを認識しないようです。しかもOSによって対応が異なり、 iOS は link
要素、style
要素ともに必須、 Windows, Android は link
要素には必須ですが style
要素は省略しても認識しました。
まあともかく全部書けばいいだけですし、書くことによるデメリットもないので対応は簡単なのですが、なにぶんガイドラインに記述がなかったので、原因を特定するまで時間が掛かってしまいました。
:target
疑似クラスが効かない
EPUBは電子書籍フォーマットだけあって、書籍ならではの表現に特に注意が払われています。
その一つに「脚注」があり、ガイドラインでも 9.3.12 節に「脚注のガイドライン」がサンプルコード付きで書かれています。
aside
要素や epub:type
属性を使うなど、セマンティックを重視した書き方を推奨されており、それはそれでいいのですが、そこまでやるなら脚注にジャンプしたり、脚注から元の場所に戻ったりしたときに :target
疑似クラスを使って背景色を変えるなど強調表示にもこだわりたいところです(Wikipediaがやっているように)。
ところが :target
疑似クラスは認識されないようで、そのようなスタイル付けはできなさそうです。困ったのは、それがガイドラインからは分からないことで、疑似クラスやCSSセレクターなどは一部しか対応可否が書かれていないのです。まあ未記載のものは未対応ということなのかもしれませんが、こういったガイドラインに未記載なものは実際に端末に表示させて対応可否を確認するしかないのでしょうかね。私が電子書籍の制作手法に疎いだけなのかもしれませんが、まるで Firebug すらなかった時代のようなやり方をしていて、もう少しなんとかならないものかなーと思った次第です。
脚注
-
1.
例えばテキストブラウザで有名なLynx(
lynx.invisible-island.net
)が<meta charset="">
に対応したのは2012年2月12日リリースの 2.8.8dev.10 であり、Lynx for Win32(lynx-win32-pata.osdn.jp
)が追従した 2.8.9rel.16TH をリリースしたのは2017年9月9日です。メジャーなブラウザではかなり昔からcharset
属性を認識しているそうですが、このようなマイナーブラウザまで考慮すると、つい最近まで対応していないものが存在し、いやもしかしたら未だ対応していない環境すらあるかもしれません。 ↩ 戻る