はてなブログテーマ開発(6)Javascript を使って要素を移動する
WordPress や Joomla! を使って自分でブログを立ち上げれば、そもそもの基本構造も自由に変えられるのですが、はてなブログなどではそんなわけにはいかず、せいぜい CSS で見た目を変えるくらいしか出来ません。じゃあ、いっそのこと Javascript で要素を移動したらどうなるのか、ということをやってしまいました。
はてなブログテーマ開発6回目です。
はてなブログテーマ開発(1)
はてなブログテーマ開発(2)
はてなブログテーマ開発(3)
はてなブログテーマ開発(4)
はてなブログテーマ開発(5)
01まずはデモ画像
細かいことは未調整ですし、フォントサイズなどはこれからです。
デバイスの表示幅 768px(iPad)以上のタブレット、デスクトップです。
デバイスの表示幅 767px 以下のタブレット、スマートフォンです。
02テーマのポイント
ブログはやっぱり記事ですから、記事ページからです。
このテーマのポイントは
- 記事タイトルを #top-editarea に移動してページを開いた時にまず目がいくようにする
- 背景画像を横幅全幅かつ記事の背景に広がるように張り、印象強くする
- サイドバーに作成したオリジナルメニューを #blog-title に移動する
- スマートフォンではメニューをアイコンタッチのスライドメニューとする
- 投稿日時とカテゴリーの装飾にちょっとカッコつけてみる(笑)
03背景画像
前回の「はてなブログテーマ開発(5)ブログタイトル、記事タイトルの装飾」では背景画像を #blog-title に張りましたが、それですと当然そのブロック内だけになります。
上のデモ画像では、画像を #container に張って記事全体の背景に配置しています。ただ、レスポンシブでテーマを作る場合、1枚の画像で画像のサイズや位置関係を守りつつすべてのデバイスに対応させるのはかなり難しいです。
特に、デモ画像のように、人物を中央に持ってきつつそのサイズをバランスよく配置するのは至難の業です。元画像のサイズをどうするかにもよりますので、それぞれの画像に応じて手探りで調整するか、複数枚用意して CSS で変更するかだと思います。決定版のいい方法があれば私も知りたいです。
今回は次のように調整しています。
- 元画像は横幅 1920px 以上は必要かと思います
- ブレイクポイントにしている 768px で、横 100% にして人物サイズがベストになるよう画像を作成する
- ブレイクポイント以下では人物が小さくなるので、デバイス幅に応じて画像を拡大する
- ブレイクポイント以上では人物の位置が下がるので、デバイス幅に応じて配置位置をあげる
現在のところ、次の方法をとっています。それにしても、calc() 関数が使えると自由度が格段に上がります。
#container { background-image: url( 画像URL ); background-size: calc(100vw + (768px - 100vw)); background-repeat: no-repeat; background-position-x: center; @media #{$mq-bp} { background-size: contain; background-position-y: calc(( 768px - 100vw) * .12); } }
04記事タイトルを #top-editarea に移動
このブログも記事タイトルを記事と切り離して上部に取り出しているように見えますが、このブログは1カラムですのでタイトルの位置を上にずらしているだけです。2カラムの場合は、上にずらしても表示幅を広げることが面倒(できなくはない)ですので、いっそのこと要素ごと移動してしまえということです。
カスタマイズ > ヘッダ > タイトル下 に div を入れておきます。これは #blog-title-inner
や #content
と同じ幅やマージンを設定するためです。
<div id="top-editarea-inner"></div>
/* タイトル下HTML */ #top-editarea { padding: 0 calc((100vw - #{$min-width}) * 0.1 + 13px); @media #{$mq-bp} { padding: 0 calc((100vw - #{$break-point}) * 0.1 + 13px); } } #top-editarea-inner { display: flex; align-items: center; max-width: $content-width; margin: 0 auto; min-height: 300px; justify-content: center; @media #{$mq-bp} { max-width: $max-width; min-height: 400px; } } /* タイトル下HTMLここまで */
カスタマイズ > フッタ に次のスクリプトを入れます。
<script> (function(){ // 記事ページなら if(document.body.classList.contains('page-entry')){ var header = document.getElementsByClassName('entry-header')[0]; document.getElementById('top-editarea-inner').appendChild(header); } }()); </script>
これで記事タイトルが #top-editarea に移動されますので、後は自由にデザインするだけです。日付とカテゴリーの配置は、前回「はてなブログテーマ開発(5)ブログタイトル、記事タイトルの装飾」でやった通りです。
05投稿日時の日付表示を曜日付きに変更
はてなブログの投稿日時の HTML ソースは次のようになっています。
<time pubdate datetime="2018-07-21T12:29:15Z" title="2018-07-21T12:29:15Z"> <span class="date-year">2018</span><span class="hyphen">-</span><span class="date-month">07</span><span class="hyphen">-</span><span class="date-day">21</span> </time>
time タグの datetime 属性が UTC のデータを持っていますので、これを取り出して Date オブジェクトにすればいろいろな形式で表示できそうです。
Date.prototype.toLocaleDateString() – JavaScript | MDN
<script> (function(){ // 記事ページなら if(document.body.classList.contains('page-entry')){ var header = document.getElementsByClassName('entry-header')[0]; document.getElementById('top-editarea-inner').appendChild(header); var time =header.getElementsByTagName('time')[0]; var dt = new Date(time.getAttribute('datetime')); var options = { weekday: "long", year: "numeric", month: "short", day: "numeric" }; time.innerHTML = '<span class="published">Published on ' + dt.toLocaleDateString("en-us", options) + '.</span>'; } }()); </script>
デモ画像では、米国表記で出力しています。ロケールを ja-jp
に変えれば 2018年7月21日土曜日
の日本語表記、オプションを weekday: "short"
に変えれば 2018年7月21日(土)
になります。時間まで表記したい場合は、toLocaleTimeString
メソッドを使います。
Date.prototype.toLocaleTimeString() – JavaScript | MDN
06サイドバーにオリジナルメニューを作成し #blog-title に移動
カスタマイズ > サイドバー に HTML モジュールを追加し、メニューを作ります。カテゴリをメニューにしてもいいのですが、今回はそれぞれのメニューに固定ページを当てようかと考えています。
<div class="offcanvasmenu">MENU</div> <div class="menulist"> <ul> <li><a href="#">メニュー1</a></li> <li><a href="#">メニュー2</a></li> <li><a href="#">メニュー2</a></li> <li><a href="#">メニュー2</a></li> </ul> </div>
とりあえずはダミーのメニューです。
(9/7)Javascriptを書き忘れていました。オリジナルメニューはサイドバーの一番上に移動しておきます。
<script> (function(){ // サイドバーの要素をブログタイトルボックスに移動する var sideElements = document.getElementById('box2-inner').children; document.getElementById('blog-title-content').appendChild(sideElements[0]); // 記事ページなら if(document.body.classList.contains('page-entry')){ (略、上記と同じ) } }()); </script>
(9/9)追加ここまで
.offcanvasmenu { display: block; @media #{$mq-bp} { display: none; } } .menulist { display: none; @media #{$mq-bp} { display: block; } li { list-style: none; @media #{$mq-bp} { display: inline; a { padding: 5px 10px; font-weight: 700; text-decoration: none; } } } }
こちらもとりあえずの CSS です。
これでデモ画像のようなテーマになります。
テーマ作るよりも記事にするのが大変…。