カード型デザインのはてなブログ用テーマZeno Teal(仮)は、もう少ししたら公開できそうです。とりあえずそのテーマのキモとなっているカード型デザインの「タイトルの上にアイキャッチ画像を表示する」方法について解説します。
これはもちろんcssで制御するのですが、これにはいくつかの方法があります。
display:tableを利用する
基本的には以下の記事で紹介されています。
www.cocococococococococococo.com
htmlの構造
はてなブログのトップページ、各エントリー部分の構造は以下のようになっています。(かなり簡略化しています。)
<article class="entry"> <div class="entry-inner"> <header class="entry-header"> <div class="entry-date"> 投稿日 </div> <h1 class="entry-title"> 記事タイトル </h1> <div class="entry-categories"> カテゴリー </div> </header> <div class="entry-content"> 記事本文 <a class="entry-see-more">続きを読む</a> </div> <footer class="entry-footer"> <p class="entry-footer-section"> 投稿者・投稿日 </p> <div class="social-buttons"> SNSボタン </div> <div class="comment-box"> コメント </div> </footer> </div> </article>
簡略化した表示
図であらわすと以下のようになります。
イメージつくでしょうか。これのheader(.entry-header)と.entry-contentの位置を入れ替えて、本文の最初に画像があれば、画像→タイトルという順番になります。
cssで順番を制御
順番を入れ替えるために、cssに以下のように入力します。
.entry-inner{display:table;} .entry-content{display:table-header-group;}
これで入れ替わります。
少し説明すると、.entry-header
や.entry-content
を含む.entry-inner
にdisplay:table;
を指定することでテーブルのような表示になります。そして.entry-content
にdisplay:table-header-group;
を指定することで、.entry-content
はテーブルのヘッダーとして表示されます。ヘッダーなのでテーブルの最初に、一番上に表示されます。逆にdisplay:table-footer-group;
を指定すればフッターとなり、.entry-inner
内の最後に表示されるようになります。
これだけでもいいのですが、(カード型だと特に).entry-footer
部分は必要ないので非表示にします。
.entry-footer{display:none;}
これでスッキリしました。画像のすぐ下に「続きを読む」を持ってきて本文は表示させないほうがいいでしょう。
position:absoluteを使う
別の方法を考えてみました。(というよりは、最初の方法は私は思いつかなかったので、自分で考え、このブログでも使っているのはこちらになります。)
まずデフォルト状態です。(.entry-footer
は非表示にしています。)
.entry-contentを上に持ってくる
以下のcssを適用します。
.entry{position:relative;} .entry-content{position:absolute;top:0;}
これで表示は以下のようになります。
よくわからないかもしれませんが、.entry-content
が親要素.entry-inner
のtop:0
、つまり一番上に移動しました。.entry-header
とは重なって表示されます。
.entry–headerを下に持ってくる
タイトルを画像の下に表示するために、画像の縦の大きさ分だけ下にずらします。
.entry{position:relative;} .entry-content{position:absolute;top:0;} .entry-header{position:relative;top:180px;left:0;}
画像の下にはなりましたが、本文とタイトルがかぶっています。
本文を間に移動する
本文はタイトルの下にしたいので、タイトルの高さを決めてしまい、その下に本文が来るように調整します。
.entry{position:relative;} .entry-content{position:absolute;top:0;} .entry-header{position:relative;top:180px;left:0;height:120px;overflow:hidden;} .entry-content img:nth-of-type(1){margin-bottom:150px;}
.entry-content img:nth-of-type(1)
というのは、.entry-content
の中の最初のimg要素ということです。本文の先頭に画像があること前提ですが、その画像の下に.entry-header
分のマージンを作っています。これで見た目上は画像→タイトル→本文になりました。
あとは一応.entry
の高さも指定しておけばOKです。
.entry{position:relative;height:420px;} .entry-content{position:absolute;top:0;} .entry-header{position:relative;top:180px;left:0;height:120px;overflow:hidden;} .entry-content img:nth-of-type(1){margin-bottom:150px;}
細かい数値はそれぞれのブログで変えなくてはなりませんが、だいたいの考え方はこのとおりです。カード型のように見せるには.entry
のスタイルをもっと調整する必要がありますね。
まとめ
うん、わかりにくいですね。とりあえず、最初の方法は.entry-content
をヘッダー扱いにして最初に持ってくる(順番を変える)ということで、2つ目の方法は順番ではなく表示位置を指定するという方法です。
単に画像を上に持ってくるだけなら最初の方法でいいのですが、画像と本文の間にタイトルを持ってくるようにするには2つ目の方法がいいと思います。
何かほかにも方法はあるかもしれません。cssはいろいろできますからね。1つの結果をいろいろな方法で実現させるのを考えるのも面白いです。
追記:display:flexを使う
もう1つあったのを書くの忘れていました。要素を横並びにするdisplay:flex
いわゆるflexboxを使う方法です。
.entry-inner{ display: -webkit-flex; /* Safari */ -webkit-flex-direction: column; /* Safari */ display: flex; flex-direction: column; } .entry-content{ -webkit-order: 1; /* Safari */ order: 1; } .entry-header{ -webkit-order: 2; /* Safari */ order: 2; } .entry-footer{ -webkit-order: 3; /* Safari */ order: 3; }
flexboxはflex-direction: column
を指定すると縦並びになります。そしてorder
はflexboxの子要素の順番をコントロールします。デフォルトが0なので、.entry-content
にorder: -1
を指定すれば他の要素の前に表示されます。.entry-header
, .entry-content
, .entry-footer
それぞれに指定すれば順番は思うままです。
個人的にはこれが一番スッキリしていて理解しやすいかな、と思います。まぁ画像と本文の間にタイトルを挟むには2つ目の方法のようなことをやらなければならないですが。