【.htaccess】mod_rewrite モジュール – その1 リダイレクトの基本

.htaccess logo

mod_rewrite モジュールは、「URL の書き換え」を行うためのモジュールです。
mod_rewrite モジュールの機能を利用することで、Redirect ディレクティブと同じく、リダイレクトを行えます。mod_rewrite モジュールのリダイレクトでは、より細かな設定を行えますが、書き換え前の URL に置かれたファイル、書き換え後の URL に置かれたファイル、両方がないと機能しません。

mod_rewrite モジュールについて5回でまとめます。

その1 リダイレクトの基本 ← 今回
その2 RewriteCond ディレクティブ
その3 様々なリダイレクト利用例
その4 HTTP 環境変数一覧
その5 RewriteRule のフラグ一覧

mod_rewrite モジュールを利用したリダイレクトの基本構文

mod_rewrite モジュールでリダイレクトを行うには、基本的には、RewriteEngine、RewriteBase、RewriteRule の3つのディレクティブを利用します。

RewriteEngine On
RewriteBase /
RewriteRule 転送元ファイル 転送先URL [R=301,L]

一つずつ見ていきましょう。

  • 1行目: RewriteEngine
  • mod_rewrite モジュールを有効化します。デフォルトでは “Off” になっているので、”On” にすることで利用を宣言します。

  • 2行目: RewriteBase
  • 転送先の URL の基準となるディレクトリを指定するのですが、

    ① 3行目の RewriteRule で指定する転送先の URL が相対パスの場合 ⇒ 転送元(.htaccess の置かれているディレクトリ)からみて、転送先の URL の基準となるディレクトリまでの相対パスを指定
    (省略した場合、RewriteRule ディレクティブの基準となる URL は .htaccess が置かれたディレクトリ、つまり ” RewriteBase / ” となります。)

    ② 3行目の RewriteRule で指定する転送先の URL が絶対パスの場合 ⇒ 不要

  • 3行目: RewriteRule
  • URL 書き換えのルールを指定します。

    転送元ファイル: .htaccess の置かれたディレクトリ内のファイル名となります。正規表現が使えます。

    転送先URL : 絶対パス、相対パス共に指定できますが、相対パスで指定する場合、2行目のRewriteBase で指定したディレクトリが基準となります。後方参照が利用できます。

    [R=301,L] : [ ] の中は、フラグ(RewriteRule ディレクティブの機能)を指定します。URL 書き換えに関する様々なフラグ(⇒ RewriteRule のフラグ一覧)がありますが、今回はリダイレクトを行うので、リダイレクトを指定するフラグ、” R (=リスポンスコード) ” と記述します。
    ” R=301 ” ⇒ 恒久的な移動の場合指定(”R= permanet ” と記述も可能)
    ” R=302 ” ⇒ 一時的な移動の場合指定(” R=temp ” と記述も可能)
    コードを指定しない場合、デフォルトの ” R=302 ” となります。

    複数のフラグを指定する場合は、” , ” で区切ります。” R=301 ” に続いて、URL の書き換えの終了を指示するフラグ、” L ” を記述し、後述のルールを実行させないようにします。

mod_rewrite モジュールを利用したリダイレクトの設定例

“blue.com” と、”green.com” という二つのドメインがあったとします。

以降、4つのパターンを考えてみます。

① 別サイトへ1ページのみの転送
blue.com/index.html ⇒ green.com/index.html

② サイト全体転送
blue.com ⇒ green.com (それぞれ対応するファイルへ転送)

③ サイト内一部のディレクトリを転送
blue.com/circle ⇒ green.com/square (それぞれ対応するファイルへ転送)

④ 同じサイト内で1ページ転送
blue.com/example01.html ⇒ blue.com/example02.html

すべて恒久的な移動とするので、RewriteRule のフラグは、[R=301,L] とします。

<① 別サイトへ1ページのみ転送>

RewriteEngine On
RewriteRule index\.html  http://green.com/index.html [R=301,L]

1行目: “RewriteEngine On” => mod_rewrite モジュールを利用の有効化

2行目: “RewriteRule” => 書き換えルールを指定
” index\.html ” => .htaccess ファイルの置かれた blue.com 内の index.html が転送元であるという意味
” http://green.com/index.html ” => 転送先 URL

* 転送先 URL が絶対パスで記述されているので、RewriteBase は省略
* RewriteRule ディレクティブは正規表現に対応するので、メタ文字を普通の文字として扱うには、直前に” \ “が必要です。” index.html ” は、” index\.html ” と記述。

