Monday, 14 October 2013

jQueryのhoverで文字色をふんわり変える効果をつけると、ページ読込完了後の最初のマウスホバーでふんわり変わらない件と代替方法

今までのウェブ制作で、jQueryのhoverを使って文字色をふんわり変える効果をつけていたところ、どうもページ読込完了後の最初のマウスホバーでふんわり変わらないことに気付いた。これはjQueryのhover内の始めのfunction(マウスホバー時の関数に当たる)でアニメーション時間を遅くした時に出くわしたもので、それ以後ひじょ〜に気になって仕方が無いのでその解消方法を探してみたら、CSS3を使えば良さそうだということがわかったので以下にチョットだけ解説を。

1. jQueryのhoverで文字色をふんわり変える

コードはいつもこんな感じのものを使っている。
$(function(){
 $("a").hover(
  function () {
   $(this).stop().animate({color: "任意の色A"}, 500);
  },
  function() {
   $(this).stop().animate({color: "任意の色B" }, 500);
  }
 );
});
jQueryのhoverは、対応ブラウザが多いのだが、ページ読込完了後の最初のマウスホバーではアニメーションが効かないようだ。この現象は、特に、CSSにもa:hoverを同時に指定している場合に起こる現象のようだ。

対応策としては、CSSのa:hoverでの指定はしないことで、アニメーションが効かない現象は解消されるが、これだとjQueryが読込めない時にa:hoverが出来なくなる、という欠点がある。

2. CSS3のtransitionで文字色をふんわり変える

通常のリンク色とマウスホバー時の色指定はこんな感じ。
a {color: 任意の色A;}
a:hover {color: 任意の色B;}
CSS3のtransitionの対応ブラウザは、IEがver10のみで、他のブラウザもベンダープレフィックスでの対応となっている。
しかし1.と違い、ページ読込み完了時の最初のマウスホバーでも効く。
なぜなら、CSSのa:hoverはそのままで、aに
a {
color: #000;
-webkit-transition: 0.5s;
-moz-transition: 0.5s;
-o-transition: 0.5s;
-ms-transition: 0.5s;
transition: 0.5s;
}
a:hover {color: Tomato;}
と赤字部分を追記すれば良いだけなので。
また、transitionに対応していないブラウザでも、1.と違ってa:hoverが出来なくなるということはない。

今後は、古いIEに対応する必要がない場合はCSS3を使うの方が良いかな。

Monday, 17 June 2013

jQueryでline-height値を取得する時、IEだけ返り値が違う

とあるCSSで
body {
    font-size: 12px;
    line-height: 2;
}
と指定し、jQueryにてline-heightの値を取得する時、
var lineHeight = parseFloat($("body").css("line-height"));
とすると、通常「24」と、font-size*line-heightが内部計算された数値が返される(parseFloatは文字列を数値に変換する関数。parseFloat関数なしだと「24px」と単位付きの文字列が返される)。しかし、IEではCSSでline-heightに指定した値「2」がそのまま返されて他のブラウザと異なる結果となり非常に困る。それ故ブラウザ判別のスクリプトが必要になる(ホンマにメンドイ)。

var userAgent = window.navigator.userAgent.toLowerCase();
var appVersion = window.navigator.appVersion.toLowerCase();
   
