タグ別アーカイブ: CSS

さらっと理解しておきたいjQueryオブジェクト(後編)

前編からひっぱります。

JavaScriptのオブジェクトについて、組み込みオブジェクト、ブラウザオブジェクト、DOMオブジェクトの三項目について説明しましたが、これらのオブジェクトではピリオドで何個もの処理を繋ぐメソッドチェーンの書式が使えません。なぜならメソッドが返す返り値が文字列や数値などバラバラな型であるからで、それは手続き型プログラミング言語のメソッドとして何ら不思議なことではありません。

ただ、HTML文書の要素を対象とした操作をする場合、一度処理を行った要素に連続して処理を与えるというケースが非常に多く、その度に要素の検索を行うのがかなりのオーバーヘッドとなります。そこで、メソッドの結果がまたオブジェクトを参照することで連続して処理を与えることのできるメソッドチェーンの実現に意味があるのです。

jQueryの要素の多くは、自身jQueryオブジェクトである上に、処理の返り値としてもjQueryオブジェクトを返します。ではjQueryオブジェクトとは何かというと、セレクタにより検索、ヒットしたDOM要素の集合を、多数の便利なメソッドの定義されたオブジェクトでラップしている状態です。console.logなどでオブジェクトの中身を確認してみると、単なる文字列として格納されたHTML要素と、ずらりと並んだプロパティ、メソッドがあることがわかります。これらのセットがjQueryオブジェクトです。

メソッドチェーンの終端で、jQueryオブジェクトのメソッドでない、通常のDOMオブジェクトのメソッドを使いたい場合はどうすれば良いでしょうか。たとえば前編で出した動かないプログラムの例ですが、jQueryオブジェクトの正体を知っていれば、このようなアクセスが可能であると予想が立ちますね。

$(".fadeinout")[0].innerHTML = "Hi!";

このように、呪文のようなjQueryと言えども仕組みがわかれば何ということも無いのです。これはjQueryのセレクタエンジンにも言えることなのですが、それはまたいずれかの機会に記事にします。


さらっと理解しておきたいjQueryオブジェクト(前編)

CSSコーダにとって、サイトを動的にしたい時の救世主となるjQuery。CSSセレクタで要素を選択し、あとはメソッドの書式に従っていくつかの呪文を唱えるだけで、簡単にアニメーションや文書構造の変更ができます。たとえば、サイト訪問時にclass=”fadein”とした全要素をフェードインする場合、以下のようなソースで事足ります。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja" dir="ltr">
<head>
//meta宣言とtitleは省略
//jQueryのインポート(Google CDN)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
$(function(){
$(".fadein").fadeIn();
//要素がフェードイン
});
</script>
</head>
//省略