<② サイト全体転送>

RewriteEngine On
RewriteRule (.*)$  http://green.com/$1 [R=301,L]

1行目: “RewriteEngine On” => mod_rewrite モジュールを利用の有効化

2行目: “RewriteRule” => 書き換えルールを指定
” (.*)$ ” => ” (.*) ” は0回以上の文字の繰り返し、” $ “は文字列の文末がマッチ(.htaccess ファイルの置かれた blue.com 内の それぞれのファイルが転送元であるという意味)
” http://green.com/$1 “=> 、” $1 ” = ” (.*) ” (green.com 内のそれぞれ対応する転送先 URLを意味)

* 転送先 URL が絶対パスで記述されているので、RewriteBase は省略

<③ サイト内一部のディレクトリを転送>

RewriteEngine On
RewriteRule ^circle/(.*)$  http://green.com/square/$1 [R=301,L]

1行目: “RewriteEngine On” => mod_rewrite モジュールを利用の有効化

2行目: “RewriteRule” => 書き換えルールを指定
” ^circle/(.*)$ ” => ” ^ ” は文字列先頭が一致、 ” (.*) ” は0回以上の文字の繰り返し、” $ “は文字列の文末がマッチ(.htaccess ファイルの置かれた blue.com 内、circle ディレクトリ内のそれぞれのファイルが転送元であるという意味)
” http://green.com/square/$1 “=> 、” $1 ” = ” (.*) ” (green.com 内、square ディレクトリ内のそれぞれ対応する転送先 URLを意味)

* 転送先 URL が絶対パスで記述されているので、RewriteBase は省略

<④ 同じサイト内で1ページ転送>

RewriteEngine On
RewriteBase /
RewriteRule example01\.html  example02.html [R=301,L]

1行目: “RewriteEngine On” => mod_rewrite モジュールを利用の有効化

2行目: “RewriteBase /” => 転送先の基準となる ディレクトリを指定。転送元(.htaccessの置かれたディレクトリ)と同じディレクトリ内という意味。

3行目:”RewriteRule” => 書き換えルールを指定
” example01\.html ” => .htaccess ファイルの置かれた blue.com 内の example01.html が転送元であるという意味
” example02.html ” => 2行目のRewriteBase で指定された基準となる伝送先ディレクトリ内 (blue.com) の example02.html が転送先 URL

ファイルの最終行には空行を入れる必要があります。ご注意ください!

【.htaccess】Redirect ディレクティブ

.htaccess logo

URLやドメインが変わって、旧 URL から新 URL への自動遷移に利用します。
リダイレクトは、Redirect ディレクティブ、mod_rewrite モジュールどちらでもできますが、2つの違いはこちらです。

Redirect ディレクティブ: 旧 URL から新 URL へシンプルなリダイレクトのみ。サーバのコア機能を利用するので、大概の場合利用できます。
旧 URL に相当するファイルがなくても、新 URL にファイルがあれば問題ありません

mod_rewrite モジュール: URL の書き換え機能なのですが、それを利用して、リダイレクトの細かな設定が出来ます。サーバの拡張機能を利用するので、サーバによっては利用できないこともあります。(とは言っても、ほとんどは利用できると思いますが)
重要なのは、書き換え前の URL に置かれたファイル、書き換え後の URL に置かれたファイル、両方が存在しないと機能しません

今回は、Redirect ディレクティブについてまとめます。

Redirect の基本構文

Redirect ディレクティブで、URL を自動転送する基本的な構文です。

Redirect [status] URL-path URL

左から一つずつ見ていきましょう。

  • Redirect
  • 旧 URL から新 URL へリダイレクトの宣言です。

  • [status]
  • 後述しますが、このオプションを指定することで、このリダイレクトが恒久的なものなのか、一時的なものなのか、など、HTTP ステイタスコードを返すことができます。指定がないと、デフォルトの “temp” となります。

  • URL-path
  • 転送元の URL パスを指定します。http: などで始まる絶対 URL ではなくて、/ で始まるルートパスです。.htaccess ファイルを置くディレクトリが、トップディレクトリとなります。

  • URL
  • 転送先の URL を指定します。http: などで始まる絶対 URL を指定します。

Redirect ディレクティブの status 引数一覧です。

説明
permanent 恒久的な移動の場合指定。HTTP ステータス:301
temp 一時的な移動の場合指定。HTTP ステータス:302
seeother 他のもので置き換えられた場合指定。HTTP ステータス:303
gone 恒久的に削除された場合指定。HTTP ステータス:410

