<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # margin系列之布局篇 >原作者:doyoe 原文鏈接:http://blog.doyoe.com/2013/12/31/css/margin%E7%B3%BB%E5%88%97%E4%B9%8B%E5%B8%83%E5%B1%80%E7%AF%87/ ## 前端工程師對CSS的基本訴求 布局能力或許是Web前端工程師對CSS的最基本的訴求,當開始進入到這個崗位,就避免不了要和CSS打交道,而和CSS交往,布局當然是不可或缺的。 很遺憾的是,CSS2.1之前都沒有出現真正意義上的布局屬性,直至現如今的CSS3,才開始出現了一些,如:flex, grid 等,不過其兼容性及國內瀏覽器的使用情況,真令人捉急。 不過,有需求就會有變通,對于達成布局目的,已衍生出各式各樣的方法,如:float, inline-block, table, absolute 等等。 ## margin的布局之道 其實,這個話題有點脫離 `margin` 的能力范圍,因為單純的 `margin` 并無法完成復雜布局,它更多做的是輔助,但卻又難以替代。 ## 經典左右結構 兩欄結構應該是最常見和經典的網頁呈現之一吧?如下 `圖一`: ![classsic layout](http://demo.doyoe.com/css/margin/images/layout-1.png)(圖一) 相信對于這樣一個網頁呈現,你不會陌生。那么你有多少種方案可以達成該布局?我想,4至5種應該是保守估計吧? 這次,我們只看 `margin` 是如何做的。 ## absolute + margin 方式 ### HTML ```html <header id="hd">頭部</header> <div id="bd"> <aside id="aside">側邊欄固定寬度</aside> <div id="main">主內容欄自適應寬度</div> </div> <footer id="ft">底部</footer> ``` ### CSS ```css #aside{ position:absolute; top:0; left:0; width:200px; } #main{ margin-left:210px; } ``` 如上關鍵代碼,我們即可實現 `圖一` 布局,該布局有一個特點就是,`#main` 可以自適應可用空間。 假定 `HTML` 是給定的,我們來解讀一下 `CSS` 代碼: 我們知道塊級元素的特性之一是換新行,也就是說,如果想讓 `#main` 和 `#aside` 在同行顯示,我們要么改變其顯示屬性為 `inline-level`(即之前說的inline-block布局方式),要么改變其流方式(absolute, float, flex and etc…)。 如上述代碼,我們使用了 `absolute`,即讓 ‘#aside’ 脫離常規流,通過絕對定位到想要的位置。 ### 主內容欄自適應寬度 同時你會發現,我們并有改變 `#main` 的顯示屬性或者流方式,也就是說其仍然具備塊級元素的特性,所以它會自動適應剩余寬度,即我們常說的自適應寬度。 我們并不希望 `#main` 區域會包含 `#aside` 在內,于是利用 `margin` 給 ‘#aside’ 預留出足夠其顯示的空間,即可達成我們所要的布局。 可能你會問為什么是 `margin-left:210px` 而不是 `200px`,實際確實應該是 `200px`,多出來的 `10px` 只是為了創建一個列間隙,與布局實現無關。 來看看具體的實現 `DEMO1`: [margin+absolute布局:左欄固定主內容自適應](http://demo.doyoe.com/css/margin/layout/absolute-margin.html) 就這樣,是不是很簡單?其實它還有亮點,那就是: ### 任意調整列順序 在不修改 HTML 的情況下,只需簡單的修改 CSS,我們即可讓左右兩欄的順序調換,來看代碼: ### CSS ```css #aside{ position:absolute; top:0; right:0; width:200px; } #main{ margin-right:210px; } ``` 其實現原理沒變,同樣看看 `DEMO2`: [margin+absolute布局:右欄固定主內容自適應](http://demo.doyoe.com/css/margin/layout/absolute-margin-2.html) ### 主內容優先顯示 可以更Cool一點,你覺得呢?很多時候,你也許會考慮到,不論在何種情況下,總想保證主要的內容優先于次要的內容呈現給用戶,那么,怎么做? 很簡單,只需要將主要內容的HTML排在次要內容的HTML之前即可,因為它是順序加載渲染的。我們可以這樣: ### HTML ```html <header id="hd">頭部</header> <div id="bd"> <div id="main">主內容欄自適應寬度</div> <aside id="aside">側邊欄固定寬度</aside> </div> <footer id="ft">底部</footer> ``` 是的,我們只需要將 `#main` 的HTML挪到 `#aside` 的HTML前面,令人興奮的是,改變HTML之后,CSS不需要做任何改變。我們來看 `DEMO3`: [margin+absolute布局:左欄固定主內容自適應,主內容有限顯示](http://demo.doyoe.com/css/margin/layout/absolute-margin-3.html) 當然,調正列順序的 `DEMO4`: [margin+absolute布局:右欄固定主內容自適應,主內容有限顯示](http://demo.doyoe.com/css/margin/layout/absolute-margin-4.html) 也同樣簡單,我們只需要寫HTML時注意一下即可。 ### 致命缺陷 列舉了 `absolute+margin` 布局的很多優點,但只說一個問題,就足以讓你在是否選用這種方式時深思熟慮,是什么呢? 我們知道 `absolute` 是定位流,脫離正常排版,也就是說絕對定位元素不影響其上下文的排版方式,你意識到我想說什么了么? OK,用代碼來演示: ### HTML ```html <header id="hd">頭部</header> <div id="bd"> <div id="main">主內容欄自適應寬度</div> <aside id="aside">側邊欄固定寬度,我的內容可能比主內容多,高度比主內容欄高</aside> </div> <footer id="ft">底部</footer> ``` 看完代碼,估計你猜到了。是的,`#aside` 無法撐開父元素的高度,它將會溢出父元素區域,結果如下圖: ![classsic layout](http://demo.doyoe.com/css/margin/images/layout-2.png)(圖二) 來看看這缺陷所導致的情況 `DEMO5`: [margin+absolute布局的致命缺陷](http://demo.doyoe.com/css/margin/layout/absolute-margin-5.html) 此時假設你設置父元素 `overflow:hidden` 那么溢出部分將會被裁減,同樣不符合布局意圖,無法可破。所以在內容量不可控的場景,不推薦使用這種方式。 ## float + margin 方式 和 `absolute + margin` 方式一樣,`float + margin` 方式一樣是經典的利用來布局的方案,并且被更廣泛使用。我們仍然以 `圖一` 為例,來看代碼: ### HTML ```html <header id="hd">頭部</header> <div id="bd"> <aside id="aside">側邊欄固定寬度</aside> <div id="main">主內容欄自適應寬度</div> </div> <footer id="ft">底部</footer> ``` ### CSS ```css #aside{ float:left; width:200px; } #main{ margin-left:210px; } ``` 如上述代碼,我們使用了 `float`,即從圖文環繞形態演變而來。當 `#aside` 定義了 `float`,那么緊隨其后的元素將會環繞在其周圍。不過環繞并不是我們想要的結果,我們想要的是 ‘#main’ 也自成封閉矩形,所以利用 `margin` 留出足夠 `#aside` 顯示的空間,中斷環繞即可。 當然,此時 `#main` 也是自適應寬度的,來看具體實例 `DEMO6`: [margin+float布局:左欄固定主內容自適應](http://demo.doyoe.com/css/margin/layout/float-margin.html) 它是否也具備可任意調整列順序的特點?何不一試? ### CSS ```css #aside{ float:right; width:200px; } #main{ margin-right:210px; } ``` 看過 `DEMO7`: [margin+float布局:右欄固定主內容自適應](http://demo.doyoe.com/css/margin/layout/float-margin-2.html),你會發現,是的,這種方式也支持任意調整列順序,很棒。 從這種趨勢看來,貌似 `float + margin` 的方式會成為黑馬,不過遺憾的告訴你,這種方式無法支持主內容優先顯示。但我們有更Cool的解決方案。 ## float + 負margin 方式 接下來我要說的大家可能都猜到了,對,經典的圣杯布局。至于圣杯的名字由來,大家可以自行Google,這里不做贅述。 恩,HTML當然是使用主內容優先顯示的那種: ### HTML ``` <header id="hd">頭部</header> <div id="bd"> <div id="main">主內容欄自適應寬度</div> <aside id="aside">側邊欄固定寬度</aside> </div> <footer id="ft">底部</footer> ``` ### CSS ```css #bd{ padding-left:210px; } #aside{ float:left; position:relative; left:-210px; width:200px; margin-left:-100%; } #main{ float:left; width:100%; } ``` 如上代碼,既是圣杯布局的核心Code,如果你看懂了,你會發現,這其實很簡單,不是么? 簡單解釋一下上面的CSS Code,首先我們是在做一個左側固定寬度,右側自適應寬度的布局。我們說過要讓塊級元素在同行顯示的條件:改變顯示方式,改變流方式,這里我們選擇了使用 `float` 來將 `#main` 和 `#aside` 變成浮動流。 OK,這時我們具備 `#main` 和 `#aside` 能在同行顯示的前置條件。我們知道,浮動元素其寬度如果沒有顯式定義,則由其內容決定。正好,`#aside` 是定寬的,所以顯示給它定義 `width:200px`,但此時 `#main` 該怎么辦?不設置 `width` 不對,因為寬度將被內容左右,設置 `width:100%` 也不對,因為這樣的話,就沒有 `#aside` 的立足之地了,正確的應該是 `width: calc(100% - 200px)`,不是么?可惜,這是新特性,只好作罷。 變通?是的,有的時候稍微換個思路,你會覺得豁然開朗。 `#main` 不是要自適應嗎?那就給它個 `100%`,怎么做?我們在包含塊 `#bd` 中就將 `#aside` 的寬度刨除,寬度全部都給 `#main`。恩,我們只需要這樣 `#bd{padding-left:210px;}` (10px仍然是用來做間隙的),這時 `#main` 就可以設置 `width:100%` 了,由于 `#bd` 設置了 `padding`,所以已在左邊預留出了一塊寬 `210px` 的區域。此時的問題在于如果將 `#aside` 挪到這個地方,你想對了,我們是在聊 負margin 布局,自然需要利用上。 `#aside{margin-left:-100%;}` 這樣可以了嗎?很明顯,這樣還不行,此時 `#aside` 和 `#main` 的起始位置將會重合,因為 `#aside` 的 `margin-left` 計算值是相對包含塊來計算的,而此時包含塊的寬度等于 `#main` 的寬度。 如何讓 `#aside` 再向左偏移 `210px`?顯然 `margin` 是不行了,因為我們已經用掉它了。如果你看過之前的文章的話,你可能還記得,有一篇文章講 [margin系列之與相對偏移的異同](http://www.hmoore.net/jaya1992/fe-notes/81816)。恩,是的,這時我們可以借助相對偏移。 向左偏移 `210px` 是件很簡單的事:`#aside{position:relative;left:-210px;}`。 至此,你的布局OK了,這就是圣杯的實現方式。來看已實現好的示例 `DEMO8`: [圣杯:左欄固定主內容自適應](http://demo.doyoe.com/css/margin/layout/holy-grail.html) 當然,圣杯布局必須可以任意調整列順序,要不,怎么能說是更Cool些的方案呢? ### CSS ```css #bd{ padding-right:210px; } #aside{ float:left; position:relative; right:-210px; width:200px; margin-left:-200px; } #main{ float:left; width:100%; } ``` 這個就直接看示例好了,不再一一解釋代碼 `DEMO9`: [圣杯:右欄固定主內容自適應](http://demo.doyoe.com/css/margin/layout/holy-grail-2.html) 所以圣杯布局具備前兩種方式共同的優點,同時沒有他們的不足,但圣杯本身也有一些問題,在IE6/7下報廢,不過不用慌,因為它可被修復。 你想到方法了嗎?
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看