ラベル クロスブラウザ の投稿を表示しています。 すべての投稿を表示
ラベル クロスブラウザ の投稿を表示しています。 すべての投稿を表示

2015年12月5日

Firefox のボタン(<button>, <input type=button>)の大きさ(幅・高さ)が違う場合の対処法

width や height を指定せず、padding や内部の文字列で大きさを確保するボタン(<button> や <input type="button">)では、IE/Chrome と比べて Firefox のボタンサイズが大きくなる。
文字の幅は、同じフォントを指定してもブラウザによって異なるのが普通だが(レンダリングエンジンが異なるため)、Firefox のみ明らかに大きくなる。

[問題になる CSS の例]

button {
    padding: 5px;
    border: 1px solid lime;
    letter-spacing: 0px;

    /* ブラウザ間の差が少ないメイリオを使用 */
    font: 15px/22px Meiryo;
    cursor: pointer;
}
[プレビュー]
[開発者ツールの画面キャプチャ]
IE Chrome Firefox (Firebug)
IE button inspection Chrome button inspection Firefox button inspection
※ Firefox のボタンサイズが、縦方向 2px、横方向 6px 大きい。

原因と対処法

困った時の stackoverflow。
Firefox はボタンフォーカス時の点線の幅と padding が確保されているため、他のブラウザより大きくなるのだとか。
これ → Firefox focused button

[ボタンフォーカスの点線を消す CSS]

button::-moz-focus-inner {
    padding: 0;
    border: 0;
}
/* input[type=button] なども同様に指定可能 */
[プレビュー]
[Firebug の画面キャプチャ]
Firefox button inspection

ボタンフォーカスの点線を消したくない場合、margin を工夫することで大きさを合わせることが可能。

button::-moz-focus-inner {
    padding: 0;
    margin: -1px; /* 点線の幅分のマイナスマージン */
}

ただし、最初にも書いたが、ブラウザによる文字の幅の差はどうすることもできないので、ボタンの大きさ完全に一致させたい場合は、button の width を指定するしかない。

検証環境

  • Windows 7 64bit
  • Internet Explorer 11
  • Firefox 42.0
  • Chrome 48.0.2564.8

2015年11月19日

<iframe> を動的生成する際の注意点

javascript で src 無しの <iframe> とその中身を構築した際、はまったことがあったのでメモ。

  • 動的に追加した <iframe> の中身をいじる際は、
    iframe.contentWindow.documentdocument.write() を使う
    または
    <iframe> のロード完了を待つ。(<iframe> 自身に onload イベントがある)
  • <iframe> に onload イベントを設置する際は、DOM への追加前に行う。
    DOM に <iframe> を追加した瞬間、onload イベントが処理されるブラウザがあるため (Chrome)

[サンプルコード]

// 単純化のため、jquery 使用

// 良い例
// IE:OK / Firefox:OK / Chrome:OK
$(function(){
    $('<iframe>').load(function(){
        // ロード完了後、DOM を変更できる。
        var ibody = this.contentWindow.document.body;
        $(ibody).append('<div>ブロック要素</div>');
    }).appendTo('body');
    // イベント設置後に DOM へ追加
});


// 悪い例(1)
// IE:OK / Firefox:NG / Chrome:OK
// Chrome は iframe の DOM 追加後、即時ロード完了する模様
// IE は iframe のロード完了を待たなくても大丈夫っぽい??
$(function(){
    var iframe = $('<iframe>').appendTo('body');
    var ibody = iframe[0].contentWindow.document.body;
    $(ibody).append('<div>ブロック要素</div>');
});


// 悪い例(2)
// IE:OK / Firefox:OK / Chrome:NG
// Chrome は iframe が即時ロード完了するので、DOM 追加後に load イベントを付けても無意味
$(function(){
    var iframe = $('<iframe>').appendTo('body');
    iframe.load(function(){
        var ibody = this.contentWindow.document.body;
        $(ibody).append('<div>ブロック要素</div>');
    });
});
[環境]
  • Windows 7 64bit
  • Internet Explorer 11
  • Firefox 42.0
  • Chrome 48.0.2564.8

2015年3月19日

IE10 table に colspan を指定するとカラムの下線が消えるバグ

検索でもたくさん引っかかる割と有名なバグ。
今更という気もするが、自分も遭遇したため、現象と解決手段をまとめておく。

発生条件(AND)
  • IE10 実機
  • ドキュメントモード: 標準 / Quirks / Internet Explorer 9 標準 / Internet Explorer 8 標準
  • table に { border-collapse: collapse; } を指定
  • td と th に 0 でない border-bottom を指定
  • td または th に 2 以上の colspan を指定

現象が発生するコードと画面キャプチャ。
[CSS]

table { border-collapse: collapse; width: 400px; }
td, th { border: 1px solid black; }
[HTML]

<table>
    <tr>
        <th>col</th>
        <th>col</th>
        <th>col</th>
    </tr>
    <tr>
        <td colspan=3>col3</td>
    </tr>
</table>
[画面キャプチャ]
IE10 table border bug image

常に発生するわけでもなく、画面の再描画で正常に表示されたりする。
開発者ツールを使うと再描画が走るので調査できなかったり・・・

解決手段

発生条件からどれか 1 つを取り除けば、現象は発生しない。
「IE10 を使わない」が理想だけど、実際はドキュメントモードを変更または CSS で何とかすることになると思う。

上のコードに対する CSS による解決例。
※ CSS ハックなどで、IE10 にだけ下記を適用
 (全ブラウザに対して適用してもコードが特殊になるだけで害はないはず・・)

/* カラムの下線を 0 に指定 */
td, th { border-bottom: 0 none; }