Redirect 設定例

“blue.com” という旧ドメインから、”green.com” という新ドメインへ、サイトを恒久的に引越ししたとします。

恒久的な移動なので、[statas] は、”permanet” を指定します。
こうすることで、検索エンジンに、旧サイトの評価が、新サイトへと受け継がれるので、恒久的な引越しである場合、SEO 的にも重要です。

blue.com/ 以下のファイルは、それぞれ green.com/ 以下の対応するファイルへ転送されます。
blue.com/index.html ⇒ green.com/index.html
blue.com/example01.html ⇒ green.com/example01.html

しかしながら、blue.com/example02.html を転送しようとすると、green.com/ 以下には example02.html という対応するファイルがありません。この場合は、エラー(Error 404)となります。

このようなエラーに対応するために、ErrorDocument ディレクティブで、動作指定をするのですが、後日まとめます。

<サイト全体転送>
構文はこのようになります。

Redirect permanent / http://green.com/

左から一つずつ見ていきましょう。

“Redirect” => リダイレクトを行う宣言
“permanent” => 恒久的な移動
” / ” => 転送元の URL パス(.htaccess ファイルは、blue.com の直下に置かれているので、blue.com 以下のファイル全てに有効)
“http://green.com” => 転送先の絶対 URL

<一部のディレクトリ転送>
blue.com 以下の circle ディレクトリのみを、green.com 以下の square ディレクトリに転送したい場合の構文はこうなります。

Redirect permanent /circle/ http://green.com/square/

<特定のページ転送>
blue.com 以下の example01.html のみを、green.com 以下の example01.html に転送したい場合の構文はこうなります。

Redirect permanent /example01.html http://green.com/example01.html

RedirectMatch ディレクティブ

Redirect と同じ機能ですが、正規表現を用いて転送元の URL パスのマッチングを行います。

正規表現、後方参照についてはこちらを参照
正規表現の基本
後方参照

RedirectMatch [status] regex URL

左から一つずつ見ていきましょう。

  • RedirectMatch
  • 旧 URL から新 URL へ正規表現を使うリダイレクトの宣言です。

  • [status]
  • Redirect と同じ引数を指定できます。指定がない場合、デフォルトの “temp” となります。

  • regex
  • 転送元の URL パスを、正規表現を使って指定します。

  • URL
  • 転送先の URL を指定します。後方参照を利用できます。

上の図で、blue.com 以下の html ファイルのみ、green.com 以下の対応する html ファイルへ転送する場合の例です。

RedirectMatch permanent /(.+)(\.html)$ https://green.com/$1$2

左から一つずつ見ていきましょう。

“RedirectMatch” => 正規表現を使ったリダイレクトを行う宣言

“permanent” => 恒久的な移動

” /(.+)(\.html)$ ” => 正規表現を使った転送元の URL パス
(.+) = 1字以上の任意の文字列、(\.html) = “.html”、$ = 文字列の文末がマッチ

“http://green.com/$1$2” => 後方参照を使った転送先の絶対 URL
$1 = (.+)、$2 = (\.html)

最後になりましたが、ファイルの最終行には空行を入れる必要があります。
お忘れなく!

後方参照

後方参照ロゴ

.htaccess では、一部のディレクティブ(RewriteRule、RewriteCond、Macht の含まれるもの)では正規表現が利用でき、基本的な正規表現はこちらにまとめました。⇒ 正規表現の基本

正規表現で条件にマッチングした文字または文字列は、変数として格納して、それより後で利用することができます。

例を見ていきましょう。このような正規表現があったとします。

(blue|green)(\d+)(\.html)

3つにグループ化されていますね。何を意味しているかというとこうなります。

(blue|green) ⇒ “blue” または “green”
(\d+) ⇒ 1個以上の任意の数字の繰り返し
\.html ⇒ “.html”。”.” はメタ文字なので、普通の文字として “.” を扱うために、直前に “\” がつきます。

つまり、”blue1.html”、”blue2.html”、”blue10.html”、”green1.html”、”green2.html”、”green10.html” などがマッチングします。

これらを変数として格納し、 “$n” という表記で、後で利用することができます。(“n” には 0~9 の数字が入ります。)マッチング条件が複数ある場合、左側から、$1、$2、$3 という順番で、変数が格納されていきます。($0 と $1は同じ)

この例の場合はこうなります。

(blue|green) ⇒ $1
(\d+) ⇒ $2
\.html ⇒ $3