もちろん$(“#main ul li”)のような指定にも対応していますので、解説サイトのサンプルをコピーして、セレクタ部分を変更するだけで好きな要素に処理を適用できます。
また、同じ要素に対して複数の処理を連続して適用する場合には、処理を順番にピリオドで繋いでいけばよいという特性も直感的です。メソッドチェーンと呼ばれるこの書き方を頭に入れておけば、JavaScriptについてほとんど知識が無くても、処理部分に手を加えることができます。

$(".fadeinout").fadeIn().fadeOut();
//フェードイン後フェードアウト

こうした直感的な文法をもつjQueryですが、本当に直感のままの記述を行っていると、ときどき反逆します(笑)。メソッドチェーンが有効にならず、途方に暮れてしまいます。たとえば次のような例です。

$(".fadeinout").attr("class").appendTo("#classname");
//クラス名を取り出し、classnameというidの領域に表示したい
//動きません

あるいは、JavaScriptについて少し知識のある人間が、jQueryもJavaScriptだからとチャンポンな書き方をして反逆されることもあります。

$(".fadeinout").innerHTML = "Hi!";
//動きません

何故こういったことが起こるのか、結論から言いますと、jQueryは独自メソッドをもつjQueryオブジェクトというオブジェクト形式を扱う為で、メソッドチェーンなどもメソッドの返り値がこのjQueryオブジェクトである為に実現しているのです。

jQueryオブジェクトを知る為に、JavaScriptのオブジェクトの種類について整理してみましょう。

組み込みオブジェクト 〜素のJavaScriptが持つオブジェクト

JavaScriptというと、WEBページを動的にする手段としてWEBと切っても切り離せない言語であると思われがちですが、実際のところ素のJavaScriptがそういった機能を有しているわけではありません。ブラウザ以外のJavaScript実行環境で、document.writeIn()などと命令しても、JavaScriptはそれがどういう命令なのか理解する事ができません。
それでは素のJavaScriptはどのような要求に応えるのかというと、数値や文字列の演算であったり、メモリへのアクセスであったりと、プログラミング言語の基本的な処理です。
しかしながら、素のJavaScriptにもオブジェクトやメソッドといった概念があり、既に組み込み済みのオブジェクトもあります。たとえばStringオブジェクトは文字列を操作するメソッドを提供するオブジェクトで、このオブジェクトは特に宣言をしなくても、文字列データに対して自動的に呼び出すことができるようになっています。

var movie = "演歌の花道";
var titlelength = movie.length;
//titlelengthの値は5

この例では変数movieに入った文字列をStringオブジェクトで自動的にラップしているため、Stringオブジェクトのlengthメソッドを使う事ができています。他にも組み込みオブジェクトとして、NumberやArrayなどがあります。

ブラウザオブジェクト 〜ブラウザメーカーによる勝手実装のオブジェクト

JavaScriptがWEBページを処理の対象として認識できるのは、WEBブラウザがJavaScriptのオブジェクトとしてページを定義し、処理の為のメソッドを提供しているからです。具体的にはページはWindowオブジェクトとして定義され、Windowオブジェクトの直下にdocument、location、navigatorなどのプロパティがあり、これらもまたオブジェクトとして定義され、メソッドが提供されているといった構造です。そして基本的にこのWindowオブジェクトは省略して書く事ができるため、おなじみのdocument.writeIn()という表記になっているわけです。
ちなみにWindowオブジェクト自体のメソッドとしては、setTimeOutなどのタイマー系やalertなどのウィンドウ表示系があります。これらは確かにdocument.alert()のようには書きませんね。

documentオブジェクトは下位にforms、images、anchorsといったオブジェクトを持ち、これらのオブジェクトはページ中のフォーム要素、イメージ、アンカー全てを配列に格納してくれているので、name属性やインデックスで個々の要素を取り出す事ができます。

var formvalue = document.フォーム名.要素名.value;
var formvalue = document.forms[インデックス].elements[インデックス].value;
var imagesource = document.イメージ名.src;

このように基本的なオブジェクトモデルをベンダーが定義してくれているおかげで、JavaScriptがWEB制作の言語として特待的なポジションを得ているわけです。ただ、ブラウザオブジェクトはIEとNetscapeのブラウザ戦争の過程で、独自仕様を実装しよう(そして囲い込みを行おう)という目論見のもとにルール無用に拡張されていった背景があります。そこで、そうした勝手実装でなくどのブラウザでも共通した記述が可能になるようなオブジェクトモデルが求められるに至りました。

DOMオブジェクト 〜XMLの汎用的な操作モデルを導入したオブジェクト

DOMとはDocument Object Modelの略で、HTMLの親戚であるXMLを操作するための汎用モデルです。ブラウザオブジェクトの勝手実装による混乱に収拾をつけるため、W3Cはこのモデルをベースにしたオブジェクトやメソッドを定義し、勧告としました。
DOMオブジェクトは文書中のhtmlタグとその属性、テキストなどに対応し、メソッドやプロパティを持ちます。また各タグへのアクセス方法として、タグ名、id、クラス名での検索メソッドを提供しています。これらはブラウザオブジェクトのdocumentオブジェクトをhtml文書の最上位の要素<html>の参照というかたちで実装されているので、これまでのブラウザオブジェクトのスクリプトと併存して使う事ができます。

document.getElementById("target").value = 1;
//idをもとに要素をオブジェクトとして取得するgetElementByIdメソッド
 
var element = document.lastChild;
//要素の親子関係(子要素を内包する親要素)をもとに要素を取得
 
element.setAttribute("id","idname");
//要素に属性を付加

今回はjQueryオブジェクトの説明まで辿り着かなかったので、次回に続きます。


clearfixのささやかな覚え書き

複数カラムのブログテンプレートなどを作成するとき、一般的にはCSSのfloatプロパティを使ってレイアウトを行います。たとえば2カラムで左にサイドメニュー、右に記事本文というレイアウトは、以下のようなhtml&CSSになるでしょう。

HTML部
<div class="wrapper">
<div class="sidebar">
//サイドメニューエリア本文
</div>
<div class="articlearea">
//記事本文
</div>
</div>
 
CSS
.sidebar{
float : left;
}
.articlearea{
float : right;
}

カラムを包括する親ボックスの大きさが指定されており、各カラムが親ボックスの高さの値を超えないときには、特にレイアウト上の問題は起こりません。しかしながら、ブログのようにカラムの本文が可変長で親ボックスの高さを超えるケースが考えられるときには、カラムが親ボックスをはみ出て表示されてしまい、レイアウトが崩壊してしまいます。

はみ出たカラム

これは、ボックス内でfloat指定されている要素の大きさが親ボックスの大きさを決める際に参照されないという特性によるものです。したがって最も仕様に適った解決は、floatさせた要素の後にclearプロパティでfloat解除した要素を設けることです。空のdiv要素やvisibilityプロパティをhiddenにしたhr要素、br要素がよく使われます。

HTML部
<div class="wrapper">
<div class="sidebar">
//サイドメニューエリア本文
</div>
<div class="articlearea">
//記事本文
</div>
 
//空divの場合
<div style="clear : both"></div>
 
//非表示にしたhrまたはbr
<hr class="clearfix" />
<br class="clearfix" />
</div>
 
CSS
.sidebar{
float : left;
}
.articlearea{
float : right;
}
.clearfix{
visibility : hidden;
clear : both;
}

この方法はシンプルですが、ページのセマンティック(意味)としてはデザイン修正の為だけの無意味な要素をhtmlに加える事になるので好ましくありません。
そこで、無駄な要素を加えることなくレイアウト修正を行う、名前もそのまま”clearfix”というテクニックが開発されました。

HTML部
<div class="wrapper">
<div class="sidebar">
//サイドメニューエリア本文
</div>
<div class="articlearea">
//記事本文
</div>
</div>
 
CSS
//clearfixの追加部分
.wrapper:after{
content : "";
display : block;
clear : both;
}
//IE6,7用
.wrapper{
zoom : 1;
}
 
.sidebar{
float : left;
}
.articlearea{
float : right;
}

CSSのafter疑似要素を使って、floatを解除する要素を無理矢理埋め込むという形です。この方法ならば、検索エンジンやアプリケーションがページのhtmlのみを取得する場合に、解釈の混乱をひきおこす無駄な要素が発生しません。IE用の追加部分については、独自仕様のhasLayoutというプロパティがtrueであれば子要素のfloatを親ボックスのサイズ計算に含めるという特性を利用しています。無害なレイアウト指定(zoom:1;やwidth:100%;など)であれば何でも良いのですが、ソースの意図を明確にする為にzoom:1;の指定をしている場合が多いようです。

ここまでがclearfixの説明です。先に述べた通り、floatを解除する要素を最後に加えるという解決方法ですね。

それに対して、親ボックスのoverflowプロパティを明示的にhiddenと指定することで、親ボックスのサイズ計算方法を変えるというテクニックもあります。overflowプロパティとは、ボックス内の要素がボックスのサイズを超えてしまった際の表示方法についての指定で、何も指定しない状態はvisible、つまりはみ出た部分も表示する指定になります。これをhiddenと指定した場合、はみ出す部分のみ非表示となると同時に、ボックスの高さの計算式にfloatさせた要素も含まれるようになります。

HTML部
<div class="wrapper">
<div class="sidebar">
//サイドメニューエリア本文
</div>
<div class="articlearea">
//記事本文
</div>
</div>
 
CSS
.wrapper{
overflow : hidden;
//IE6,7用
zoom : 1;
}
.sidebar{
float : left;
}
.articlearea{
float : right;
}

場当たり的な対応ではありますが、セマンティックを汚染せずさらに簡単なので、こちらをバカの一つ覚えのように使ってしまって良いかもしれません。


子テーマを使ったWordPressカスタマイズ(CSS編)

(前口上が長いので、とりあえずタイトル通りのカスタマイズの方法だけ知りたいという方は、四段落ほど飛ばして読んで下さい)

WordPressカスタマイズ、ダッシュボードの左メニューからの設定変更を初級編とするならば、さしずめ中級編はCSSを用いた各要素の表示変更といったところでしょうか。静的ページのCSSによるレイアウトに習熟された方でも、いつも通りの手順でCSSをいじったが反映されない、あるいはダッシュボードで促されるままアップデートをしたら、苦労して設定したスタイルが無効になったなどなど、トラブルに直面して初めてWordPressが一筋縄でいかないという事に気付く筈です。まさにそこからが中級編の入り口で、中級編以降のカスタマイズには、WordPressの仕組みの一定以上の理解が必要とされるのです。

WordPressでは、一つのページを作るのに様々なディレクトリの様々なファイルを参照し、それらを決められた優先順位で読み込んで表示します。スタイルシートについてもそれは同様ですが、スタイルシートの性質として、同じ要素に対するスタイル指定は後に宣言された方を優先とするという原則と、idやクラスなど具体性のある宣言を優先するという原則があります。ゆえに、特定の要素について最終的に有効になっているスタイルがどのファイルのどこで宣言されたものかが判別できないと、現在のスタイルを変更しようと思っても変更の箇所がわかりません。
要素に実際どういったスタイルが有効になっているのかは、CSSの熟練者にとっては常識ですが、ブラウザの機能を使って調べられます。SafariやChromeなどのWebKit系ブラウザであれば、要素の上で右クリックし”要素の詳細を表示”を選択すると、”webインスペクタ”ウィンドウが現れるので、右側の”一致したCSSルール”という部分に注目します。画像の例ではp要素に適用されたルールが列挙されていますが、line-heightについてはcore.cssというファイルの250行目で宣言されたものの、同じcore.cssの1350行目でより具体的なルールが宣言されたため、効果が打ち消されていることがわかります。

WEBインスペクタ

Firefoxの場合も、右クリック→”要素を調査”で同様の機能を使うことができます。

さて、ブラウザの機能で宣言の位置が特定できたら、その箇所を変更することでスタイルの変更も有効になります。WordPressでは、大抵の場合最終的に有効になっているスタイルは、ルートディレクトリからwp-content→themes→現在使用中のテーマ名のディレクトリ、と階層を下ってその中にある、style.cssというファイルで宣言されています。つまり導入しているテーマに付随したCSSなのですが、このファイルをいじれば、とりあえずスタイルの変更ができることが多いと覚えておいて下さい。

しかしながら、このstyle.cssを直接いじっての変更は非推奨です。というのも、不具合が起きてしまったときにその原因が果たしてテーマ自体の問題なのか、あるいは加えた変更の問題なのか、が判別しづらくなります。また、テーマをアップデートする際にはこのstyle.cssごとアップデートされることになるので、アップデート毎に変更部分がリセットされてしまいます。

そういった問題を回避する方法として、WordPress3.0以降のヴァージョンには子テーマという仕組みが存在します。これにより現在有効になっているテーマを直接変更することなく、任意の部分のみに変更を付け足すことができます。また、ファイルとしては親テーマのパッケージの外部に置く形となるので、親テーマのファイルがアップデートされても影響を受けません。
具体的な設定方法を見ていきましょう。まずは子テーマのディレクトリを用意し、その中にstyle.cssというファイルを作ります。今回はmystiqueテーマの子テーマとしてchildtheme1というテーマを作るとします。style.cssの先頭に最低限以下の記述があれば、子テーマとして機能します。

/*
Theme Name: childtheme1
Template: mystique
*/

CSSのコメント行を使って、まずテーマ名と継承元テーマ名を宣言します。通常のスタイル宣言と違いコロンの左側にスペースは許されないので注意して下さい。またTemplateのラベルに指定する値は、親テーマの名称ではなく、themesディレクトリ下の親テーマのディレクトリ名です。大文字小文字の区別もあるので注意を払って下さい。
ともあれ、これで子テーマとして認識されるようになりました。ダッシュボードの左メニューの”外観”から”テーマ”を選ぶと、この子テーマが通常のテーマと同様選択できるようになっています。子テーマを選択すると、親テーマのファイルはそのままにstyle.cssのみ親テーマのではなく子テーマのものを読み込むようになります。

匿名作子テーマ

先程のstyle.cssに少し肉付けをしましょう。まず、子テーマのstyle.cssではスタイルの記述が行われていないので、このまま読み込むとテーマの表示が滅茶苦茶になってしまうはずです。親テーマのstyle.cssの記述を継承するための記述を行います。

/*
Theme Name: childtheme1
Template: mystique
*/
@import url('../mystique/style.css');

@import宣言に親テーマのパスを与えます。注意すべきなのは、子テーマのstyle.cssからの相対パスを与えるということです。
これで親テーマのスタイルを丸ごと読み込みました。さて、先述のCSSのルール、後から宣言した方を優先というものを思い出して下さい。つまり@import宣言の後でスタイルの設定を行えば、既に親テーマのstyle.cssで同じ要素に対する設定がされていても、自動的に子テーマのものが優先されるということです。

/*
Theme Name: childtheme1
Template: mystique
*/
@import url('../mystique/style.css');
#none{
display : none;
}

