13

カスケードは、CSS を特別で強力にするものです。しかし、メディア クエリの場合、オーバーラップ問題に見えることがあります。

次の CSS を検討してください ( CSS メディア クエリ オーバーラップの継続ルール):

/* Standard - for all screens below 20em */

body { color: black; font-size: 1em; }

/* Query A - slightly wider, mobile viewport */

@media (min-width: 20em) and (max-width: 45em) {
    body { color: red; } /* supposed to be unique for this width */
}

/* Query B - everything else */

@media (min-width: 45em) {
    body { font-size: larger; } /* because viewport is bigger */
}

したがって、画面の幅がちょうど 45em の場合、45em のオーバーラップは標準の CSS カスケードに従って処理されます。

  • すべてのmax-width: 45em定義が最初に適用されます。
  • 以降はすべてmin-width: 45em適用されます。

次の 2 つの条件を考慮してください。

  • 通常、すべてのテキストは になりますがblackクエリ Aは一意であり、color: red.
  • クエリ Bはより大きなビューポート用であるため、そのテキストには CSS がありfont-size: largerます。

したがって、正確に 45em の幅では、大きな赤いテキストが表示されます。これを回避するための最善の解決策は何でしょうか?


2 つの可能性があります。

  1. Query Bcolor: blackに含まれるテキストを再宣言しますが、将来を変更することを選択した場合、2 つの宣言を管理することになります。(もちろん、この 1 行のコードではそれほど問題はありませんが、他にも多くの宣言とセレクターがあると想像してください。)color

  2. max-width: 799pxやのようなピクセル値を使用してオーバーラップを避けmin-width: 800pxますが、ピクセルを使用しています。それぞれ 49.9375em と 50em になる可能性があると思います。しかし、デフォルトが 16em ではなくなり、何かが丸められた場合はどうなるでしょうか? そして、そのギャップで何が起こるかはまだわかりません. (時空連続体を壊すブラックホール?)

どちらにも欠点があります...他のアイデアはありますか?

4

2 に答える 2

12

@media特定のメディアクエリに対して2 つの相互に排他的なブロックを作成する唯一の信頼できる方法notは、ブロックの 1 つでそれを否定するために使用することです。@media残念ながら、これはブロックごとにメディア クエリを 1 回繰り返すことを意味します。したがって、これの代わりに、たとえば次のようにします。

@media (max-width: 49.9375em) {
    body {
        color: red;
    }
}

@media (min-width: 50em) {
    body {
        font-size: larger;
    }
}

あなたはこれを持っているでしょう:

/* 
 * Note: Media Queries 4 still requires 'not' to be followed by a
 * media type (e.g. 'all' or 'screen') for reasons I cannot comprehend.
 */
@media not all and (min-width: 50em) {
    body {
        color: red;
    }
}

@media (min-width: 50em) {
    body {
        font-size: larger;
    }
}

インタラクティブな jsFiddle デモ

widthこれは、とのようなレンジ メディア機能とのギャップを埋めるのに非常に効果的ですheight。しかし、最初の 2 つのオプションと同様に、これは完璧ではありません。前述のように、同じメディア クエリを 2 回繰り返し、notそのうちの 1 つに追加する必要があります。条件付きルール 3@mediaで説明されているように、if/else 構造はありません。


前の質問への回答でこれについて言及していますが:

私の実験では、ビューポートが実際には 799.5px (明らかに前者と一致する) であっても、iOS 上の Safari はすべての小数ピクセル値を四捨五入して、 と のいずれかmax-width: 799pxが一致するように見えます。min-width: 800px

それでも、丸めに関しては、いくつかの癖に気付いたことに注意してください。とはいえ、両方のメディア クエリを回避し、どちらのルール セットからもスタイルを取得できなくなるような小数値を見つけることはできませんでした (ちなみに、これは起こり得る最悪の事態なので、心配しないでください)。時空の裂け目を作る可能性について)。つまり、ブラウザー (少なくとも私がテストした Safari) は、値が (CSS ピクセルが 1 つだけ) 異なっていても、メディア クエリを確実に満たすという合理的な仕事をしているということです。

ただし、デスクトップ ブラウザーで観察できるギャップが大きい単位に関しては、em のように、はるかに大きな誤差範囲があります。たとえば、あるコメントでは、49.9375em よりも恣意的なものの代わりに 49.99999em を使用することを提案していますが、明らかに違いがあり、少なくともデフォルトのフォント サイズは 16px です。

コードを簡素化し、メディア クエリを 10 進数値を使用するように変更し、コードを jsFiddle に配置しました。

@media (max-width: 49.9375em) {
    body {
        color: red;
    }
}

@media (min-width: 50em) {
    body {
        font-size: larger;
    }
}

結果ペインのサイズを正確に 800 ピクセルに変更すると (テキストが更新されてガイドが表示されます)、 is usedか@media (max-width: 49.9375em)is used@media (max-width: 49.99999em)によって、実際には異なる結果になります(これには私も驚きました)...

いずれにせよ、その通りです。オプション 2 にも欠点があります。正直なところ、私はそれが特に好きではありません。なぜなら、私の制御不能なデバイスやユーザーエージェントの癖に頭を悩ませたくないからです。あなたが私のような人なら、少なくとも作成者としてのコントロールの範囲内にあるので、コードにもっと注意を払うという犠牲を払って (?) ルールを再宣言するという不都合を経験したほうがよいと思います。

于 2012-11-30T16:21:07.250 に答える