- ベストアンサー
CSSの継承
HTMLに挑戦してから1年が経ちます。 少しずつ勉強してようやく形になってきましたが 継承のことについてよく分からないままきたので質問いたします。 スタイルシートの本には継承されない属性の方が多く書かれています。 例えば代表的なbackground-colorとかがありますが、 私のパソコンでは何故か継承されてしまっているようなのです。 環境はWindowsXP Pro、ブラウザはIE6で試しています。 例えば以下のようなソースです。これをコピペでメモ帳に貼り付けて下さればテストできます。 継承されないのなら<P>タグの背景色は初期値の白のままだと思います。 これって私の継承の理解が間違っているんでしょうか。 それとも他に原因があるのでしょうか。未だに謎なのでよろしくお願いします。 <style type="text/css"> <!-- div {background-color:red} --> </style> <div>aaa <p>継承していません</p> aaa</div>
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
ANo.4様のご説明の通りなのですが、以下の様に考えたらわかりやすいかも知れません。 ※ちょっと実際のイメージがないと説明しにくいので、テキストだけの簡略図でもイメージが伝えやすいmargine-leftプロパティの方で代用させて頂きました。あくまでテキストでの図なのでボックスの多少のガタガタは無視して下さい。 【CSS】 div { margin-left: 100px; } 【HTML】 <div>aaa <p>継承していません</p> aaa</div> 上記の場合は、下記の様な感じで見えていますよね。線内がdivの領域だとします。 【A1】 ----------------------------------------------- |aaa(左マージン100px) |継承していません(左マージン0) |aaa(左マージン100px) ----------------------------------------------- <div>の直下に納められている"aaa"と子要素pの中の"継承していません"の「見た目上の」左マージンが「揃って」いる状態なのが、質問者様のお考えだとおそらく腑に落ちないのでは?子要素pが左マージンを継承していないのであれば下記の様に表示されるべきでは、と思ってらっしゃいませんか? 【A2】 ----------------------------------------------- |aaa(左マージン100px) 継承していません(左マージン0) |aaa(左マージン100px) ----------------------------------------------- しかし、仮に上記の様にレンダリングされるとなると、divの子要素である筈のpの領域が親要素divのボックスを越えてはみ出していることになります。子要素が親要素のボックスの領域をはみ出して見える様なレイアウト及びその様に指定するプロパティもありますが、その名称の示す通り子要素は親要素の中で表示領域が展開するのが基本です(勿論、ANo.4様も書かれた通り「親要素が子要素に依存」する仕様もありますが、今回の説明ではその事についてはとりあえずあまり深く考えないで下さい。)。 マージン(ボックスの外側の余白)よりパディング(ボックスの内側の余白)の方が概念が理解しやすいかと思いますので、次はそれで説明してみます。 【CSS】 div { padding-left: 100px; } 上記のスタイルであれば以下の様に見えますよね。 【B1】 ---------------------------------------------------- | aaa(左パディング100px) | 継承していません(左パディング0) | aaa(左パディング100px) ---------------------------------------------------- もしも、このpadding-leftが継承される仕様だとしたら、下記の様に表示されてしまうでしょう。 【B2】 ---------------------------------------------------- | aaa(左パディング100px) | 継承しています(左パディング0) | aaa(左パディング100px) ---------------------------------------------------- <p>~</p>の領域がaaaの箇所より更に(倍に)左余白ができてしまっています。何故かというと、子要素pのレンダリング領域は、親要素の左パディングの値100pxの位置を基点として既にそこから開始されているのに、更にpの内部でも左パディング100pxの余白が「継承」されて与えられてしまい、結果としてpの内包するデータ(この場合はテキスト)は親要素divからすると、合計で左から200pxの位置にある様に表示されてしまうわけです。 もしこういう仕様だったらスタイル設定の際の計算が大変ややこしくなっていきますよね?子要素が増えれば増えるほど、親要素の指定にいちいち遡って引き算してマイナス値を与えて子要素のプロパティを指定する事になり、大変煩雑です。 なので、【A1】【B1】の様に表示されている状態こそが「継承していない」状態なのです。
その他の回答 (5)
- abril
- ベストアンサー率69% (388/560)
蛇足ですが、もう一点だけ気になったので…ANo.3様の回答に対して以下の様にレスされていますが: > されます! 何という斬新な回答でしょう。 > されると分かれば私の悩みは解消です。 いえ、あくまで「継承」はされていません。CSSの仕様書にも明記されています。 ググって調べてみて下さい。CSSの仕様書の日本語訳等が沢山見つけられます。下記はその一例です。 http://www.y-adagio.com/public/standards/tr_css2/colors.html#q2 先に私や他の方が回答した通り、background-colorの場合は初期値が"transparent"だったから継承されている様に見えただけです。 ANo.3の方(は人一倍仕様書を引用される方なので、まさかそこを無視される様な事は仰らないと思います)が「あまり深く考えないで、常識的に継承します。」と書かれたのはそういう意味だったと私は解釈しております。 誤解されません様に…
お礼
再度の回答ありがとうございます。 実はこの質問の前までブラウザ側の機能拡張で 継承しないものも現実的には継承していると結論づけていました。 夏頃から散々考えてテストしても分からなかったので・・・ 自分の持っている本が少し昔の奴なのでIE6とか最新のブラウザは 色々と変わっているのかなと思って、その確認のための質問でした。 そうしたらbackground-colorの件は見事に看破されたので、 自分の考えがやはり勘違いしていそうだなとの考えに至りました。 しかし、たまたまかなとも思い納得できる状況でもなかったのでmargin-leftに話を振りました。 ここでも見事に論破されるに至り、やっと納得できました。 #3様は私の理想の回答に近かったので、 今後の回答によってどちらかを結論にしようと思っていた次第です。
<div> <p>継承していません</p> </div> htmlで上記のような場合、divという箱の中にpという箱が入っている状態になります。 marginのことを考える前に、pの横幅がどのようにして決まっているのかを考える必要があります。 pはブロック要素なので、ブロック要素の横幅は親要素の幅いっぱいにまで広がります。なので、marginやpaddingが効いていない状態では、pの幅はdivの幅と同じになりますし、divの幅はbody、bodyの幅はhtmlと同じになるので、結果pの箱の横幅はウインドウいっぱいの幅になると思います。 ここでdivにmarginを取ると、widthの指定されていない(autoの場合)divの幅は変わってしまうので、pの幅も変わるというわけです。 これだけで見ると子要素は親要素の設定に依存するようにも見えますが、例えばインライン要素の横幅だったり、ブロック要素の高さなどは親要素が子要素に依存します。
お礼
回答ありがとうございます。 十分に理解はしていないのですが、雰囲気は分かります。 結局、これも見かけ上は継承しているようにみえるということですね。 自動整形があったりtransparentであったりとちょっと想像できませんでした。 自分で考えていたら後1年は悩んだと思います。
- ORUKA1951
- ベストアンサー率45% (5062/11036)
継承されます。 あまり深く考えないで、常識的に継承します。 継承しないところで継承させたけれぱ、inheritプロパティを使えばよい。 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html lang="ja"> <head> <meta http-equiv="content-type" content="text/html; charset=Shift_JIS"> <title>Untitled</title> <meta http-equiv="Content-Style-Type" content="text/css"> <style type="text/css"> <!-- div.Main{ border: solid 1px red; } div.Main h2{ border:inherit; /* 継承されないbordeを継承させる。 */ width:80%; margin:auto; } --> </style> <title>サンプル</title> </head> <body> <h1>title</h1> <div class="Main"> <h2>テスト</h2> <p>内容</p> </div> </body> </html>
お礼
ご回答ありがとうございます。 されます! 何という斬新な回答でしょう。 されると分かれば私の悩みは解消です。 他の方はできないし、本にもできないと書いてあるので 現実の背景とか説明して下さると有り難いです。 inheritについては知っています。 今回は継承されないものはどうしても継承させたくないので それで質問しています。
backgroundの初期値は確かtransparent(透明)のはずです。 なのでp要素の背景色は透明のままで、divの背景色が見えていることになります。 継承とはあくまで値を継承するということなので、結果的な見栄えとは別になります。
お礼
回答ありがとうございます。 見かけ上そうなっているということは理解できました。 しかし、まだ謎は解けていません。 なぜなら継承しないといわれている多くの要素で継承されているように見えるからです。 No1の方の返信に少し詳しく書いておきましたので よろしければもう少しおつきあい下さい。
- abril
- ベストアンサー率69% (388/560)
これは、仕様上では「継承」しているわけではないんですよ。 ただ、background-colorプロパティの初期値は"transparent"(透過)の為、子要素にこのプロパティで新たに背景色を指定しない限りは、親要素で指定された背景色が「透けて」子要素に見えている状態なのです。 ですので、質問者様のサンプルですと、親要素であるdivに対して指定された背景色「赤」が、子要素pでは背景色が「透けている」為、結果としてあたかもpにもdivの背景色があたかも継承されたかの様に「赤」い背景に見えるわけです。 イメージとして赤い紙(div)の上に透明なフィルム(p)が重なっている様な状態を思い浮かべて下さい。p自身は透明なわけですが、下の赤い紙の色が透けている為にpにも色がついている様に見えますよね。そういう事です。 > <P>タグの背景色は初期値の白のままだと思います。 前述の通り、pに対して背景色を何も指定していないのであれば、初期値は"transparent"であって、決して「白」ではありません。おそらく質問者様はブラウザの背景色の初期設定を変更されてない状態で、その「ブラウザの背景色の初期設定の”白”」を「background-colorプロパティの初期値」と混同されているのではないでしょうか。 ですので、今回は「継承の理解が間違っている」というより、background-colorプロパティの初期値についての理解が間違っていたという事ですね。
お礼
ご回答ありがとうございます。 trasparentですか。ちょっと調べてみました。透過なんですね。 見かけ上継承されたように見えたが正解なんですか。 ちょっと例えが悪いのかなとも思いスタイルをmargine-rightに変更してみました。 margine-rightも本には継承されないとなっていますが、継承されているようにみえます。 よろしければもう少しおつきあい下さい。 <style type="text/css"> <!-- div {margin-right:100} --> </style> <div>aaa <p>継承していません</p> aaa</div>
お礼
大変分かり易い回答ありがとうございます。 ボックスと考えるイメージは全然ありませんでした! はみ出すと考えるとは、天地がひっくり返ったくらいに驚いています。 改めてHTMLの奥深さを思い知らされました。 なんかパズルみたいですね。