if (userAgent.indexOf('msie') != -1) {
    if (appVersion.indexOf('msie 6.') != -1) { //ie6のとき
        var getStyle = $("body")[0].currentStyle || document.defaultView.getComputedStyle($("body")[0], '');
        var lineHeight = getStyle.lineHeight*parseFloat($("body").css("font-size"));
        var bHeight = Math.round(lineHeight)
    } else if (appVersion.indexOf('msie 7.') != -1) {//ie7のとき
        var getStyle = $("body")[0].currentStyle || document.defaultView.getComputedStyle($("body")[0], '');
        var lineHeight = getStyle.lineHeight*parseFloat($("body").css("font-size"));
        var bHeight = Math.round(lineHeight)
    } else if (appVersion.indexOf('msie 8.') != -1) {//ie8のとき
        var getStyle = $("body")[0].currentStyle || document.defaultView.getComputedStyle($("body")[0], '');
        var lineHeight = getStyle.lineHeight*parseFloat($("body").css("font-size"));
        var bHeight = Math.round(lineHeight);
    } else if (appVersion.indexOf('msie 9.') != -1) {//ie9のとき
        var lineHeight = parseFloat($("body").css("line-height"))*parseFloat($("body").css("font-size"));
        var bHeight = Math.round(lineHeight);
    } else if (appVersion.indexOf('msie 10.') != -1) {//ie10のとき
        var lineHeight = parseFloat($("body").css("line-height"))*parseFloat($("body").css("font-size"));
        var bHeight = Math.round(lineHeight);
    }
}else{//ie以外
    var lineHeight = parseFloat($("body").css("line-height"));
    var bHeight = Math.round(lineHeight);
}

これで、IEでも期待する値「24」が返ってくる、はず。

上記スクリプトは、JavaScriptでUserAgentによるブラウザ判定「if.useragent.js」v0.9 | みやなび | 宮古島 ホームページ制作 広告代理店より拝借した。深謝。
ie6〜8のとき変数getStyleがあるのは、jQuery を利用して1行の高さ(line-heigt)を取得する: JavaScriptメモを参考にした。深謝。

最終的なline-heightの値は、Math.round関数にて小数点以下四捨五入で丸めてある。

Wednesday, 12 June 2013

上下に展開・格納する縦型メニューjQueryの簡略化に成功

現在拙サイト・ブログ等で使用中の「上下に展開・格納する縦型メニューjQuery」はかなり煩雑で、今回整理して簡略化させることに成功。

縦型メニューのHTML


<ul>
 <li>
  <span id="accordion01" class="accordion">news</span>
  (ここに「+」または「−」が挿入される)
  <ul id="subNavi01" class="subNavi">
   <li><a href="#">ESZETT</a></li>
   <li><a href="#">TYPŒ</a></li>
   <li><a href="#">LETTER-PRESS</a></li>
  </ul>
 </li>
 <li>
  <span id="accordion02" class="accordion">works</span>
  (ここに「+」または「−」が挿入される)
  <ul id="subNavi02" class="subNavi">
   <li><a href="#">web design</a></li>
   <li><a href="#">web demo</a></li>
   <li><a href="#">print</a></li>
  </ul>
 </li>
 <li>
  <span id="accordion03" class="accordion">projects</span>
  (ここに「+」または「−」が挿入される)
  <ul id="subNavi03" class="subNavi">
   <li><a href="#">event calendar</a></li>
   <li><a href="#">letterpress map</a></li>
   <li><a href="#">line museum</a></li>
  </ul>
 </li>
 <li>
  <span id="accordion04" class="accordion">bibliography</span>
  (ここに「+」または「−」が挿入される)
  <ul id="subNavi04" class="subNavi">
   <li><a href="#">basic</a></li>
   <li><a href="#">typography</a></li>
   <li><a href="#">letterform</a></li>
  </ul>
 </li>
</ul>

これまでのjQuery