/* 代わりに table の下線を指定 */
table { border-bottom: 1px solid black; }

/* または、tr でも可能 (tr の border は IE8以降で有効) */
tr { border-bottom: 1px solid black; }

IE お得意の条件付きコメントは IE10 から廃止されているため、IE10 のみ適用する場合は CSS ハックまたは javascript に頼るしかない。
まだバグが残ってるのに・・・

2014年6月7日

IE9.js(ie7-js) でスタイルシートの解析を部分的に無視

記事タイトルのような機能が無かったため、機能追加したものを作成。
https://bitbucket.org/temp_impl/ie9-js/src

オリジナルとの差分
https://bitbucket.org/temp_impl/ie9-js/commits/124d43c6f6d12327aa0c8e20775ba6a106ea2de0

使用方法

<style> や <link> に class="ie9js-ignore" を付けると、スタイルシート解析の対象外になる。
「class に 対象クラス名が含まれているか」で判定しているので、クラス名が複数あってもOK。

<html>
<head>
<!-- スタイルシート解析から無視される -->
<link type="text/css" rel="stylesheet" href="style.ignore.css" class="ie9js-ignore" />
<style type="text/css" class="ie9js-ignore">
div > div:first-child {
    background-color: cyan;
}
</style>

<!-- スタイルシート解析される -->
<link type="text/css" rel="stylesheet" href="style.css" />
<style type="text/css">
div > div:last-child {
    background-color: yellow;
}
</style>

<!--[if lt IE 9]>
<script src="IE9.min.js"></script>
<![endif]-->
</head>

<body>
  <div>
    <div>first</div>
    <div>last</div>
  </div>
</body>
</html>

使いどころ

対象ブラウザ(IE7/IE8)で元から使えるスタイルシートは解析させる必要がないので無視できる。
解析されて javascript 適用のスタイルシートになると、そのままでは DHTML で使えないなどの問題が起こったりする。

また、ファイルサイズが大きい css を無視できると、当然レスポンスが良くなる。
IE7/IE8 に対応している jquery-ui の css など。

2014年5月31日

IE9.js(ie7-js) を DHTML でも使用する方法

IE9.js(ie7-js) は便利だが、画面表示後に変更された HTML(いわゆる DHTML・動的 HTML)に対してスタイルが適用されないことがある。

理由は単純で、主に擬似要素などブラウザが対応していないスタイルシートを javascript により適用しているためである。
javascript によるスタイル適用は画面ロード時の 1 回だけになり、後から変更された HTML に対しては何もできない。

そこで、スタイルを再適用させるための関数 IE7.recalc() が存在する。
IE9.js + DHTML でスタイルシートが適用されない場合は試してみる価値あり。
主に擬似要素を使ってるスタイルで有効。

使用例


<html>
<head>
<style type="text/css">
div > div:first-child > span {
    background-color: cyan;
}
</style>
<!--[if lt IE 9]>
<script src="http://ie7-js.googlecode.com/svn/version/2.1(beta4)/IE9.js"></script>
<![endif]-->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
    var index = 0;
    $('#add_dynamic').click(function(){
        $('#dynamic').append('<div><span>' + (index++) + '</span></div>');
        IE7.recalc();
    });
});
</script>
</head>

<body>
<input type="button" id="add_dynamic" value="add" />
<div id="dynamic"></div>
</body>
</html>
※first-child は IE7・IE8 でも使用可能だが、IE9.js を使用すると javascript 適用のスタイルシートになる。

参考URL

2014年5月30日

IE7 テキストボックスの上下余白(margin)

IE でテキストボックス <input type="text" /> を縦方向に並べる際、テキストボックスに margin:0 を指定しても、IE のバージョンによっては上下に余白ができることがある。
特に IE7 において顕著である。
※横方向に並べる際は問題ない。

具体例

[CSS]

div {
    margin: 0;
    padding: 0;
    width: 120px;
    /* 見易さのためのオプション */
    background-color: #00ffff;
    text-align: center;
}
div input {
    margin: 0;
    width: 50px;
    border: 1px solid #000000;
}
[HTML]
※DOCTYPE を指定しないとバージョン間の差異はさらに増える

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- 中略 -->
<div>
<input type="text" /><input type="text" /><br/>
<input type="text" /><input type="text" />
</div>
[プレビュー]
IE11
IE8~10もほぼ同じ
IE11 textbox
IE7 IE7 textbox

解決手段

見た目どおり上下の余白を取り除くという発想で、<input> に "margin: -1px 0" を指定しただけでは、縦中央に余白が残る。
IE7 textbox minus margin

そこで、<div> に font-size:12px を指定してみると、縦中央の余白も無くなる。
(理由は不明、高さ関係の計算で font-size が必要とか?)
<input> に対してではなく、それを包括する要素に指定するのがポイント
IE7 textbox minus margin and font-size

[IE7 に対応した CSS]

div {
    margin: 0;
    padding: 0;
    width: 120px;
    font-size: 12px;
    /* 見易さのためのオプション */
    background-color: #00ffff;
    text-align: center;
}
div input {
    margin: 0;
    width: 50px;
    border: 1px solid #000000;
}
/* IE7 のみ適用 */
*+html div input {
    margin: -1px 0;
}

/* [おまけ] reset.css で記載する場合
 * ※属性セレクタを使用するため、IE9.js などが必要
 */
*+html input[type=text] {
    margin: -1px 0;
}

備考

<input> に padding:0 を指定すると、IE8 と IE9 でも上に余白ができるが、上記と同様に <div> に font-size を指定すれば無くなる。
クロスブラウザ対応で font-size の指定は意外と重要。