実際の.htaccessに使われる例としてはこんなかんじになります。

RedirectMatch /(blue|green)(\d+)(\.html) http://newdomein.com/$1$2$3
#               ↑"$1"に格納 ↑"$2" ↑"$3"              後方参照 ↑
# 転送元にある該当htmlファイルを、newdomein.comにある同じ名前のhtmlファイルに転送

Macht の含まれるディレクティブ、RewriteRule ディレクティブでは、前述したように、後方参照に ” $n ” が使われるのですが、RewriteCond ディレクティブでは、” %n ” が使われます。ご注意ください。

正規表現の基本

正規表現ロゴ

.htaccess では、一部のディレクティブ(RewriteRule、RewriteCond、Macht の含まれるもの)では正規表現が利用できます。

正規表現とは、プログラミングで使用される、いくつかの文字列を1つの形式で表現する記述方法です。何に使われるかといえば、多くの文字列から必要な文字列を検索して、条件を指定したりする場合です。

プログラミングとかしていても、あまり使わないやつとか、忘れちゃうんですよね。
.htaccess のディレクティブをまとめる前に、基本的な正規表現をまとめてみます。

基本的な正規表現

記号 説明
. 任意の1文字にマッチ
例)”の.と” なら、”のーと”、”のうと”、”のりと” などがマッチ。
^ ^ に続く文字列が 行の先頭にある場合にマッチ
例)”^本” なら、”本棚”、”本拠” はマッチ。”台本” はマッチしない。
$ $ の前の文字列が 行の文末にある場合マッチ
例)”花$” なら、”生花”、”紅花” はマッチ。”花束” はマッチしない。
* * の前の文字が 0回以上繰り返す場合にマッチ
例)”はー*い” なら、”はい”、”はーい”、”はーーい” などがマッチ。
+ + の前の文字が 1回以上繰り返す場合にマッチ
例)”はー+い” なら、”はーい”、”はーーい” がマッチ。”はい” はマッチしない。
? ? の前の文字が 0個か1個ある場合にマッチ
例)”はー?い” なら、”はい”、”はーい” がマッチ。”はーーい” はマッチしない。
| ~または~(選択肢の区切り目)
例)”小学生|中学生|高校生” なら、この3つの選択肢のいずれかがマッチした場合。
[] 角括弧内の文字のどれか1つにマッチ。
例)[abc123] なら、”a”、”b”、”c”、”1″、”2″、”3″にマッチ。

角括弧内の文字を “-” を使って範囲指定可能
例)[a-cX-Z0-1] は “a”、”b”、”c”、”X”、”Y”、”Z”、”0″、”1” にマッチ。

[^] 角括弧内の文字が含まれないものにマッチ
例)[^a-c] なら、”a”、”b”、”c” 以外にマッチ。
() グループ化(文字の集合を1つにまとめて扱う)
例)(一時間)+ なら、”一時間” にマッチ。
{} 直前の文字、またはグループの桁数を指定
例)”あ{3}” なら、”あああ” がマッチ。
“あ{2,3}” なら、”ああ”、”あああ” がマッチ。
“あ{2,}” なら、あを2回以上繰り返すものがマッチ。

メタ文字を普通の文字として扱う ” \

正規表現の基本として使用される ” . 、^ 、$ 、* 、+ 、? 、| 、[ 、] 、{ 、} ” は、メタ文字と呼ばれ、上記、「基本的な正規表現」でまとめた通り、文字を形式に沿って表現するための意味が与えられています。これらのメタ文字を、普通の文字として扱うには、直前に “ \ ” を記述することで実現します。

説明
\ エスケープ 直後のメタ文字を普通の文字として扱う
例)”2\+3″ の場合、”2+3″ がマッチ。”+” は、「直前の文字が 1回以上繰り返す場合にマッチ」という意味ではなく、普通の文字として扱われる。

定義済みの文字クラス

記号 説明
\d [0-9] 全ての数字
\D [^0-9] 数字以外の全ての文字
\s [\t\f\r\n] 垂直タブ以外のすべての空白文字
\S [^\t\f\r\n] 空白文字以外の全ての文字
\w [a-zA-Z_0-9] アルファベット、アンダーバー、数字
\W [^a-zA-Z_0-9] アルファベット、アンダーバー、数字以外の全ての文字

後方参照

正規表現で条件にマッチングした文字または文字列は、変数として格納して、それより後で利用することができます。
後方参照について詳しくはこちら⇒後方参照

【.htaccess】設定ファイルで出来ること

.htaccess logo

