3カラムのフロントエンドの話

Shunsuke Sawada

このブログのデザインを変えたのですが、
作業したフロントの内容を小さくわけて残しておこうかと。

2年ぶりにブログのデザインを変更 | Workabroad.jp

ワイヤーフレーム

Screen Shot 2016-01-04 at 1.50.34 AM
Sketchで何となく作った後にコーディング開始しました。
コーディングの段階でこっちの方がいいなと思ったら随時変えているので、正確に同じというわけではないです。

Flexbox

3カラムなんですがFlexboxです。float: left はほとんど使っていません。
Flexboxについてはこのリンクが凄いわかりやすいです。
A Complete Guide to Flexbox | CSS-Tricks

ブラウザによって記述が違ったりして分かりにくいので、Bourbon - A Lightweight Sass Tool Set を使って、気を使わなくてもいいようにしています。

シンプルにするとこんな感じです。

iOSでのposition:fixed問題

フッター中の内容はコンテンツの下に隠れていて、
最後までスクロールしたら現れるというのをやってみました。

フッターは普通に配置してスペースを確保。
フッターの中身を position: fixed で固定します。コンテンツの z-index をフッターより高くしておけばフッターが隠れて上手くいくだろうと思っていたのですが、iOSで思わぬ現象がおきました。

こんな感じで思いっきり上に出てきてしまっています。
Photo 3-01-2016 9 37 47 pm
このリンク先 をiOSで見て、Fullscreenをクリックすると再現できると思います。

  
AndroidやMacのChromeではまったく問題ないので悩みましたが
translate3d(0,0,0) で解決する模様。
css - While scrolling on an iOS device, the z-index of elements isn't working - Stack Overflow

ただ、これによって新たな問題が。。
デスクトップ版の右サイドバーにAmazonの関連書籍を出していて、これに Bootstrap Affix ぽいものを使っています。実際にはライブラリは使っておらず自分で書いたJavascriptですがまぁ同じようなものです。
ユーザーがスクロールダウンするにあたって、サイドバーが空っぽになってしまうのを防ぐため、サイドバーのコンテンツに position: fixed を動的に充てるというもの。

ただ、前述の translate3d によって問題がおきます。
translate3d が与えられたエレメントの子孫は、その親を基準にしてしまうということ。通常ならウィンドウに固定されるはずのエレメントが position: absolute のような振る舞いをします。

こんな感じです。

仕方がないので media query を使ってモバイルの時だけ translate3d があたるようにしました。

追記

上記でうまくいくと思っていたけど、Andoroidのはてブappで見ると、また上に被ってた…。
Desktop / Android / iOS / アプリ内ブラウザ と考えなければいけない環境が増えたのでCSSはちょっと諦めて、モバイルの時は 「最初非表示、フッターにたどり着いたらJavascriptで表示と」 という具合に逃げました。
あらためて知るモバイルの position: fixed 問題。恐るべし…。

Affix

前述のAffixの説明も少し。

こんな感じの時に position: fixed にしたい。
fixedだからどんなにスクロールしようがウィンドウの上部か下部に固定です。
affix01
  
そしてこんな感じの時に position: absolute にしたい。
absoluteで親要素の下部に固定します。これでスクロールに応じて動いてくれます。
affix02

  
Javascriptはこんなの。

coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$inner = $('.child.right .inner')
bottom = $inner.offset().top + $inner.outerHeight()

$(window).on 'scroll', ->

  if $(window).scrollTop() + $(window).height() > $('.footer').offset().top
    $inner.removeClass('affix')
    $inner.addClass('affix-bottom')
  else if $(window).scrollTop() + $(window).height() > bottom
    $inner.removeClass('affix-bottom')
    $inner.addClass('affix')
  else
    $inner.removeClass('affix')
    $inner.removeClass('affix-bottom')

  
デモです。HTML/CSSとかはこちらで確認できます。
最後までスクロールすると何を言っているのか分かると思います。

  
以上かな。
Flexbox、iOSのz-index問題、Affixでだいたいこのサイトが出来上がってます :)
それではー。

Shunsuke Sawada

おすすめの記事

Wordpressのアップロード作業を楽にする
acomoo CSVインポート機能を追加しました。
ツッコまれピッチに行ってきた 東京 下克上編