摘要:響應(yīng)式自適應(yīng)響應(yīng)式和自適應(yīng)設(shè)計(jì)共同點(diǎn)都是要處理在不同裝置下瀏覽網(wǎng)頁的問題,可讀性,版型等等。關(guān)於由於我們?nèi)詴?huì)在的設(shè)計(jì)中使用百分比,如此一來或多或少還是會(huì)受到進(jìn)位誤差的影響,因此並不是佈局的萬能藥。
問題
為了要能夠解釋得更清楚我們需要實(shí)作一小段跟我們會(huì)遇到的問題相關(guān)的程式碼
.list-item { float: left; width: 33%; }
現(xiàn)在您可能會(huì)想知道關(guān)於上面這段程式碼有什麼問題,看起來這樣並不明顯,好!假設(shè)這是一個(gè)三欄(column)的網(wǎng)格,就算你知道 33% + 33% + 33% = 99% 並不是 100%。但在大多數(shù)的情況下並不會(huì)有什麼問題,不過這誤差的 1% 如果遇到容器像是 1400px 時(shí)就是 14px,那就是一個(gè)蠻大的誤差了。那為什麼我們不直接調(diào)整百分比的精度呢? 我們是可以將它降低到 1.4px 甚至是 0.14px 那麼一來就不會(huì)有問題啦
.list-item { float: left; width: 33.33%; }實(shí)際上...
關(guān)於流質(zhì)網(wǎng)格(Fluid Grid)破版的問題,...其實(shí)就只是誤差造成縫隙或偏移。
所謂響應(yīng)式設(shè)計(jì)(RWD)依照 Ethan Marcotte 所定義: 就是流質(zhì)網(wǎng)格,響應(yīng)式圖片,加上 Media Query 所構(gòu)成。但關(guān)於流質(zhì)網(wǎng)格卻有一個(gè)比較麻煩的問題,就是計(jì)算捨入的部分是錯(cuò)誤的。當(dāng)我們使用百分比設(shè)定欄位時(shí),瀏覽器必須要根據(jù)螢?zāi)?,viewport 及可視區(qū)域?qū)⑵滢D(zhuǎn)換為實(shí)際的像素(pixel)。在這個(gè)轉(zhuǎn)換的過程中 Chrome, Safari, Opera 等瀏覽器全部產(chǎn)出錯(cuò)誤的值。
Fluid:英文為液態(tài),液體,流質(zhì)定義為一種物質(zhì)可持續(xù)性的改變形狀以適應(yīng)周圍的壓力或容器
流質(zhì)網(wǎng)格:網(wǎng)格尺寸會(huì)根據(jù)父元素尺寸自動(dòng)調(diào)整,簡單說即我們定義最外圍的尺寸後就像液體一樣格子會(huì)自動(dòng)變形去適應(yīng)尺寸
所謂的錯(cuò)誤主要是因?yàn)檫@是需要被定義在 CSS 規(guī)範(fàn)的問題。但由於 CSS 並沒有規(guī)範(fàn)瀏覽器對於百分比計(jì)算精度應(yīng)該要到小數(shù)第幾位,舉例來說如果 6 個(gè)欄位的網(wǎng)格 100% ÷ 6 = 16.666667% ,那麼在一個(gè) 1000px 的可視區(qū)域 viewport 中一欄(column)的寬就是 166.66667px,但因?yàn)闆]有規(guī)範(fàn),所以瀏覽器廠商各自使用自己的規(guī)則,如果瀏覽器使用四捨五入那麼在我們這個(gè)範(fàn)例我們就會(huì)得到 167px 結(jié)果就是 167 x 6 = 1002 就會(huì)超出 viewport 範(fàn)圍。如果捨去變成 166px 那最終我們會(huì)少 4px。
IE6 7 採用前者就是進(jìn)位,這也意味著常常會(huì)超出我們想要的尺寸,WebKit 採用後者以避免破版,Opera 甚至直接在百分比動(dòng)手腳把 16.66667% 直接換成 16%,結(jié)果就是一個(gè)欄位(column)的寬跟我們要的整整誤差 6px。好!在你開始罵這些開發(fā)商之前,請先想想這是因?yàn)?CSS 規(guī)範(fàn)沒有定義規(guī)則??!
更糟糕的狀況?不幸的是,如果您同時(shí)也使用百分比來設(shè)定這些間隔(gutters)尺寸如 pedding 之類的,那麼這問題真的會(huì)非常糟糕。過去(約 2012 年)大部分佈局的方式都是採用 float 的方式,即網(wǎng)格中格子位置必須仰賴大量計(jì)算來完成。
假設(shè)我們有一列 12 欄的網(wǎng)格透過百分比設(shè)定 width, margin, padding,那麼第 12 欄的位置需要前面 11 欄的 padding, margin, width 來計(jì)算,也就是說包含自己在內(nèi)會(huì)有 56 次機(jī)會(huì)計(jì)算產(chǎn)生誤差2(padding) + 2(margin) + 1(width) = 5; 11 * 5 + 1(margin itself) = 56,假如每一次計(jì)算都誤差 1px 那麼就會(huì)有 56px 的誤差。
在你知道這點(diǎn)之後也就不奇怪為什麼 mediaqueri.es 網(wǎng)站上這麼多設(shè)計(jì)都沒有凸顯區(qū)塊邊緣的設(shè)計(jì),因?yàn)槿绱艘粊砭瓦@個(gè)計(jì)算的誤差就比較不明顯一點(diǎn)。
您可以檢視範(fàn)例來看看各個(gè)瀏覽器誤差的情況
那有什麼辦法?首先,我得先對那些自適應(yīng)(adaptive)網(wǎng)頁設(shè)計(jì)的提倡者說,我明白你看到這邊非常開心。的確! 採用自適應(yīng)的方法能良好的運(yùn)作,因?yàn)?Adaptive Web Design 預(yù)先對 viewport 尺寸定義然後當(dāng)遇到那些不符合的尺寸時(shí)則採用小一級例如:預(yù)先設(shè)計(jì)了 1024 和 960 寬的 viewport 如果遇到 1000 就採用 960 的設(shè)計(jì)。因?yàn)椴皇褂昧髻|(zhì)網(wǎng)格所以完全避開了關(guān)於百分比誤差的問題。但這裡並不是要說 AWD 就是比較好的做法,只是稍微提一下採用 AWD 的話不會(huì)遇到這個(gè)問題。
最佳解決方案響應(yīng)式(Responsive) vs 自適應(yīng)(Adaptive)
響應(yīng)式和自適應(yīng)設(shè)計(jì)共同點(diǎn); 都是要處理在不同裝置下瀏覽網(wǎng)頁的問題,可讀性,版型等等。
最大的部分在於 RWD 是透過 Fluid Grid 和元素使其自動(dòng)符合視窗或父元素尺寸,而自適應(yīng) AWD 則是預(yù)先定義可視區(qū)域的尺寸然後透過 JS CSS 等方式去套用版型樣式
您可能注意到我剛剛並沒有提到 Firefox 計(jì)算的問題。Firefox 實(shí)作了一個(gè)較為先進(jìn)的方式稱為 sub-pixel 渲染取代捨入計(jì)算的方式,F(xiàn)irefox 會(huì)替所有 CSS 屬性保留 sub-pixel 值,當(dāng)元素的位置需要相依其他元素時(shí)就會(huì)把 sub-pixel 拿出來計(jì)算。這個(gè)效果相對接近設(shè)計(jì)師的期望。
IE8 也採用了 sub-pixel 顯然是為了補(bǔ)救 IE7 非常糟糕的計(jì)算方式。WebKit 與 Opera 以及那些使用捨去值策略的瀏覽器還沒有採用 sub-pixel 的方式。
而其中一個(gè)解決方式就是我們可以等到所有瀏覽器都採取 sub-pixel 的方式渲染,不過這可能需要等待非常久的時(shí)間。
這篇文章試圖要找出解決方案而不是被動(dòng)的等待,幸運(yùn)的是下面有一些方式是我們今天可以採用的。
由於我們?nèi)詴?huì)在 Flexbox 的設(shè)計(jì)中使用百分比,如此一來或多或少還是會(huì)受到進(jìn)位誤差的影響,因此 Flexbox 並不是佈局的萬能藥。
盡可能移除使用百分比的部分首先,我們必須要認(rèn)同將所有佈局 Layout 每個(gè)屬性例如間隔的 padding 等都用百分比處理只是那些龜毛,強(qiáng)迫癥開發(fā)者的樂趣,我們並不需要完全採用百分比。
第一個(gè)問題是因?yàn)樵?CSS2 時(shí)盒子模型(Box model)中 padding 和 border 並不包含在元素寬內(nèi),意思是如果我們設(shè)定一個(gè)元素的寬為百分比,我們也必須使用百分比去設(shè)定 padding margin,否則計(jì)算上一定會(huì)出現(xiàn)不符合 100% 的狀況,但如果把 box-model 換成 box-sizing: border-box ,padding 和 border 就會(huì)包含在 width 裡,意思是我們就不需要在被迫在這些屬性上使用百分比,就可以使用固定的值 em, rem, px 等。針對網(wǎng)格邊界之間的間隔空間比較好的做法是使用 padding 而不是 margin。所有內(nèi)容與間隔都套用保持一致比例,這樣一來比起當(dāng)要顯示出邊界的樣式時(shí)才個(gè)別因?yàn)閷R的關(guān)係加上容器元素(wrapper),前者的優(yōu)點(diǎn)大於後者。
所以結(jié)論就是當(dāng)使用 border-box 時(shí),間距的部分 margin padding 就不會(huì)再遇到數(shù)學(xué)計(jì)算捨入的誤差問題。但在 width 方面仍然會(huì)有這個(gè)問題,不過以 12 欄來說我們把最大誤差從 56px 降低到 11px 。雖然很不錯(cuò)了,但對使用者來說還是會(huì)被注意到這樣的瑕疵。
不讓捨入誤差累加捨入誤差真正的問題是因?yàn)樵谠O(shè)計(jì)佈局時(shí)這些誤差常常是會(huì)累加的,為了要取得一個(gè)格子的左邊界定位我們必須要依賴前面同層的格子來計(jì)算,因?yàn)?float 需要依據(jù)上一個(gè)元素來排位置。
那假如我們有辦法直接指定左邊界呢? 就是說如果可以就直接設(shè)定從父元素左邊界到本身的距離,然後其他元素遵循一樣 float 的排版呢?
事實(shí)證明是可以這樣做的。大約從 2004 年這個(gè)技術(shù)就已經(jīng)被使用了稱為 container relative floats,這也是 Drupal 的 Zen 樣板使用的核心技術(shù)。
雖然乍看之下這招不怎麼高明,但事實(shí)證明這個(gè)做法還蠻牢靠的。
這個(gè)方法主要是透過在每個(gè)網(wǎng)格套用下面的 CSS
float: left; margin-right: -100%;
接著每一個(gè)格子設(shè)定 margin-left 值是從父容器左邊界到其定位的距離。下面是一個(gè)簡單的範(fàn)例
.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%; }
注意您也可以反過來設(shè)定網(wǎng)格對應(yīng)右邊界的距離 float: right 然後 margin-left: -100%;。
不過這個(gè)原理到底是啥?首先思考一下 margin-right: -100% 這個(gè) -100% 就是外層容器的寬,接著再想想一個(gè) float 元素 的 margin-right 是會(huì)影響緊鄰地下一個(gè) float 元素,假如我們設(shè)定 margin-right: -10px 那麼它右邊的元素(格子)就會(huì)從原本的位置往左偏移 10px 就是減 10px。
邏輯上 -100% 意味著下一個(gè)元素應(yīng)該要偏移減去容器寬的距離,不過有個(gè)重點(diǎn)就是如果減掉過大的值讓元素超過父容器邊界時(shí)結(jié)果並不會(huì)超出左邊界。
簡言之就是 float 元素在排列位置時(shí)不用在管前面元素右邊界的位置(原本是從上一個(gè)元素的右邊界開始計(jì)算,現(xiàn)在不是),只要看自己和父容器左邊界的距離就好。
試著玩玩下面這個(gè)範(fàn)例
如果你對這個(gè)做法有一種好像 absolute 定位的感覺,覺得很不可靠,那是因?yàn)槟銘?yīng)該沒注意到關(guān)鍵的不同點(diǎn),absolute 的方式會(huì)使元素完全脫離文件排版的一個(gè)規(guī)則順序之中,且 absolute 不會(huì)影響周圍其他元素的位置,但 container-relative 的設(shè)定是可以透過 clear 移除的。
這是關(guān)鍵,因?yàn)楫?dāng) float 項(xiàng)目搭配這樣的用法就可以無視其他元素的右邊界位置,但設(shè)定 clear 時(shí)下邊界仍可以產(chǎn)生影響換行。
這表示我們可以透過設(shè)定上一個(gè)網(wǎng)格或項(xiàng)目 clear 來換行產(chǎn)生新 row ,這是 absolute 辦不到的。
由於我們的網(wǎng)格不再被其他周圍的兄弟元素影響,我們就不再受到 HTML tag 的順序限制。如此一來我們就可以很簡單地把 HTML 中排序的第一個(gè)元素放到列的中間或者隨意把 row 中的網(wǎng)格任意調(diào)整位置順序。
但是這麼做我們還是沒有完全修好誤差的問題!不過我們已經(jīng)減少定位相關(guān)的計(jì)算過程,現(xiàn)在只剩一個(gè)值就是和父元素的距離。不過這個(gè)值仍然受到捨入誤差的影響,也就是或多或少還是會(huì)遇到 1px 的誤差。不過幸運(yùn)的是因?yàn)榇蟛糠值木W(wǎng)站使用者並沒有強(qiáng)迫癥,這樣微小的誤差並不太容易被注意到。
如果內(nèi)容本身是有質(zhì)量的使用者不會(huì)特別去注意那 1px 設(shè)計(jì)上的誤差,不過還有一個(gè)替代的解決方案可以幫助我們實(shí)作甚至減少這 1px 的誤差。
真的可以處理 1px 的誤差?如果您的網(wǎng)格 float 是往左靠,因?yàn)樗械脑囟际窍蜃髮R,所以最可能的狀況那 1px 的誤差都會(huì)顯示在最右邊的那格。即便所有列 row都對齊,這 1px 也蠻容易被發(fā)現(xiàn),但如果我們把這些很明顯的地方換成對齊右邊,如此一來誤差的 1px 會(huì)被放到頁面的中間就比較不會(huì)被注意到。
使用 Zen Grids關(guān)於為什麼需要使用 CSS 預(yù)編譯器實(shí)作 RWD,那是因?yàn)槔缡褂?Sass 可以簡化一些我們需要的設(shè)計(jì)同時(shí)處理那些用純 CSS 會(huì)比較為複雜的地方。那麼 Zen Grids 是如何處理關(guān)於捨入誤差呢?透過使用 Zen Grids 預(yù)設(shè)就透過 border-box 來處理網(wǎng)格的間隔搭配 container-relative 方式,提供一些輔助方法(Methods)讓我們可以簡單的改變對齊的方向。
使用 Sass 與 calc() 處理除了 Zen Grids 的做法,透過 Sass 我們還有一些簡單的方式可以協(xié)助我們
.list-item { float: left; width: (100%/3); } // or .list-item { float: left; width: percentage(1/3); }
透過這兩種方式 Sass 會(huì)自動(dòng)幫我們把精度輸出到小數(shù)以下第五位,雖然沒有完全解決問題但是有幫助的。
現(xiàn)在最新的做法則是使用 calc() 這麼做是把問題交還給瀏覽器去處理,而對於那些還沒支援的瀏覽器則交給 Sass
.list-item { float: left; width: (100% / 3); width: calc(100%/3); }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/115263.html
摘要:事件會(huì)議太多了,太耗時(shí)了我們究竟化了多少間幾乎每一個(gè)我將引入新公司的團(tuán)隊(duì)都曾在某些方面抱怨會(huì)議的持續(xù)時(shí)間。傳統(tǒng)開發(fā)團(tuán)隊(duì)在規(guī)劃和設(shè)計(jì)方面花費(fèi)了更多精力,而團(tuán)隊(duì)完全減少了這一點(diǎn)。然而,這一事件是最具爭議性的事件,可能團(tuán)隊(duì)認(rèn)為這時(shí)間仍然很長。 Scrum事件 - 會(huì)議太多了,太耗時(shí)了!!! 我們究竟化了多少間? 幾乎每一個(gè)我將Scrum引入新公司的團(tuán)隊(duì)都曾在某些方面抱怨Scrum會(huì)議的持續(xù)...
摘要:接下來我們將會(huì)更具體的說明是什麼東西和這傢伙會(huì)怎麼解決這些問題,並且列出目前開發(fā)中一些令人興奮的功能。這個(gè)功能甚至還沒有一個(gè)瀏覽器支援。完整的清單請查閱目前還未被寫入規(guī)範(fàn),意思是這邊提到任何內(nèi)容極有可能會(huì)改變。 譯者:其實(shí)...我想說這可能是最令我感到興奮..但又害怕頭痛的功能... 附上原文連結(jié) 你曾經(jīng)想要使用某個(gè) CSS 的新功能,但是最後卻因?yàn)檫@個(gè)功能瀏覽器還未全面支援而放棄了嗎...
摘要:急切的創(chuàng)建對象餓漢式以上爲(wèi)?zhàn)I漢式單列設(shè)計(jì),該設(shè)計(jì)是線程安全的,即不同的線程在調(diào)用時(shí)返回的是統(tǒng)一對象,在加載這個(gè)類時(shí),馬上創(chuàng)建了這個(gè)類的唯一單列實(shí)列。 單件模式(JAVA實(shí)現(xiàn)) 定義 單件模式: 確保一個(gè)類只有一個(gè)實(shí)列, 並提供一個(gè)全局訪問點(diǎn) 單件模式和全局變量的區(qū)別 若將對象賦值給一個(gè)全局變量, 則該對象需在程序開始時(shí)就創(chuàng)建好, 而改對象可能不會(huì)使用, 造成資源浪費(fèi), 而單件模式支持...
閱讀 2380·2021-11-24 11:16
閱讀 2087·2021-09-30 09:47
閱讀 2043·2021-09-10 10:51
閱讀 1345·2019-08-30 14:08
閱讀 3174·2019-08-30 13:47
閱讀 1556·2019-08-30 13:02
閱讀 3258·2019-08-29 12:29
閱讀 3273·2019-08-26 17:05