設定ファイル.htaccess、私はリダイレクトぐらいでしか利用していないのですが、色々便利なので、しっかり理解するためにまとめてみたいと思います。

.htaccess とは

.htaccess(ドット・エイチ・ティー・アクセス)とは、Apache を用いた Web サーバーの管理ファイルです。( Apache は一時期6割ぐらいのシェアがありましたが、最近 Nginx のシェアが伸びてきているみているみたいですね。.htaccess で設定を行う場合は、利用している Web サーバーが Apache なのか要確認です。)

Apache の設定は、サーバー管理者なら、httpd.conf で行うのですが、私のように、レンタルサーバーを利用している立場ですと、httpd.conf をいじるなんてこと、できません。httpd.conf で行う設定を、サイトの管理者レベルでも一部行えるのが、この.htaccess ファイルです。ただ、.htaccess で利用可能なコマンドは、httpd.conf で許可されているものに限ります。上手くいかないようであれば、利用可能なコマンドかどうか、サーバー会社側に問い合わせが必要ですね。

設定は割合簡単で、ディレクトリ単位で行います。

「.」で始まると、一瞬、拡張子か何か?と思ってしましますが、UNIX系のOSでは隠しファイルを意味しています。

.htaccess でよく利用される設定

出来ることはたくさんあるのですが、よく使われているものをピックアップして、次回以降一つずつまとめていきたいと思います。。

  • リダイレクト (Redirect)
  • URLやドメインが変わって、旧URLから新URLへの自動遷移に利用します。
    HTML のヘッダに書き込むことでもリダイレクトは可能ですが、SEO 的に、設定ファイルで行った方がいいなどとも言われていますね。

  • リダイレクトの細かな設定 (mod_rewrite)
  • mod_rewrite モジュールは、URL の書き換えを行うものですが、その機能を利用してリダイレクトさせることもできます。Redirect ディレクティブより細かな設定が出来ます。「wwwありなし設定」、「index.htmlありなし設定」、「https(SSL)へリダイレクト」など。

  • エラーページの設定 (ErrorDocument)
  • ページがなかった時、問題やエラーが発生したときの動作を指定できます。これを指定していないと、ユーザは別の URL へ移動してしまうかもしれないし、レンタルサーバーの広告などが表示される場合もあるので、他のページにリダイレクトさせるか、特定のメッセージを表示するなどの設定をしておいた方が良いです。

  • デフォルトページ設定 (DirectoryIndex)
  • クライアントがディレクトリ名の最後に「/」を指定した場合に返すディレクトリインデックスを指定できます。「index.html」「index.php」など。

  • ベーシック認証
  • ディレクトリなどに認証を付けてID/パスワードを確認するダイアログを挟むことができます。「.htaccess」だけでなく「.htpasswd」というファイルも必要です。

  • アクセス制限 (Deny / Allow)
  • 外部からのアクセスを拒否または許可することができます。IPアドレス、ホスト名などを指定できます。

.htaccess の設置場所


.htaccess はディレクトリごとに有効になります。この図の場合、.htaccess(A)は、blue-box ディレクトリと、その中に含まれる yellow-box ディレクトリに有効となります。
.htaccess(B) は、yellow-box のみに有効となります。
全く外にある green-box ディレクトリは、.htaccess(A)、(B)ともに、影響を受けません。

.htaccess の基本的な書き方

ファイル名: .htaccess
テキストエディタで作成したファイルは、拡張子無しで “.htaccess” として保存します。OS の方で、拡張子無しの保存が出来ない場合は、取りあえず “.htaccess.txt” として、転送後にファイル名を変更します。

コメントアウト: # で始まる行
“#” で始まる行がコメントになります。基本的には、コメント行は独立させます。

文字コード: UTF-8
テキストエディタで保存の際に、文字コードを “UTF-8” に指定します。

改行コード: LF
テキストエディタで保存の際に、改行コードを “LF” に指定します。
改行をすると、構文の終端とみなされるので、基本的に構文の途中で改行はしません。
また、ファイルの最終行には空行を入れる必要があります。

転送場所: ディレクトリごとに有効
.htaccess の有効範囲はディレクトリごととなります。(上記、「.htaccess の設置場所」参照)
複数 .htaccess ファイルがある場合、内容が被れば、より深い階層のものが上書きされます。

パーミッション: 644
Web サーバに転送後、パーミッションを “644(rw-r–r–)” に指定します。