$(function(){
 $("#subNavi01, #subNavi02, #subNavi03, #subNavi04").hide();
 $("#accordion01, #accordion02, #accordion03, #accordion04").after("<span class='openClose'>+</span>");
 $("#accordion01").click(function(){
  $("#subNavi01:not(:animated)").animate({height: 'show'}, 500,'easeOutQuad');
  $("#accordion01").next().replaceWith("<span class='openClose'>–</span>");
  $("#subNavi01:not(:animated)").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion01").next().replaceWith("<span class='openClose'>+</span>");});
  $("#subNavi02").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion02").next().replaceWith("<span class='openClose'>+</span>");});
  $("#subNavi03").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion03").next().replaceWith("<span class='openClose'>+</span>");});
  $("#subNavi04").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion04").next().replaceWith("<span class='openClose'>+</span>");});
 });
 $("#accordion02").click(function(){
  $("#subNavi02:not(:animated)").animate({height: 'show'}, 500,'easeOutQuad');
  $("#accordion02").next().replaceWith("<span class='openClose'>–</span>");
  $("#subNavi02:not(:animated)").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion02").next().replaceWith("<span class='openClose'>+</span>");});
  $("#subNavi01").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion01").next().replaceWith("<span class='openClose'>+</span>");});
  $("#subNavi03").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion03").next().replaceWith("<span class='openClose'>+</span>");});
  $("#subNavi04").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion04").next().replaceWith("<span class='openClose'>+</span>");});
 });
 $("#accordion03").click(function(){
  $("#subNavi03:not(:animated)").animate({height: 'show'}, 500,'easeOutQuad');
  $("#accordion03").next().replaceWith("<span class='openClose'>–</span>");
  $("#subNavi03:not(:animated)").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion03").next().replaceWith("<span class='openClose'>+</span>");});
  $("#subNavi01").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion01").next().replaceWith("<span class='openClose'>+</span>");});
  $("#subNavi02").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion02").next().replaceWith("<span class='openClose'>+</span>");});
  $("#subNavi04").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion04").next().replaceWith("<span class='openClose'>+</span>");});
 });
 $("#accordion04").click(function(){
  $("#subNavi04:not(:animated)").animate({height: 'show'}, 500,'easeOutQuad');
  $("#accordion04").next().replaceWith("<span class='openClose'>–</span>");
  $("#subNavi04:not(:animated)").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion04").next().replaceWith("<span class='openClose'>+</span>");});
  $("#subNavi01").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion01").next().replaceWith("<span class='openClose'>+</span>");});
  $("#subNavi02").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion02").next().replaceWith("<span class='openClose'>+</span>");});
  $("#subNavi03").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion03").next().replaceWith("<span class='openClose'>+</span>");});
 });
});
うん、ものの見事に煩雑だね〜。ここではもう詳しく解説しないが、ただ1つだけ云えば、ID属性で各ナビごとに一々指示しているから。詳細は、拙ブログ上下に展開・格納するナビおよび縦型メニュー展開・収納時(開閉時)にメニュー横の+−表示が切替るjQueryをご覧あれ。

整理した結果


1.$(function(){
2. $(".subNavi").hide();
3. $(".accordion").after("<span class='openClose'>+</span>");
4. $(".accordion").click(function(){
5.  $(this).next().next().animate({height: 'show'}, 500,'easeOutQuad');
6.  $(this).next().replaceWith("<span class='openClose'>–</span>");
7.  $(".accordion").next().next().not(":animated").animate({height: 'hide'}, 500,'easeInQuad',↵
   function(){$(this).prev().replaceWith("<span class='openClose'>+</span>");});
8. });
9.});
あらまあスッキリ。
要は、クラス属性での指定に替えて汎用性を高めたことだね。
解説すると、
  • 2行目:subNaviクラスを持つUL要素で囲んだ箇所は最初見えないようにする。これはCSSにて「.subNavi {display:none;}」を指定した方が良い。ページロード時にsubNavi部分が1度表示されてから消えるという動作が解消されるから。
  • 3行目:accordionクラスを持つSPAN要素の後ろにSPAN要素の兄弟要素として「+」を追加する(詳細は縦型メニュー展開・収納時(開閉時)にメニュー横の+−表示が切替るjQueryをご覧あれ)。
  • 4行目:accordionクラスを持つSPAN要素の1つをクリックすると、
    • 5行目:このときの$(this)は実際にクリックしたaccordionクラスを持つSPAN要素を指し、それのnext().next()、つまり$(this)の次の次の兄弟要素であるsubNaviクラスを持つUL要素で囲んだ箇所が表示される。この時注意したいのは、クリックされたaccordionクラスを持つSPAN要素の次の兄弟要素は3行目で追加されるafter()内のSPAN要素であるということ。なのでsubNaviクラスを持つUL要素は次の次の兄弟要素となる。
    • 6行目:クリックされたaccordionクラスを持つSPAN要素の次の兄弟要素である、after()で追加したSPAN要素を「−」に置き換える。
    • 7行目:accordionクラスを持つSPAN要素の次の次の兄弟要素であるsubNaviクラスを持つUL要素で囲んだ箇所を格納する。ここで注意。セレクターが$(this)ではなく$(".accordion")なのは、クリックされたaccordionクラスだけでなく全てのaccordionクラスを対象にしているから。この縦型メニューは、どこか1箇所が展開されたら他の全てのsubNaviは格納するようにしているので。
    • 7行目:後半の関数では$(this).prev()と指示しているがこれは何を指しているか。この時の$(this)は7行目前半の$(".accordion").next().next()、つまりはsubNaviクラスを持つUL要素を指していて、それのprev()、つまりその前の兄弟要素であるafter()で追加したSPAN要素を指す。で、この内「−」に差替えられたものを「+」に変更する。
