クリックジャッキングの本質的な解決策
誰か書いてそうだけど、気にせずに投下
CSS での解決策
具体的には、以下のルールをユーザースタイルシートに追加すればいい。
* { opacity: 1 !important }
CSS2, CSS2.1, CSS3 では、ユーザースタイルシートの !important な宣言は他のどの宣言よりも優先されるはずなので、ちゃんと仕様を満たしているブラウザを使っていれば問題ないはず。
(IE の場合は、 opacity じゃなくて filter を。。というか、オプションで何か filter とか無効に出来た気がするけど、忘れた><)
ユーザースタイルシートは、 IE, Firefox, Opera, Safari ほとんどのブラウザで使うことができる。
あと、 iframe の大きさを制限しておくとさらに良いかもしれない。
iframe { min-height: 200px !important; min-width: 200px !important }
ただ
すべての要素が透明にできなくなってしまうのは寂しいなあ。。。
ちなみに
iframe { opacity: 1 !important }のように iframe だけにターゲットを絞ることはできない。親要素や祖先要素が透明になる可能性があるから。
追記
でも、よく考えると iframe の上に div やら何やらを載せてボタン意外を隠してしまうという手もあるなあ。ボタンは見えてるんだけど、ボタンの名前が「送信」とかだったら分からないな。
やっぱ、 CSS オフか iframe { display: none !important } が本質的なのかなあ。やっぱり現実的ではないな。
CSS のセレクタの名前の整理
はじめに
「CSS のセレクタ」っていうと以下のようなものを想像すると思うんですけど
div.container ul > li
じゃあ、
などなど色々と疑問が出てくる訳で、どういう名前で呼べばいいか。自分のために書いておく。
これ系のエントリでは、以下のエントリが一番参考になります
http://d.hatena.ne.jp/kiririmode/20080516/p1
Selector
カンマで区切られてる一個一個のやつ
div.container ul > li
とか
div#hoge.hoge ~ span#fuga.fuga
Combinator
>
とか
+
とか
~
空白とか
Sequence of simple selectors
Combinator で区切られてる一個一個のやつ
div.container
ul
li
div#hoge.hoge
span#fuga.fuga
Simple selector
div#hoge.hoge
でいうと
div
#hoge
.hoge
あと
Combinator と Sequence of simple slectors を組み合わせた
~ span#fuga.fuga
とか
> li
みたいなものにも名前が欲しいなあ。プログラムではこの単位で扱うことが多いので。
Combinator and sequence of simple seletors とでも読んでおくか。
うーん
JavaScript でこれを扱うオブジェクトを作るときは
var caoss = new CSSCombinatorAndSequenceOfSimpleSelectors();
とかになるのかな><長い><
カオス><
IE で一時的に要素のスタイルを変更する
いろいろためしたけど、以下が一番楽
// 変更 element.runtimeStyle.cssText = ' width: 100%; height: 100%'; // 戻す element.runtimeStyle.cssText = '';
CSS Selector の最大の欠点
先頭に Combinator を置けないこと
// 以下のようなことができない elm.querySelectorAll('> div'); elm.querySelectorAll('+ div'); elm.querySelectorAll('~ div');
Selector が仕様化されたときは、たぶん、サブツリーを起点に使われることなんて想像してなかったんだろうなあ。
その点、 jQuery はすごいなあ。
Web 標準的な CSS の値変換方法(px → em など)(訂正あり)
はじめに
W3C の仕様に CSS の値を変換が可能なオブジェクトが定義されていることに気がついたのでメモしておきます。
まず CSSStyleDeclaration オブジェクトを取得する
例えば、
var decl = element.style;
または、
var decl = getComputedStyle(element, '');
http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSStyleDeclaration
CSSStyleDeclaration オブジェクトから getPropertyCSSValue という関数を使って CSSValue オブジェクトを取得する
var val = decl.getPropertyCSSValue('width')
http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSValue
以下のようにして様々な単位の値が取得できる
ただし、 CSSValue が CSSPrimitiveValue の場合だけ
if (!(val instanceof CSSPrimitiveValue)) throw Error(); // センチメートル単位で値を取得 var num = val.getFloatValue(CSSPrimitiveValue.CSS_CM);
http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSPrimitiveValue
訂正
ちゃんと仕様のほうを確認してみました。
すると、以下のように記述されていました。
Conversions are allowed between absolute values (from millimeters to centimeters, from degrees to radians, and so on) but not between relative values. (For example, a pixel value cannot be converted to a centimeter value.)
http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSPrimitiveValue
絶対値間の変換は認められるが、相対値の変換は認められない。
ということは、どうやら WebKit の独自拡張ということなんですね。
WebKit--
めも
このメモについて
- id:amachang の私的な学習目的
- IE6 の標準モードに関するバグ
いろいろとポイント
- layout
- IE6 の視覚整形モデルの中で要素は、大きく分けて layout を持つ要素と、 layout を持たない要素に分けることができる。
- layout を持つ要素とは、自分のサイズや位置に責任を持つ要素である。
- layout を持つ要素は、四角形の領域を作る。
- layout を持たない要素は、直近の layout を持つ要素のサイズおよび位置と、そこの間にあるすべての要素の margin, padding, border によってその開始点、折り返し点が決まる。
- layout を持たない要素は、四角形の領域を作らない。上下左右の間隔を保持しているだけに過ぎない。
- layout を持たない要素間の上下マージン(相殺されるマージン)は二つの要素間の共有のもので、ある要素特有の管理下にはない。(つまり、要素のレンダリングのバグを直したいときにマージンは影響しないことが多い)
- 要素に layout を与える場合は style に zoom: 1 を指定すればいい
(border-left または border-right) と padding-bottom の問題
以下の HTML によって発生する
http://amachang.art-code.org/ierendering/000.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <title>IE Rendering Test</title> </head> <body> <!-- border-left と padding-bottom を持つ layout を持たないブロックレベル要素 --> <div style="border-left: 1em solid blue; padding-bottom: 1px;"> <div>ほげほげほげほ</div> <div>ほげほげほげほ</div> <div>ほげほげほげほ</div> <!-- この要素の最後に layout を持たないブロックレベル要素 --> <div>layout を持たないブロックレベル要素</div> </div> <!-- この要素が 2em (ボーダーの幅 x 2)だけずらされる --> <div>ずれてますか?</div> </body> </html>
ずれないパターン 1
http://amachang.art-code.org/ierendering/001.html
<body> <div style="border-left: 1em solid blue; padding-bottom: 1px;"> <div>ほげほげほげほ</div> <div>ほげほげほげほ</div> <div>ほげほげほげほ</div> <!-- この最後の要素をインライン要素にする --> <span>layout を持たないブロックレベル要素</span> </div> <!-- ずれない --> <div>ずれてますか?</div> </body>
ずれないパターン 2
http://amachang.art-code.org/ierendering/002.html
<body> <div style="border-left: 1em solid blue; padding-bottom: 1px;"> <div>ほげほげほげほ</div> <div>ほげほげほげほ</div> <div>ほげほげほげほ</div> <!-- この最後のノードをテキストノードにする --> テキストノード </div> <!-- ずれない --> <div>ずれてますか?</div> </body>
ずれる幅が違うパターン 1
http://amachang.art-code.org/ierendering/003.html
<body> <div style="border-left: 1em solid blue; padding-bottom: 1px;"> <div>ほげほげほげほ</div> <div>ほげほげほげほ</div> <div>ほげほげほげほ</div> <!-- border-bottom を付ける --> <div style="border-bottom: 1px solid blue;">layout を持たないブロックレベル要素</div> </div> <!-- 2em ではなくて 1em しかずれない --> <div>ずれてますか?</div> </body>
ずれる幅が違うパターン 2
http://amachang.art-code.org/ierendering/004.html
<body> <div style="border-left: 1em solid blue; padding-bottom: 1px;"> <div>ほげほげほげほ</div> <div>ほげほげほげほ</div> <div>ほげほげほげほ</div> <!-- padding-bottom を付ける --> <div style="padding-bottom: 1px;">layout を持たないブロックレベル要素</div> </div> <!-- 2em ではなくて 1em しかずれない --> <div>ずれてますか?</div> </body>
ずれないパターン 3
http://amachang.art-code.org/ierendering/005.html
<body> <!-- border-bottom を追加 --> <div style="border-left: 1em solid blue; border-bottom: 1px solid blue; padding-bottom: 1px;"> <div>ほげほげほげほ</div> <div>ほげほげほげほ</div> <div>ほげほげほげほ</div> <div>layout を持たないブロックレベル要素</div> </div> <!-- ずれない --> <div>ずれてますか?</div> </body>
ずれないパターン 4
http://amachang.art-code.org/ierendering/006.html
<body> <!-- layout を与える --> <div style="zoom: 1; border-left: 1em solid blue; padding-bottom: 1px;"> <div>ほげほげほげほ</div> <div>ほげほげほげほ</div> <div>ほげほげほげほ</div> <div>layout を持たないブロックレベル要素</div> </div> <!-- ずれない --> <div>ずれてますか?</div> </body>
ずれないパターン 5
http://amachang.art-code.org/ierendering/007.html
<body> <div style="border-left: 1em solid blue; padding-bottom: 1px;"> <div>ほげほげほげほ</div> <div>ほげほげほげほ</div> <div>ほげほげほげほ</div> <!-- layout を与える --> <div style="zoom: 1">layout を持つブロックレベル要素</div> </div> <!-- ずれない --> <div>ずれてますか?</div> </body>
ずれる幅が違うパターン 3
http://amachang.art-code.org/ierendering/008.html
<body> <div style="border-left: 1em solid blue; padding-bottom: 1px;"> <!-- からっぽ --> </div> <!-- 1em ずれる --> <div>ずれてますか?</div> </body>
はみ出した箇所が表示されない問題
http://cssbug.at.infoseek.co.jp/detail/winie/b025.html
http://cssbug.at.infoseek.co.jp/detail/winie/b041.html
http://cssbug.at.infoseek.co.jp/detail/winie/b046.html
実際の例と回避
http://amachang.art-code.org/ierendering/009.html
<body> <div style="zoom:1; border: 1px solid blue; margin: 2em;"> あああ <div style="border: 1px solid red">端っこ見えてます?</div> あああ <div style="margin: 0 -1em; border: 1px solid red">端っこ見えてます?</div> あああ <div style="zoom: 1; margin: 0 -1em; border: 1px solid red">端っこ見えてます?</div> あああ <div style="position: relative; margin: 0 -1em; border: 1px solid red">端っこ見えてます?</div> あああ <div style="zoom: 1; position: relative; margin: 0 -1em; border: 1px solid red">端っこ見えてます?</div> あああ </div> <div style="zoom:1; border: 1px solid blue; margin: 2em;"> あああ <div style="margin: -2em 0 0; border: 1px solid red">端っこ見えてます?</div> </div> <div style="zoom:1; border: 1px solid blue; margin: 2em;"> あああ <div style="zoom: 1; margin: -2em 0 0; border: 1px solid red">端っこ見えてます?</div> </div> <div style="zoom:1; border: 1px solid blue; margin: 2em;"> あああ <div style="position: relative; margin: -2em 0 0; border: 1px solid red">端っこ見えてます?</div> </div> <div style="zoom:1; border: 1px solid blue; margin: 2em;"> あああ <div style="zoom: 1; position: relative; margin: -2em 0 0; border: 1px solid red">端っこ見えてます?</div> </div> <div style="border: 1px solid blue; margin: 2em;"> あああ <div style="border: 1px solid red">端っこ見えてます?</div> あああ <div style="margin: 0 -1em; border: 1px solid red">端っこ見えてます?</div> あああ <div style="zoom: 1; margin: 0 -1em; border: 1px solid red">端っこ見えてます?</div> あああ <div style="position: relative; margin: 0 -1em; border: 1px solid red">端っこ見えてます?</div> あああ <div style="zoom: 1; position: relative; margin: 0 -1em; border: 1px solid red">端っこ見えてます?</div> あああ </div> <div style="border: 1px solid blue; margin: 2em;"> あああ <div style="margin: -2em 0 0; border: 1px solid red">端っこ見えてます?</div> </div> <div style="border: 1px solid blue; margin: 2em;"> あああ <div style="zoom: 1; margin: -2em 0 0; border: 1px solid red">端っこ見えてます?</div> </div> <div style="border: 1px solid blue; margin: 2em;"> あああ <div style="position: relative; margin: -2em 0 0; border: 1px solid red">端っこ見えてます?</div> </div> <div style="border: 1px solid blue; margin: 2em;"> あああ <div style="zoom: 1; position: relative; margin: -2em 0 0; border: 1px solid red">端っこ見えてます?</div> </div> </body>
float の clear と background の問題
layout を持たない親要素の中で float を clear すると背景が margin 領域まで広がる。そして、自分の兄要素の layout を持たないものが消える(消えると言っても実際に消えるわけではなく、「再描画」が伝搬しなくなる。スクロールによって出現する)
この消え方を Peek-a-boo というらしい
http://amachang.art-code.org/ierendering/010.html
<body> <div style="margin: 1em; background: gray;"> <div>あああ</div> <div style="position: relative">いいい</div> <div style="zoom: 1">ううう</div> <div style="zoom: 1; position: relative">えええ</div> <div style="float: right">おおお</div> <div style="clear: right">かかか</div> <div>あああ</div> <div style="position: relative">いいい</div> <div style="zoom: 1">ううう</div> <div style="zoom: 1; position: relative">えええ</div> <div style="float: right">おおお</div> <div style="clear: right">かかか</div> <div>あああ</div> <div style="position: relative">いいい</div> <div style="zoom: 1">ううう</div> <div style="zoom: 1; position: relative">えええ</div> </div> <div style="margin: 1em; zoom: 1; background: gray;"> <div>あああ</div> <div style="position: relative">いいい</div> <div style="zoom: 1">ううう</div> <div style="zoom: 1; position: relative">えええ</div> <div style="float: right">おおお</div> <div style="clear: right">かかか</div> <div>あああ</div> <div style="position: relative">いいい</div> <div style="zoom: 1">ううう</div> <div style="zoom: 1; position: relative">えええ</div> <div style="float: right">おおお</div> <div style="clear: right">かかか</div> <div>あああ</div> <div style="position: relative">いいい</div> <div style="zoom: 1">ううう</div> <div style="zoom: 1; position: relative">えええ</div> </div> <div style="margin: 2em; background: gray;"> <div>あああ</div> <div style="position: relative">いいい</div> <div style="zoom: 1">ううう</div> <div style="zoom: 1; position: relative">えええ</div> <div style="float: right">おおお</div> <div style="clear: right"></div> </div> <div style="zoom:1; margin: 2em; background: gray;"> <div>あああ</div> <div style="position: relative">いいい</div> <div style="zoom: 1">ううう</div> <div style="zoom: 1; position: relative">えええ</div> <div style="float: right">おおお</div> <div style="clear: right"></div> </div> <div style="margin: 2em; background: gray;"> <div>あああ</div> <div style="position: relative">いいい</div> <div style="zoom: 1">ううう</div> <div style="zoom: 1; position: relative">えええ</div> <div style="float: right">おおお</div> <div style="clear: right"></div> </div> </body>
基本的には以下の有名なバグも仕組みは同じ
http://www.positioniseverything.net/explorer/peekaboo.html
http://amachang.art-code.org/ierendering/011.html
<body> <div style="background: gray"> <div style="height: 20em; float: left"> <br /> <span> Float <br /><br /> <a href="#"> test link </a> </span> </div> This is bare text. <a href="#">Test link</a> <div style="border: 3px solid #f00; background: #dde;">This is text inside a div. <a href="#">Test link</a></div> This is bare text. <a href="#">Test link</a> <div style="border: 3px solid #0c0; background: #dde;">This is text inside a div. <a href="#">Test link</a></div> This is bare text. <a href="#">Test link</a> <div style="border: 3px solid #00f; background: #dde;">This is text inside a div. <a href="#">Test link</a></div> This is bare text. <a href="#">Test link</a> <div style="clear: left">Clearing div</div> <div style="border: 3px solid #00f; background: #dde;">This div is after the cleared div. (purple box) If cleared div does not touch float, bug is not triggered. <a href="#">Test link</a></div> </div> </body>
float よりも clear が原因
float というよりもボックス内で clearance マージンが設定されたかどうかで発生するかが決まる。
たとえば、コンテンツを文字で満たして float 要素を囲み、 clearance マージンの設定が必要のない状態にするとこの問題は発生しない。( clear を指定した要素の margin-top を clearance よりも大きくしてもこの問題は発生しない)
あと、 clearance マージンより下方向にコンテンツがない場合は、 Peek-a-boo は起きない。
重要なことは、 clearance マージンと non-layout なブロックの背景。