正規表現:Macht の含まれるディレクティブ、RewriteRule、RewriteCond で利用可能
正規表現について詳しくはこちら⇒ 正規表現の基本
後方参照について詳しくはこちら⇒後方参照

【CSS / HTML】img に入る隙間って何だろう?

Cat and Dog

img の下に入る隙間


margin も padding も 0 なのに、なぜか img の下に隙間が入ってしまう。何ででしょう?
これ、地味に困るんですよね。
レイアウトが若干ずれるし、ネガティブマージンで見出しを画像に重ねようとしても、計算通りいかない・・・

原因は、img はインラインレベルの要素なので、デフォルトで vertical-align: baseline となっているからです。空間に引かれたベースラインの上に、画像が表示されるという考え方です。ベースラインに揃えられた画像の下には、任意の隙間ができます。

<① vertical-align で上または下に揃える >
img タグに vertical-align: top または vertical-align: bottom を指定することで、画像を上揃えか下揃えにして、ベースラインの下の隙間が無くなります。

img {
vertical-align: bottom; /* または vertical-align: top; */
}

<② display で img をブロックレベルの要素化にする >
display: block でブロックレベルの要素化することで、インラインレベルの配置にまつわるベースラインは消えます。ですが、ブロックレベルとして扱われるので、基本的には、隣接する要素とは縦方向に並びます。(横方向に並びません。)

img {
display: block;
}

ブロックレベル、インラインレベル、それぞれの特徴をよく知ることが大切ですね。

img の横に入る隙間


img と img を横並びに隙間なしに表示させたいのに、こんな風に、間に隙間が入ることがあります。

これは、html の書き方によります。
次の様に、二つの img タグを改行して記述して書いた場合です。

<img src="cat-dog.jpg">
<img src="hedgehog.jpg">

隙間を消すためには、これを改行せずにつなげて記述します。

<img src="cat-dog.jpg"><img src="hedgehog.jpg">


これで隙間が消えます。小さなことですが、気を付けなくてはいけないことですね。

【CSS】margin の相殺を理解する

HTML CSS Logo

きっちり計算してレイアウトを作ったのに、大きさが合わない・・・。
margin が思ったように反映されない?どうして?
margin の相殺を理解していないと、そんなことになったりしますよね。
どんな場合に margin の相殺が起きるのか、起きないのかのまとめです。

どんな時に margin の相殺が起こるのか

細かな条件や例外を除いて、ざっくり言ってしまえばこれです。

「縦方向に接するブロックレベルの要素間の margin は相殺される」

隣接する margin は大きい方が適用されます。
要素同士が親子関係である場合、横方向の margin も接しますが、縦方向は相殺が起こり、横方向は起こりません

margin の相殺例外: 兄弟関係の要素

兄弟関係の要素に以下のモジュールやプロパティが指定されている場合、相殺は起こりません。

  • フレックスボックス・レイアウト
  • グリッド・レイアウト
  • position プロパティ(fixed、absolute が指定されている)
  • float プロパティ(left、right が指定されている)

margin の相殺例外: 親子関係の要素

親子関係の要素に以下のモジュールやプロパティが指定されている場合、相殺は起こりません。

  • フレックスボックス・レイアウト
  • グリッド・レイアウト
  • position プロパティ(fixed、absolute が指定されている)
  • 親要素に border が指定されている
    (border-top 指定 → margin-top は相殺なし)
    (border-bottom 指定 → margin-bottom は相殺なし)
  • 親要素に padding が指定されている
    (padding-top 指定 → padding-top は相殺なし)
    (padding-bottom 指定 → padding-bottom は相殺なし)
  • 親要素の heigh に数値が指定されている場合、margin-bottom は親要素のものが採用される
    (heigh: auto の場合、相殺が起こる)

margin の相殺の特殊ケース: 空要素

空要素(コンテンツの高さがゼロ)の場合のみ、margin の相殺は特殊です。

  1. まず、空要素の中の margin-top と margin-bottom の間で相殺が起こります。大きい方が採用されます。
  2. 次に、空要素と隣接する要素との間に相殺が起こります。上の要素の margin-bottom、下の要素の margin-top、空要素の margin で一番大きいものが採用されます。

【CSS】メディアクエリを使ってレスポンシブWebを作る

HTML CSS Logo

メディアクエリと、Flexboxを使って、PC・タブレット・スマホと、3段階の画面サイズに合わせてレスポンシブWebを作ってみました。
サンプルページ:https://exp.hazu.jp/media-query/media-query.html
仕組みをまとめてみたいと思います。

どのように表示させたいのか