以上だが、click関数内に1度に展開・格納の指示が入っているので、この動作は展開したかと思えばすぐ格納されて結局subNaviクラス部分は表示されないのではないかと思うが、ここでのミソは、7行目にあるnot(":animated")。これをここに入れることによって、1回のクリックでクリックされたaccordionクラス内のsubNaviクラスはanimateしながら展開され、もう一度自身を含めたいずれかのaccordionクラスをクリックすると、クリックされたaccordionクラス内のsubNaviクラスはanimateしながら展開されると同時に、すでに展開しているsubNaviクラスはanimate状態ではないのでこれが7行目の指示のにより格納される、という動作になる。

Monday, 3 June 2013

縦型メニュー展開・収納時(開閉時)にメニュー横の+−表示が切替るjQuery

今回の拙サイト全面改修の際追加したメニュー横の+−表示が切替るjQueryの詳説をば。
実際どのようなものかは、この拙ブログのサイドメニューも同じ仕様なのでご覧あれ。

メニュー右に「+」を追加して、メニュー展開時にこれが「−」に変わり、メニュー収納時にまた「+」になるようなメニュー展開・収納jQuery。この「+」「−」はいわば飾りなのでHTML上には書きたくない、しかしjQueryの特性上、CSSの疑似要素〔:after〕をセレクターとして呼べないこともあって、「+」「−」の切替え方に難儀。当初、〔toggle(fn1, fn2, ..., fnN)〕を使用しようと考えたがjQuery 1.9からこれが廃止されたことを知り愕然。(詳細はjQuery Core 1.9 Upgrade Guide | jQueryを参照)
他に手はないかと色々調べた結果、jQueryの〔after()〕と〔replaceWith()〕が使えそうと判断。〔after()〕は指定したセレクターの後ろにHTML文字列などを挿入するもの、〔replaceWith()〕は指定したセレクターのHTML文字列などを置換するもの。この2つを組み合わせて「+」「−」の切替えを可能にした。
以下に使用例を。
HTML
<ul>
 <li><span id="accordion02">works</span>
  <ul id="subNavi02">
   <li><a href="#">web design</a></li>
   <li><a href="#">web demo</a></li>
   <li><a href="#">print</a></li>
   <li><a href="#">letter carving</a></li>
  </ul>
 </li>
</ul>

jQuery
$(function(){
1:  $("#subNavi02").hide();
2:  $("#accordion02").after("+");
3:  $("#accordion02").click(function(){
4:  $("#subNavi02:not(:animated)").animate({height: 'show'}, 500,'easeOutQuad');
5:  $("#accordion02").next().replaceWith("–");
6:  $("#subNavi02:not(:animated)").animate({height: 'hide'}, 500,'easeInQuad', function(){$("#accordion02").next().replaceWith("+");});
 });
});
解説
  • 1: はじめはサブナビ部分を隠しておくための〔hide()〕
  • 2:「works」の右に「+」を追加するための〔after("+")〕
  • 3,4,5:「works」をクリックすると(3)、サブナビ部分が展開(4)、同時に「+」が「−」に置換される(5)
  • 6: もう一度「works」をクリックするとサブナビ部分は収納され、収納完了後に「−」が「+」に置換される

