ホームページ > 記事 > ウェブフロントエンド > レスポンシブ デザインの % 問題_html/css_WEB-ITnose
より明確に説明するには、これから遭遇する問題に関連する小さなコードを実装する必要があります
うわーここで、上記のコード部分に何があるか疑問に思っているかもしれません。明らかではありません、わかりました!これが 3 列のグリッドであると仮定すると、33% + 33% + 33% = 99% が 100% ではないことがわかっていてもです。ただし、ほとんどの場合は問題ありませんが、1400px などのコンテナに遭遇したときに 1% の誤差が 14px である場合、これはかなり大きな誤差になります。では、パーセンテージの精度を直接調整してみませんか? 1.4px または 0.14px に減らすこともできます。問題はありません
.list-item { float: left; width: 33%;}
Fluid Grid (流体の破損の問題) についてGrid... のバージョンは、実際にはエラーによって引き起こされる単なるギャップまたはオフセットです。
いわゆるレスポンシブ デザイン (RWD) は Ethan Marcotte によって定義され、流体グリッド、レスポンシブ画像、メディア クエリで構成されます。しかし、流体グリッドにはさらに厄介な問題があります。それは、計算の丸め部分が間違っているということです。パーセントを使用してフィールドを設定する場合、ブラウザは画面、ビューポート、表示領域に基づいてそれを実際のピクセルに変換する必要があります。この変換プロセス中に、Chrome、Safari、Opera、およびその他のブラウザはすべて間違った値を出力します。
流体: 英語では液体、流体は周囲の圧力や容器に適応して形状を持続的に変化させることができる物質として定義されます。 流体グリッド: グリッドのサイズは親要素のサイズに応じて自動的に調整されます。簡単に言えば、最も外側のサイズを定義した後、グリッドはそのサイズに適応するために液体のように自動的に変形します
いわゆるエラーの主な原因は、これが CSS 仕様で定義する必要がある問題であるためです。ただし、CSS では、ブラウザがパーセント計算の精度に使用する小数点以下の桁数が指定されていません。たとえば、6 列のグリッドが 100% ÷ 6 = 16.666667% の場合、1000 ピクセルの表示領域のビューポートでは列の幅は 166.66667 になります。 px ですが、標準がないため、ブラウザの製造元は独自のルールを使用します。ブラウザが丸めを使用する場合、この例では 167 x 6 = 1002 が得られ、ビューポートの範囲を超えます。四捨五入して 166px になると、4px 小さくなります。
IE6 7 は前者を使用して、必要なサイズを超えることがよくありますが、Opera はバージョンの破損を避けるために後者を使用し、その結果は 16.66667% です。列の幅は希望のものからちょうど 6 ピクセルずれています。良い!これらの開発者を叱り始める前に、これは CSS 仕様でルールが定義されていないためであることを考慮してください。
残念ながら、ペディングなどの側溝のサイズ設定にもパーセンテージを使用すると、これは非常に悪いことになる可能性があります。過去 (2012 年頃) は、ほとんどのレイアウト方法でフロートが使用されていました。つまり、グリッド内のグリッドの位置は多くの計算に依存する必要がありました。
幅、マージン、パディングがパーセンテージで設定された 12 列のグリッドがあるとします。つまり、列 12 の位置には、それ自体を含む前の 11 列のパディング、マージン、幅が必要になります。 56 回の確率計算により、2(パディング) + 2(マージン) + 1(幅) = 5 の誤差が生じます。11 * 5 + 1(マージン自体) = 56 になります。各計算に 1px の誤差がある場合、 56pxの誤差になります。
これを知れば、mediaqueri.es Web サイト上の多くのデザインがブロックのエッジを強調表示していないのも不思議ではありません。そうすることで、計算エラーが目立たなくなるからです。
各ブラウザのエラー状況を確認するにはサンプルをチェックしてください
まず第一に、アダプティブ Web デザインの支持者に言わなければなりません、私はここであなたが見ていることを非常に満足していると理解しています。確かに、アダプティブ Web デザインはビューポート サイズを事前に定義し、サイズを満たさないビューポートに遭遇した場合はより小さいサイズを使用するため、アダプティブな方法はうまく機能します。たとえば、1024 および 960 幅のビューポートは、1000 に遭遇した場合に事前に設計されます。 960のデザインを採用。流体グリッドが使用されないため、パーセント誤差の問題は完全に回避されます。ただし、これは AWD の方が優れたアプローチであると言っているのではなく、AWD を使用するとこの問題が発生しないことを簡単に述べたいと思います。
レスポンシブ デザインとアダプティブ デザイン
レスポンシブ デザインとアダプティブ デザインには共通点があり、どちらも異なるデバイスでの Web ページの閲覧、読みやすさ、レイアウトなどの問題に対処する必要があります。
最大の部分は、RWD が Fluid Grid と要素を使用してウィンドウまたは親要素のサイズに自動的に適合するのに対し、アダプティブ AWD は表示領域のサイズを事前定義し、JS CSS やその他のメソッドを通じてレイアウト スタイルを適用することです
您可能注意到我剛剛並沒有提到 Firefox 計算的問題。Firefox 實作了一個較為先進的方式稱為 sub-pixel 渲染 取代捨入計算的方式,Firefox 會替所有 CSS 屬性保留 sub-pixel 值,當元素的位置需要相依其他元素時就會把 sub-pixel 拿出來計算。這個效果相對接近設計師的期望。
IE8 也採用了 sub-pixel 顯然是為了補救 IE7 非常糟糕的計算方式。WebKit 與 Opera 以及那些使用 捨去值策略 的瀏覽器還沒有採用 sub-pixel 的方式。
而其中一個解決方式就是我們可以等到所有瀏覽器都採取 sub-pixel 的方式渲染,不過這可能需要等待非常久的時間。
這篇文章試圖要找出解決方案而不是被動的等待,幸運的是下面有一些方式是我們今天可以採用的。
由於我們仍會在 Flexbox 的設計中使用百分比,如此一來或多或少還是會受到進位誤差的影響,因此 Flexbox 並不是佈局的萬能藥。
首先,我們必須要認同將所有佈局 Layout 每個屬性例如間隔的 padding 等都用百分比處理只是那些龜毛,強迫症開發者的樂趣,我們並不需要完全採用百分比。
第一個問題是因為在 CSS2 時盒子模型(Box model)中 padding 和 border 並不包含在元素寬內,意思是如果我們設定一個元素的寬為百分比,我們也必須使用百分比去設定 padding margin,否則計算上一定會出現不符合 100% 的狀況,但如果把 box-model 換成 box-sizing: border-box ,padding 和 border 就會包含在 width 裡,意思是我們就不需要在被迫在這些屬性上使用百分比,就可以使用固定的值 em, rem, px 等。針對網格邊界之間的間隔空間比較好的做法是使用 padding 而不是 margin。所有內容與間隔都套用保持一致比例,這樣一來比起當要 顯示出邊界的樣式 時才個別因為對齊的關係加上容器元素(wrapper),前者的優點大於後者。
所以結論就是當使用 border-box 時,間距的部分 margin padding 就不會再遇到數學計算捨入的誤差問題。但在 width 方面仍然會有這個問題,不過以 12 欄來說我們把最大誤差從 56px 降低到 11px 。雖然很不錯了,但對使用者來說還是會被注意到這樣的瑕疵。
捨入誤差真正的問題是因為在設計佈局時這些誤差常常是會累加的,為了要取得一個格子的左邊界定位我們必須要依賴前面同層的格子來計算,因為 float 需要依據上一個元素來排位置。
那假如我們有辦法直接指定左邊界呢? 就是說如果可以就直接設定從父元素左邊界到本身的距離,然後其他元素遵循一樣 float 的排版呢?
事實證明是可以這樣做的。大約從 2004 年這個技術就已經被使用了稱為 container relative floats ,這也是 Drupal 的 Zen 樣板使用的核心技術。
雖然乍看之下這招不怎麼高明,但事實證明這個做法還蠻牢靠的。
這個方法主要是透過在每個網格套用下面的 CSS
float: left;margin-right: -100%;
接著每一個格子設定 margin-left 值是從父容器左邊界到其定位的距離。下面是一個簡單的範例
.item1 { float: left; width 40%; margin-left: 0; margin-right: -100%;}.item2 { float: left; width: 40%; margin-left: 40%; margin-right: -100%;}.item3 { float: left; width: 20%; margin-left: 80%; margin-right: -100%;}
注意您也可以反過來設定網格對應右邊界的距離 float: right 然後 margin-left: -100%; 。
不過這個原理到底是啥?首先思考一下 margin-right: -100% 這個 -100% 就是外層容器的寬,接著再想想一個 float 元素 的 margin-right 是會影響緊鄰地下一個 float 元素,假如我們設定 margin-right: -10px 那麼它右邊的元素(格子)就會從原本的位置往左偏移 10px 就是減 10px。
邏輯上 -100% 意味著下一個元素應該要偏移減去容器寬的距離,不過有個重點就是如果減掉過大的值讓元素超過父容器邊界時結果並不會超出左邊界。
簡言之就是 float 元素在排列位置時不用在管前面元素右邊界的位置(原本是從上一個元素的右邊界開始計算,現在不是),只要看自己和父容器左邊界的距離就好。
試著玩玩下面這個 範例
如果你對這個做法有一種好像 absolute 定位的感覺,覺得很不可靠,那是因為你應該沒注意到關鍵的不同點, absolute 的方式會使元素完全脫離文件排版的一個規則順序之中,且 absolute 不會影響周圍其他元素的位置,但 container-relative 的設定是可以透過 clear 移除的。
這是關鍵,因為當 float 項目搭配這樣的用法就可以無視其他元素的右邊界位置,但設定 clear 時下邊界仍可以產生影響換行。
這表示我們可以透過設定上一個網格或項目 clear 來換行產生新 row ,這是 absolute 辦不到的。
由於我們的網格不再被其他周圍的兄弟元素影響,我們就不再受到 HTML tag 的順序限制。如此一來我們就可以很簡單地把 HTML 中排序的第一個元素放到列的中間或者隨意把 row 中的網格任意調整位置順序。
但是這麼做我們還是沒有完全修好誤差的問題!不過我們已經減少定位相關的計算過程,現在只剩一個值就是和父元素的距離。不過這個值仍然受到捨入誤差的影響,也就是或多或少還是會遇到 1px 的誤差。不過幸運的是因為大部分的網站使用者並沒有強迫症,這樣微小的誤差並不太容易被注意到。
如果內容本身是有質量的使用者不會特別去注意那 1px 設計上的誤差,不過還有一個替代的解決方案可以幫助我們實作甚至減少這 1px 的誤差。
如果您的網格 float 是往左靠,因為所有的元素都是向左對齊,所以最可能的狀況那 1px 的誤差都會顯示在最右邊的那格。即便所有 列 row 都對齊,這 1px 也蠻容易被發現,但如果我們把這些很明顯的地方換成對齊右邊,如此一來誤差的 1px 會被放到頁面的中間就比較不會被注意到。
關於 為什麼需要使用 CSS 預編譯器實作 RWD ,那是因為例如使用 Sass 可以簡化一些我們需要的設計同時處理那些用純 CSS 會比較為複雜的地方。那麼 Zen Grids 是如何處理關於捨入誤差呢?透過使用 Zen Grids 預設就透過 border-box 來處理網格的間隔搭配 container-relative 方式,提供一些輔助方法(Methods)讓我們可以簡單的改變對齊的方向。
除了 Zen Grids 的做法,透過 Sass 我們還有一些簡單的方式可以協助我們
.list-item { float: left; width: (100%/3);}// or.list-item { float: left; width: percentage(1/3);}
透過這兩種方式 Sass 會自動幫我們把精度輸出到小數以下第五位,雖然沒有完全解決問題但是有幫助的。
現在最新的做法則是使用 calc() 這麼做是把問題交還給瀏覽器去處理,而對於那些還沒支援的瀏覽器則交給 Sass
.list-item { float: left; width: (100% / 3); width: calc(100%/3);}