スマホ縦 → 1カラン
スマホ横・タブレット縦 → 2カラン
タブレット横・PC → 3カラン

ディバイスによるブレイクポイント

3段階の画面サイズに合わせて切り替えたいのですが、ブレイクポイントは何ピクセルにするのか、というのが問題ですね。Googleのディベロッパーツールによれば、こうなっています。
(以下の単位はCSS で利用する「CSS ピクセル」で「画面解像度」ではありません。iOS では「csspx」、Android では「dp」。)

スマートフォン

対応 横幅 高さ
iPhone 5/SE 320 568
iPhone 6/7/8 375 667
iPhone 6/7/8 Plus 414 736
iPhone X 375 812
Android(ほとんどのスマホ) 360 640

タブレット

端末 横幅 高さ
iPad 768 1024
iPad Pro 1024 1366
Android Sサイズ 600 960
Android Mサイズ 768 1024
Android Lサイズ 800 1280

これより、こんな3段階にしてみました。

メディアクエリ区分け(width)

スマホ縦: ~499px
スマホ横+タブレット縦: 500px ~ 800px
タブレット横+PC: 801px~

メディアクエリ

< HTMLのメタ情報 >
まず、HTML の<head>の部分で、で、「ビューポート=ディバイスの画面サイズ」になるように指示します。
(「ビューポート」については、前回、まとめました。→ 【CSS】よく使う単位 & ビューポート単位

<meta name="viewport" content="width=device-width,initial-scale=1">

< メディアクエリの書き方 >
CSS のメディアクエリを利用して、ブレイクポイントごとに条件分けしていきます。

@media screen and (max-width:499px) { /* 1カランになるよう記述 */ }
@media screen and (min-width:500px) and (max-width:800px) { /* 2カランになるよう記述 */ }
@media screen and (min-width:801px){ /* 3カランになるよう記述 */ }

< CSS例 >

/* スマホ縦対応 1カラン */
@media screen and (max-width:499px) { 
.flex-container {
	display: -webkit-box;
	display: -ms-flexbox;
	display: flex;
	-webkit-box-orient: vertical;
	-webkit-box-direction: normal;
	-ms-flex-direction: column;
	flex-direction: column;	
	-ms-flex-wrap: wrap;
	flex-wrap: wrap;
}

.item {
	width: 100%;
}
}

/* スマホ横&タブレット縦対応 2カラン */
@media screen and (min-width:500px) and (max-width:800px) {
.flex-container {
	display: -webkit-box;
	display: -ms-flexbox;
	display: flex;
	-webkit-box-orient: horizontal;
	-webkit-box-direction: normal;
	-ms-flex-direction: row;
	flex-direction: row;
	-ms-flex-wrap: wrap;
	flex-wrap: wrap;
}

.item {
	width: 50%;
}
}

/* タブレット横&PC対応 3カラン */
@media screen and (min-width:801px){
.flex-container {
	display: -webkit-box;
	display: -ms-flexbox;
	display: flex;
	-webkit-box-orient: horizontal;
	-webkit-box-direction: normal;
	-ms-flex-direction: row;
	flex-direction: row;
	-ms-flex-wrap: wrap;
	flex-wrap: wrap;
}

.item {
	width: 33.3%;
}
}

【CSS】よく使う単位 & ビューポート単位

HTML CSS Logo

最近よく見かけるビューポート単位。ビューポートという概念自体もなんとなくしか分かっていないので、前から CSS でよく使われている単位と一緒にまとめてみます。

絶対的な単位

単位 説明 ピクセル換算
in 1インチ = 2.54センチメートル 96px
cm 1センチメートル = 10ミリメートル 約37.80px
mm ミリメートル 約3.78px
pt 1ポイント = 1/72インチ 約1.33px
pc 1パイカ = 12ポイント 16px
px ピクセル 1px

文字に使われる相対的な単位

単位 説明
em 親要素のフォントサイズが基準
rem ルート要素(普通はHTML)のフォントサイズが基準
% その要素のサイズが基準
ex その要素の小文字「x」の高さが基準
ch その要素の数字「0」の幅が基準

ビューポートを基準にした相対的な単位

ビューポートとは:ブラウザが Web ページをレンダリングする際に想定する仮想的な「表示領域」

っていうことなんですが、分かりづらいですよね。色々調べたんですが、こんな感じかと思います。
(以下の「px」は「画面解像度」ではありません。CSS で利用する「CSS ピクセル」です。)

  1. ビューポートの幅 500px と設定したとする。仮想で500pxのウィンドウでレタリングしますよーということ。
  2. 実際の画面幅が、500pxより大きければ、拡大されて表示される。
  3. 実際の画面幅が、500pxよりちいさければ、縮小されて表示される。

色々試して見たのですが、色々な条件が絡み合って、必ずしもそうとは言えないのですが、ざっくりとした考え方としてはそんな感じです。

ビューポートは HTML の head の meta 要素で指定します。ビューポート幅 500px の場合はこうなります。

<meta name="viewport" content="width=500">

仕組みとしてはこうなんですが、レスポンシブ Web デザインを考える場合、ディバイスの画面サイズに合わせて、ビューポートを合わせる、というのが理想になります。

<meta name="viewport" content="width=device-width,initial-scale=1">

width=divice-width」と指定することで、ディバイスの画面サイズに合わせて、ビューポートの幅をフレキシブルに変化させる、ということになります。

ビューポートがフレキシブルに変化するとなると、それぞれの要素の大きさも、相対的に変化します。そこで、ビューポートの幅や高さを基準とした、相対的な単位を利用する方がいいのではないか、という考えに基づいて利用されるのが、「ビューポートを基準にした相対的な単位」とういうことになります。

単位 説明
vw ビューポートの幅に対する1/100の単位
vh ビューポートの高さに対する1/100の単位
vmin ビューポートの幅と高さのうち、小さい方の値に対する1/100の単位
vmax ビューポートの幅と高さのうち、大きい方の値に対する1/100の単位

【CSS】overflow-wrap (word-wrap) と word-break の違い

HTML CSS Logo

HTMLで文章を書く場合、表示範囲の一番最後まで来た時の改行は、何も指定していない場合、以下の通りです。

日本語:単語の途中であろうと、自動改行(禁則処理あり)
英数字(適当なスペースあり):スペースに合わせて自動改行(禁則処理あり)
英数字(表示範囲を超える連続する長いもの):改行されずはみ出す

特に、この長い英数字の改行を制御するのに便利な CSSプロパティ、overflow-wrap (word-wrap) と word-break 、違いは何なんでしょう?

word-break : 表示範囲最後まで来た時、(単語が長かろうが短かろうが)単語の途中で改行させるかどうか

overflow-wrap (word-wrap) : 表示範囲に収まらない長い連続する文字列を、途中で改行させるかどうか

(②ですが、word-wrap が古い名称で、サポートされていないブラウザもあるため、新しい名称の overflow-wrap と併記した方がいいようです。)

↓このような文字列がどのように表示されるか、それぞれ見ていきます。

例)CSSで改行が指定されていないデフォルト