実はもう一つのミソが上記6の『収納完了後に「−」が「+」に置換』。4,5での書き方の場合はクリックと同時に置換されるが、4,6で使用している〔animate(params, [duration], [easing], [callback])〕(コレ自体の解説は以前のエントリ「上下に展開・格納するナビ」をご覧あれ)の〔[callback]〕部分に置換の関数〔function(){$("#accordion02").next().replaceWith("+");}〕を書き込むことで、収納完了後に置換がなされるようになる(らしい)。

以上だが、ここで1つ疑問が。
今回は1つの〔click()〕内に2つの〔animate()〕を挿入しているが、これで何故メニューの展開・収納が上手くいくのか、理屈上よく理解できていない。。。

何回目かのウェブサイト全面リニューアル

ちょっと思うところあって7回目の拙サイト全面改修を挙行。
今回は見映えなどの大幅変更というよりも細かい箇所の改装が主目的だったが、構造見直しのためHTMLは全取っ替え。以下に今回の改修点を列挙。

  • 横幅を960pxから1200pxへ
  • ヘッダおよびサイドメニューの固定化
  • 不要になったページの削除
  • 「上に戻る」ボタンの削除
  • メニュー展開時のアイコンのアニメ追加
  • 文字詰めjQueryの追加

横幅変更

横幅は現状1200pxでも大丈夫と(勝手に)判断し変更。そのついでに今まで左寄せにしていたレイアウトを左右中心揃えに。そのTIPSはネット上に沢山転がっているので割愛。

サイドメニュー固定

ウェブ、ショウジンさんの記事「サイドメニューとフッターメニューをCSSのposition:fixedで固定する例 *一応「IE6」もいける。」を参考にした。深謝!
サイドメニューに該当するCSS
#side {
 width: 100%;
 float:left;
 position: fixed;
 overflow: auto;
 background-image: url("../images/common/eszett_logo01.jpg");
 background-repeat: no-repeat;
 background-position: 3.6rem top;
}
#sideWrapper {width: 180px;}
上記赤字の「position: fixed;」を追加することでサイドメニューは固定される。
そして、今回の密かな目玉である「eſzett」ロゴを背景に追加しこれもサイドメニューと共に固定させるために、上記青字を追加。幅100%はサイト全体の横幅に対する設定で、これにより背景ロゴはサイドメニューに設定しているにも関わらず中途で切れずに(サイドメニュー自体は#sideWrapperにて幅180pxに設定)表示される。
コンテンツ部分のCSS
#main {
 width: 900px;
 float: right;
 overflow: auto;
 position: relative;
 margin-bottom: 6rem;
}
コンテンツ部分のCSSにて、赤字の「float: right;」を追加で、コンテンツ部分は設定通りの場所に収まる。
また、サイドメニューに背景ロゴを追加したので、青字の「position: relative;」を追加することで、背景ロゴがコンテンツ部分上に被ることを回避。
「position: relative;」を設定しないと背景ロゴが被さる。。。

メニュー展開時のアイコンのアニメ追加

なにかというと、メニュー展開する項目の右に「+」を追加して、メニュー展開時にこれが「-」に変わり、メニュー収納時にまた「+」になるよう、今まで使用してきたメニュー展開jQueryを改良。詳説は別エントリ「縦型メニュー展開・収納時(開閉時)にメニュー横の+−表示が切替るjQuery」にて。

文字詰めjQueryの追加

