jQuery

jQueryで 可変式な要素を縦に中央揃えにするやり方で タイトルをアイキャッチの真ん中に配置してみた

記事ページのアイキャッチやらタイトルやらの配置などなど変えました! 見づらさバツグンだったので。

新しい配置はどうでしょうか? 敢えて前までのデザインは見せません。残さないことにします。

※(2013/05/21追記)高さが都度変動がある要素の場合、今回の記事が有用ですが、もし親要素の高さが決まっている場合は CSSだけで対応できます。詳細は新しく記事を書きました! CSSでテキストを指定要素へ縦中央揃えにする(複数行対応版) | LogicA ので参照願います。
また、サンプルのテキストボックスの表示がおかしかったので修正しました。修正前にご覧頂いた方々ごめんなさい m(__)m

高さが変動する要素をピッタリ真ん中にしたい

ということで、このブログのタイトルです。タイトルは最近はがんばってロングテール的なものを考慮して、少し長めにしてました。
ですが、長くするとハミ出します。もしくは2列や3列になります。今までのデザインだとぐちゃぐちゃになります。なのでやめました。

変動しない要素、つまり 高さが決まっていたり、列が決まっているインライン要素などであれば、HTMLとCSSで調整して簡単に縦で真ん中に揃えられるんです。

参考サイト to-Rさん

参考になります!基本はココで紹介されているやり方がベースになってます。
けど、タイトル(ウチはh2です)のようなブロック要素で都度 高さの値(列数)が変動すると真ん中からズレてしまいます。カッコ悪いのでなんとかしてみようとして何とかしてみました。

サンプルです

ほげほげホゲホゲhogehogeHOGEHOGE

青い部分がアイキャッチエリアになります。
白い帯が 今回のキモ。タイトルエリアになります。白帯の中の赤字がタイトルになります。
今回はわかりやすいように、青いアイキャッチエリアの縦ど真ん中に線を入れています。

下のテキストボックスに入れた文字がそのままタイトルに入ります。適当に長文になるように入れてみてください。(出来れば全角日本語で)
列が増える度に高さが変わり、白帯エリアが高くなりますが、真ん中からズレません。やりました!

コードです

まずはHTMLです。

[html]

<div id="flame"> <!– アイキャッチのエリア –>

<h2 class="wordBreak">ほげほげホゲホゲhogehogeHOGEHOGE</h2> <!– タイトル –>

<div id="picture"></div> <!– アイキャッチの画像 –>

</div>

<form>
<div id="textZone">
<label>
<p>ここに文字を入力するとタイトルが変わります</p>
<input type="text" id="inputText"> <!– タイトル入力エリア –>
</label>
</div>
</form>

[/html]

jQueryはこんな感じです。

[javascript]

jQuery(document).ready(function(){

var h2Getter = function(){
// タイトルの位置やプロパティの取得、変更

var h2Height = jQuery("#flame h2").innerHeight() / 2;
// タイトルの高さ(パディング含む)を取得 ÷2
var conHeight = jQuery("#flame").innerHeight() / 2;
// コンテンツの高さ(パディング含む)を取得 ÷2
h2Position = (conHeight – h2Height) + "px";
// コンテンツの中心位置と タイトルの中心位置を合わせるときの topからの距離

var h2Width = jQuery("#flame").innerWidth();
// コンテンツの幅(パディング含む)を取得

var h2PaddingL = jQuery("#flame h2").css("paddingLeft");
// 左のパディング(px付)を取得
h2PaddingL = h2PaddingL.replace(‘px’,”);
// "px" を削除
h2PaddingL = eval(h2PaddingL);
// 文字列から数値へ変換

var h2PaddingR = jQuery("#flame h2").css("paddingRight");
// 右のパディング(px付)を取得
h2PaddingR = h2PaddingR.replace(‘px’,”);
// "px" を削除
h2PaddingR = eval(h2PaddingR);
// 文字列から数値へ変換

var h2Padding = h2PaddingL + h2PaddingR;
// 左右のパディングの値を取得

h2Width = h2Width – h2Padding + "px";
// タイトル部分のwidthを指定(パディング込みでコンテンツの100%)

jQuery("#flame h2").css({"top":h2Position, "width":h2Width});
// タイトルの位置をh2Positionで縦中央に、横幅を枠内に収める
}

h2Getter();
// 読み込み時に実行する

jQuery("input").bind(‘click blur keydown keyup keypress change resize’,function(){
// 入力エリアに何かしら動きがあれば作動

var inputText = jQuery("#inputText");
// テキストボックス
var h2Text = jQuery("#flame h2");
// タイトル
var counter = inputText.val().length;
// テキストに入力された文字数

if (counter > 0){  // 文字入力されている場合
h2Text.text(inputText.val());
// タイトルの文字をテキストボックスの入力と入れ替える
h2Getter();
// 再度、タイトルの位置調整
}
else {  // 文字入力させていない場合
h2Text.text("ほげほげホゲホゲhogehogeHOGEHOGE");
// タイトルをデフォルト文字に戻す
h2Getter();
// 再度、タイトルの位置調整
}
return(h2Text);
// 値を返す
});

});

[/javascript]

ちなみにCSSはこんな感じにしてます。

[css]

// アイキャッチエリア
#flame {
max-width: 596px;
height: 400px;
background-color: blue;
margin: 100px auto;
position: relative;
padding: 0px;
}
// タイトル(白帯)エリア
#flame h2 {
padding: 15px 30px;
background-color: #fff;
filter: alpha(opacity=60);
background-color: rgba(255, 255, 255, 0.4);
color: red;
line-height: 1.4em;
position: absolute;
margin: 0;
font-size: 24px;
white-space: normal;
word-break: break-all;
}
// 本来は画像が入るエリアですが、今回は中央の白い線として使用してます
#picture {
width: 596px;
height: 199px;
border-bottom: 1px solid #fff;
}
// 入力フォームのエリア
#textZone {
width: 300px;
margin: -50px auto 0;
text-align: center;
white-space: nowrap;
}

[/css]

jQueryのコードの説明します

真ん中にオフセットさせる

VarticalMiddle

まず、アイキャッチエリアの高さを取得

タイトル(h2)のエリアの高さ(height)を取得

差分の値(中心からコンテンツの50%を上げたポイント)を取得

幅を常にアイキャッチエリアと同じにする

AlignCenter

ついでに、タイトルの幅は パディングで内側に設けた余白部分も含めてになります。パディングが後から変動されても対応できるように、コードを追記しています。

まずはアイキャッチの幅(width)を取得

左右のパディングの値を取得(数値化)

差分の値がタイトル(h2)のwidthの値

タイトルの位置を調整する

取得した 縦の中央揃えの値と、パディング抜きしたwidthの値を指定して完了です。

※ 入力フォームの箇所は今回は端折ります。でも、入力がリアルタイムで反映するようにしたり ちょっと工夫はしましたw

CSSでの注意点

今回はタイトルの文章が右端で折り返してくれない状態に一度陥りました。全角なら white-space: normal で回避できるんですが、半角英数字だと突き抜けます。貫通します。

半角英数字用のCSSで、 word-break: break-all というものを使ってみたところ、ChromeやIEでは上手いこと行きました。ですが、Firefox Opera あたりはダメでした。(2012.4.26 最新版)

まあ、今回のケースでは自ブログのタイトルに使うところなので、調子こいて半角英数字のタイトルにしなければいいだけなので まあいいです。
また解決策が見つかったら試してみて、良ければご報告します。