word-break プロパティ

word-breakは3つの値(normal, break-all, keep-all)が取れます。

1.word-break: normal
デフォルトと同じです。

2.word-break: break-all
表示範囲を超える長さの英数字の文字列、適当なスペースの入っている短い文字列、どちらにしろ、範囲に収まるように、単語の途中で自動改行
されます。
日本語はデフォルトと同じく、単語の途中で自動改行されます。

3.word-break: keep-all
表示範囲を超えたとしても、決められた場所でしか改行しません。
英数字: 「スペース(空白)」「?」「-」
日本語: 「句読点(、。)」「スペース(空白)」「?」「-(全角ハイフン)」

overflow-wrap (word-wrap) プロパティ

overflow-wrap は2つの値(normal, break-word)がとれます。

1.overflow-wrap: normal
デフォルトと同じです。

2.overflow-wrap: break-word
表示範囲を超える長いの英数字の文字列: 範囲に収まるように、単語の途中で自動改行
適当なスペースの入っている短い英数字の文字列: 単語の切れ目で自動改行
日本語はデフォルトと同じく、単語の途中で自動改行されます。

overflow-wrap (word-wrap) が効かない場合

一般的な文章なら、overflow-wrap: break-word が一番利用しやすい感じがしますが、「内容が定まるまで幅の決まらない要素」がある場合、効きません。

1.shrink-to-fit width
Flexbox(親要素が display:flex)や、display:inline-block、float、position:absolute は、内容によって幅が決まるので、自動改行が効いていないように振る舞います。
→ 回避策 width:auto になっているので、幅(width)や最大幅(max-width)を明示する。

2.テーブル
テーブルの親要素(table-layout:auto)、子要素(display:table-cell)の場合、子要素に overflow-wrap: break-word を指定しても自動改行が無視されます。
→ 回避策 親要素に対して、固定レイアウトアルゴリズム table-layout:fixed を指定する。