Simplicityを少し改造してみた part17-2 あのフリップでスペースの有効活用ふたたび・レスポンシブ対応編

前回フリップでスペースの有効活用を実現するにあたって、記事部分がフリップする機構を作りました。

Simplicityを少し改造してみた part17 あのフリップでスペースの有効活用ふたたび
ネタが無いとかそういうんじゃないんですよ。 ネタがないのなんかはいつものことです。ただ、今ならもう少し何とかできそうな気が…そう、気がした...

この時に、サンプルをご覧になられた方は、なんでメインの記事部分に赤いボーダーが入ってるんだ?と気づかれたかも知れません。実はこれ、今回のための伏線だったのです(笑)

そんな大層なものではありませんが、説明したかったこととして、次のようなことがあります。

親要素をposition: relativeで設定したブロックの中にある、子要素のposition: absoluteは親要素を押し広げるか?

はい、またよくわかんないことを書きました。つまり、これは以前書いた、

Simplicityを少し改造してみた 番外編 part21 jQueryとJavascript関数を併用する
もうね、jQueryだけならまだしも「JavaScriptと言う言葉を聞くだけで拒絶反応を起こす」と言うのはとても良くわかります。なんせJa...

この記事と同じような感じですが、今回のはもう少し凶悪です。

floatの場合は、浮いている子要素自体が高さを持たなかったために、前後にclearfixを入れることで高さを持たせて親要素を押し広げると言うのが可能でした。が、今回のものはそれが不可能です。

簡単な例としては以下のような感じです。

親要素の赤線は、widthを持っていますが、高さを持っていません。一方子要素はwidthもheightも持っていますが親要素を押し広げません。これは何故か?
ここにはposition: absoluteが絶対位置への配置と言う理由があります。絶対位置とは何か、上記例で言うと、親要素の座標内に配置すると言う意味合いでしょうか。position: relativeというのが「全体的の」position: absoluteが「個別の」と言う風に考えるのが良いかも知れません。

以下の例のようにするとわかりやすいかも知れません。

親要素に高さを持たせて、はみ出た分を非表示にしています。
親要素のブロックの左上を0,0とした原点と考えた時に、その中の子要素は0,0の親要素の原点から任意の位置に表示されるという事になるわけです。親要素はドキュメントに対して全体的に位置していて、子要素はその中の親要素に対して個別に位置していると言う具合になります。子要素がposition: relativeであれば、親要素を押し広げるわけですが、position: absoluteであると親要素を押し広げません。

つまり、前回のフリップさせている親要素の.flipperはposition: relativeで、その子要素である.front、.backはposition: absoluteであったわけです。

さて、こうなると何が問題かと言いますと、つまり、サイドバーの位置がおかしくなると言うことになります。
通常Simplicityでは、#body-inの中に#mainがfloat: leftで入っており、#sidebarはfloat: rightで入っています。前回のフリップでは、#mainに.frontと言うクラスを入れて、更にその下に.backと言うブロックを作り、.frontと.backを.flipperと言うクラスで囲んでいます。

ここから、Simplicityの通常の構成の#mainにあたる部分は.flipperと変わっているということです。

こういう構造です。本来#body-inの中にある、#mainと#sidebarの構成から、#mainが.flipperに変わったというのが理解して頂けると思います。

.flipper は position: relative;
.front、.back は position: absolute;

こうなっています。冒頭でサンプル提示した関係と同じです。.front、.backがposition: absoluteで無ければならない理由としては、同じ位置で回転させるからです。位置合わせのために.flipperの親要素の中にposition: absoluteで各子要素が入っています。

では、どのようにして親要素に高さを持たせるか

もし、.frontと.backが同じ高さなら、色々考慮する必要もなく、.frontの高さをjQuery等で調べるか設計段階から高さを決めておいてそれを.flipperに入れれば良いだけの話です。しかし、相手は本文記事部分と、関連記事の部分ですから、高さが異なります。また今表示しているのは、.frontなのか、.backなのかがわからないと、高さを調べることはできません。

これらを考えた時に、以下のようなスクリプトを入れました。

もし$.flipperが.frontfaceと言うクラスを持っていたらと言う条件で、背面か全面かの高さを調べて.flipperに高さを入れるようにしています。

.frontfaceと言うクラスは名前をつけ間違えましたが、つまりは.frontをクリックした時に.flipperに付与しています。で.backをクリックした時は外すということをしているわけです。最初はどちらもついていないので、.frontの高さが入ります。クリックして背面になった場合は、背面の高さを.flipperに入れることになります。

しかしこれだけでは更なる問題が出てきます。リサイズです。

画面の幅が狭くなれば中の記事はたくさん折り返されることになります。そうすれば高さが増えていきます。広くなれば.flipperの最大幅までは文章等が横に長くなるので高さが元に戻っていきます。

これらを実現するにあたって、jQueryだけでもできますが、より便利にということで、前回紹介した以下のブログカードの記事の方法を流用して、リサイズの時用の処理を書いています。

Simplicityを少し改造してみた 番外編 part21 jQueryとJavascript関数を併用する
もうね、jQueryだけならまだしも「JavaScriptと言う言葉を聞くだけで拒絶反応を起こす」と言うのはとても良くわかります。なんせJa...

はい、内容は同じです。同じですが、リサイズした時にその時々の高さを得られます。常に計算すると処理が重くなるので、前回のjavascriptの処理で「リサイズが終わった時にだけ処理」をさせているというわけです。
リサイズがない場合は、クリックした時(フリップした時)に.front、.backいずれかのサイズがわかればよいだけですが、リサイズした時にはその時々の面がどちらかを調べて高さを入れる必要があります。
クリックか、リサイズかの違いだけなので処理自体は同じことをしています。

としても良いかと思います。

これらの処理にてそれぞれの面の高さを.flipperに持たせることができたので、.flipperのcssにfloat: left;を入れれば、サイドバーと.flipperは、Simplicity通常の#mainと#sidebarと同じ関係になります。
これでリサイズに対応できたかと思います。

番外編

リサイズとは関係ないですが、これら一連の内容を応用して、ブログカードをフリップさせてみました。

See the Pen ブログカードをフリップさせる by Hidekichi (@Hidekichi) on CodePen.

デザインはアレですけどね、ここらは好きなようにできますので、何かしらの参考までに。

スポンサーリンク

シェアする

フォローする