このように書くと、idがnoneの要素が親テーマでどのように設定されていようと表示されなくなります。仕組みがわかれば、あとはつらつらといつも通りのCSS編集ができますね。

以上が子テーマのカスタマイズ(CSS編)です。子テーマではスタイルの変更以外にも、親テーマのもつテンプレートやウィジェットなども置き換え/追加することができます。そちらはPHPの知識が必要となってきますので、いずれ詳しく紹介したいと思います。


プログラム・設定ファイルのコメント書式一覧

個人的によく使うプログラミング言語・設定ファイルのコメント書式を、まとめてメモしておこうと思います。

コメント書式一覧
言語・設定名 コメントの書式 備考
XHTML(HTML)・HTML5 <!‐‐ ここにコメントを書く ‐‐> 複数行も可能です。コメント中の連続したハイフン(‐‐)の使用は禁止されています。
CSS /* ここにコメントを書く */ 複数行も可能です。
PHP // ここにコメントを書く 一行のコメント。複数行はダメ。C++形式。
#ここにコメントを書く 一行のコメント。複数行はダメ。ShellやPerl形式。
/* ここにコメントを書く */ 複数行も可能です。
JavaScript・ActionScript // ここにコメントを書く 一行のコメント。複数行はダメ。C++形式。
/* ここにコメントを書く */ 複数行も可能です。
Objective-C・Swift // ここにコメントを書く 一行のコメント。複数行はダメ。C++形式。
/* ここにコメントを書く */ 複数行も可能です。
SQL ‐‐ ここにコメントを書く 一行のコメント。複数行はダメ。
/* ここにコメントを書く */ 複数行も可能です。
php.ini(PHPの設定ファイル) ; ここにコメントを書く 一行のコメント。複数行はダメ。
.htaccess(サーバアプリケーションの設定ファイル) # ここにコメントを書く 一行のコメント。複数行はダメ。

これからもうちょっと複雑なWEB制作を始めたら、表の項目が増えていく可能性もあります。そして、間違っている箇所を発見したら指摘していただけると非常に助かります。