前エントリHTMLで文字詰め出来るJAVASCRIPTとJQUERYにて紹介したものを今回拙サイトに採用。その際、句読点・括弧類が2つ以上連続した場合「全角二分取り」になるだけでなく、欧文のenダッシュ・emダッシュ・掛算記号・©のアキ設定も追加。この拙ブログ最下部にあるコピーライト表記をご覧あれ。微妙すぎて判りづらいかも(苦笑


以上、変更の模様は拙サイト、www.eszett-design.comをご覧あれ。

Tuesday, 14 May 2013

HTMLで文字詰め出来るJavaScriptとjQuery

日頃WEBのテキストで句読点および括弧類が連続して出現する場合の詰め処理をしたくてどうしたものかと思案していたら、素晴しいJavaScript(とjQueryの混合)を発見。このスクリプト、要はペアカーニングを任意に設定できてしかも2つの括弧類連続を設定するだけで括弧類が3つ以上連続してもちゃんと詰めてくれる。いやはやありがたや。ということで今回参考というか丸々活用させていただいたのはFLAutoKerning.jsというスクリプト。
感謝深謝。

カーニングのペアを自動処理

今回の組版の設定は、基本ベタ組みで、句読点および括弧類が2つ連続した場合「全角二分取り」になるような、つまりは二分分詰まるような、オーソドックスな設定で試してみる。そして今回の句読点および括弧類は
起こし括弧類:「『([{〈《【〔
受け括弧類:」』)]}〉》】〕
句読点類・中点:、,。.・
の計21種の組合せに詰め設定を施すが、この組合せを配列にて自動化した。
jQuery(function($){
 var pncPrn = ["」","』",")","]","}","〉","》","】","〕","「","『","(","[","{","〈","《","【","〔","、",",","。",".","・"];
 for (var x=pncPrn.length; x--;){
  for (var y=pncPrn.length; y--;){
   p[pncPrn[x] + pncPrn[y]] = -0.6;
  }
 }
});
上記jQueryにて設定した句読点括弧類の【組合せ】をFLAutoKerning.js内カーニングペア定義の箇所に追加(不要な組合せもあるが、処理上別段問題ないのでそのままにする)。

行頭文字の処理

実はこのスクリプト、行頭の1文字もカーニング設定できる。つまり、行頭1字下げしない組み設定の時、起こし括弧類が行頭に来ると直前が二分アキになるのを詰めることができる。これも配列にて自動化した。
jQuery(function($){
 var Prn = ["「","『","(","[","{","〈","《","【","〔"];
 for (var z=Prn.length; z--;){
  p[Prn[z]] = -0.6;
 }
});
このjQueryもFLAutoKerning.js内行頭専用の箇所に追加。

行末文字の処理は…

このスクリプトでは出来ない。というか組版ソフトはどうやって行末処理のために行末の判別をしているのか、実に不思議だと改めて思う次第。

設定値「-0.6」って何なのさ?

ワタクシのデモページの文字サイズはrem単位にて、rootサイズ1rem(10px相当)、本文サイズは1.2rem(12px相当)に設定しているので、このとき二分は本文の半分の0.6rem(6px相当)になるので。
そうそう、このスクリプトはem単位に設定されているので、その部分をrem単位に変更した(下記の2箇所)
if(space!=0)
 char2 = "<span class='kerning01' style='letter-spacing:" + space + "rem'>" + char + "</span>";
     
//行頭約物の処理
if(i == 0 && kerningInfo[char])
 char2 =  "<span class='kerning02' style='margin-left:" + kerningInfo[char] + "rem'>" + char2 + "</span>";
こうして完成したデモページに、今回は「詰め解除」と「詰め設定」の2つのボタンを設置して詰め具合が判るようにした。
デモページ【WEB TYPOGRAPHY KERNING

Thursday, 9 May 2013

JavaScriptとjQueryで文字サイズ・行高・行取り・見出し行数から見出しのマージンを自動計算

ワタクシがwebデザイン上一番気にするのが見出しのマージン。いつもその時の感覚で決めるが、しっくり来ないことが多々ある。何か巧い方法が無いものかと『文字の組方ルールブック ヨコ組編』の「見出しの構造と組方」を眺めていて、自動計算出来るかもと思いjQueryメインに適宜JavaScriptを組み込みスクリプトなるものを書いてみた。
2013.5.14追記

参照

ほか、色々なサイト・ブログを参照させていただいた。深謝。

注意

なにせjQueryはおろかJavaScript、いやプログラミング全般に素人なので間違ってたりする可能性があるので、使用時は自己責任でお願いする。

実作したweb組版

本文の文字サイズ・1行の字詰・行間(行送り)などを決めると版面が決まる。見出しもその版面に則り「行取り」の方法でその上下のアキを決めていく。具体的には下図をご覧あれ。本文だけでなく見出しも行に綺麗に乗っているのがわかる。
本文サイズ12px、行高22px、行間10px、42字詰。各見出しサイズなどは図の通り。

完成形をブラウザで表示後キャプチャし、イラレで作成した水色の版面上にキャプチャ画像を配置した。

web組版の注意点

行送りの設定方法がDTPと異なる。
webの行送りはline-heightで設定するが、これは厳密には文字通り行の高さを設定するもので、アキの付き方は以下の図の通りになる。

本文上下のグレー網がline-heightで設定されるアキ

これを踏まえて版面設計や見出しのマージンを算出する。

見出しマージンの計算式

ということで、計算式を導くために、下図のように必要な部分を設定。
var bFont = body要素(本文)のfont-size
var bHeight = body要素(本文)のline-height
var hFont = 見出しのfont-size
var hHeight = 見出しのline-height
var hGyodori = 見出しの行ドリ行数
var hGyosu = 見出しの行数
var hMargint = 見出しの上マージン
var hMarginb = 見出しの下マージン

hMargint : hMarginbの比率をj : kとする
見出しが1つの場合
見出しが1つの場合

見出しの上下マージンの計算式は各々、
hMargint = j*(hGyodori*bHeight-hGyosu*hHeight)/(j+k)
hMarginb = k*(hGyodori*bHeight-hGyosu*hHeight)/(j+k)
j : k = 1 : 1の時、
hMargint = hMarginb = 0.5*(hGyodori*bHeight-hGyosu*hHeight)
j : k = 8 : 5(黄金比の近似比)の時、
hMargint = 8*(hGyodori*bHeight-hGyosu*hHeight)/13
hMarginb = 5*(hGyodori*bHeight-hGyosu*hHeight)/13
という風になる。
見出しが2つ以上の場合
見出しが2つ以上連続する場合

上記「見出しが1つの場合」に同じ計算式で算出でき、見出し間のマージンは上下見出しの下マージンと上マージンを足せば良い。

今回使用したjQueryやJavaScriptの留意点

  1. 本文や見出しのfont-sizeやline-heightの値は、css()で取得するが「16px」というように単位付きの文字列として返してくる。今回は数値として使いたいので、JavaScriptのparseFloat関数で文字列を数値化する必要がある。
  2. 本文や見出しのfont-sizeやline-heightは今回CSS3のrem単位で規定しているが、上記1.でrem単位で規定した値を取得するとpxに変換される。
  3. 本文や見出しのfont-sizeやline-heightはどちらも偶数か、またはどちらも奇数が好ましい。行高の計算でline-height-font-sizeの値を1/2にして行の上下に配分するが、そのとき小数点以下(0.5)が出ないようにするため。小数点はブラウザ側で丸めるが、ブラウザごとに丸め方が異なりレイアウトが崩れる可能性がある、らしい。
  4. 最終的に算出されたマージンの値は、Math.round()で小数点以下を四捨五入して整数値になるようにしている。上下マージン比j : kによりマージン値が無理数の場合があるので、それを丸めるために。
  5. 見出しが連続する場合、絞り込むため、ある要素の「前」にあたる兄弟要素を抽出するjQueryのprev([expr])関数を使うが、$("h4").prev("h3").prev("h2")のように連ねても使える。この場合、h2・h3・h4と連続しているh2のみにマージン設定ができる。



こうしてあとはJavaScriptとjQueryとで記述すれば完成。

スクリプトは【デモページ】のソースを参照していただければ。