左側固定,右側自適應或者右側固定在,左側自適應是一樣的。這種布局很常見,而且面試過程中也經常會問到,這里我總結的方法一共有5種。要實現這種布局,也算比較簡單。我們先給出html結構:
<div id="wrap">
<div id="sidebar" style="height:240px;">固定寬度區</div>
<div id="content" style="height:340px;">自適應區</div>
</div>
<div id="footer">后面的一個DIV,以確保前面的定位不會導致后面的變形</div>
代碼中的#wrap的div,是用來包裹我們要定位的這兩個區的;他后面還有個#footer,用來測試在前面的定位搞定后會不會導致后面的div錯位——如果錯位了,那證明我們的定位方法必須改進。
下面列舉幾個常見的方法:
1.固定寬度區浮動,自適應區不設寬度而設置 margin
我們拿右邊定寬左邊自適應來做示范,CSS代碼如下:
#wrap {
overflow: hidden;
*zoom: 1;
}
#content,
#sidebar {
background-color: #eee;
}
#sidebar {
float: left;
width: 300px;
}
#content {
margin-left: 310px;
}
#footer {
background-color: #f00;
color: #fff;
margin-top: 1em
}
其中,sidebar讓他浮動,並設置了一個寬度;而content沒有設置寬度。
大家要注意html中必須使用div標簽,不要妄圖使用什么p標簽來達到目的。因為div有個默認屬性,即如果不設置寬度,那他會自動填滿他的父標簽的寬度。這里的content就是例子。
當然我們不能讓他填滿了,填滿了他就不能和sidebar保持同一行了。我們給他設置一個margin。由於sidebar在右邊,所以我們設置content的margin-right值,值比sidebar的寬度大一點點——以便區分他們的范圍。例子中是310.
假設content的默認寬度是100%,那么他設置了margin后,他的寬度就變成了100%-310,此時content發現自己的寬度可以與sidebar擠在同一行了,於是他就上來了。
而寬度100%是相對於他的父標簽來的,如果我們改變了他父標簽的寬度,那content的寬度也就會變——比如我們把瀏覽器窗口縮小,那wrap的寬度就會變小,而content的寬度也就變小——但,他的實際寬度100%-310始終是不會變的。
這個方法看起來很完美,只要我們記得清除浮動(這里我用了最簡單的方法),那footer也不會錯位。而且無論content和sidebar誰更長,都不會對布局造成影響.
但實際上這個方法有個很老火的限制——html中sidebar必須在content之前!
但我需要sidebar在content之后!因為我的content里面才是網頁的主要內容,我不想主要內容反而排在次要內容后面。
但如果sidebar在content之后,那上面的一切都會化為泡影。
可能有的人不理解,說你干嘛非要sidebar在后面呢?這個問題說來話長,反正問題就是——content必須在sidebar之前,但content寬度要自適應,怎么辦?
下面有兩個辦法,不過我們先把html結構改成我們想要的樣子:
<div id="wrap">
<div id="content" style="height:340px;">自適應區,在前面</div>
<div id="sidebar" style="height:240px;">固定寬度區</div>
</div>
2.固定寬度區使用絕對定位,自適應區照例設置margin
我們把sidebar扔掉,只對content設置margin,那么我們會發現content的寬度就已經變成自適應了——於是content對sidebar說,我的寬度,與你無關。
content很容易就搞定了,此時來看看sidebar,他迫不得已拋棄了float。我們來看看sidebar的特點:在右邊,寬度300,他的定位對content不影響——很明顯,一個絕對主義分子誕生了。
於是我們的css如下:
#wrap {
*zoom: 1;
position: relative;
}
#sidebar {
width: 300px;
position: absolute;
left: 0;
top: 0;
}
#content {
margin-left: 310px;
}
這段css中要注意給wrap加上了相對定位,以免sidebar太絕對了跑到整個網頁的右上角而不是wrap的右上角。
好像完成了?在沒有看footer的表現時,我很欣慰。我們來把sidebar加長——增長100px!不要一年,只要一條內褲!哦,,,只要一句代碼。
3.float與margin齊上陣
經過前面的教訓,我們重新確立了這個自適應寬度布局必須要達成的條件:
sidebar寬度固定,content寬度自適應
content要在sidebar之前
后面的元素要能正常定位,不能受影響
由於絕對定位會讓其他元素無視他的存在,所以絕對定位的方式必須拋棄。
如果content和sidebar一樣,都用float,那content的自適應寬度就沒戲了;如果不給content加float,那sidebar又會跑到下一行去。
所以,最終我決定:float與margin都用。
我打算把content的寬度設為100%,然后設置float:left,最后把他向左移動310,以便於sidebar能擠上來。
但這么一來content里面的內容也會跟着左移310,導致被遮住了,所以我們要把他重新擠出來。為了好擠,我用了一個額外的div包裹住內容,所以html結構變成了這種樣子:
<div id="wrap">
<div id="sidebar" style="height:240px;">sidebar固定寬度區</div>
<div id="content" style="height:140px;">
<div id="contentb">
content自適應區,在前面
</div>
</div>
</div>
css則變成這樣:
#sidebar {
width: 300px;
float: left;
}
#content {
margin-right: -310px;
float: right;
width: 100%;
}
#contentb {
margin-right: 310px;
}
這樣一改,真正的“content”就變成了contentb,他的寬度跟以前的content一樣,是100%-310.
大家可能注意到了代碼中的兩個margin-left,一個-310px一個310px,最后結合起來相當於什么都沒干,着實蛋疼。但他確實解決了content與sidebar的順序問題。
這個方法的缺點就是:太怪異,以及額外多了一層div。
4.標准瀏覽器的方法
當然,以不折騰人為標准的w3c標准早就為我們提供了制作這種自適應寬度的標准方法。那就簡單了:把wrap設為display:table並指定寬度100%,然后把content+sidebar設為display:table-cell;然后只給sidebar指定一個寬度,那么content的寬度就變成自適應了。
代碼很少,而且不會有額外標簽。不過這是IE7都無效的方法。
html結構:
<div id="wrap">
<div id="sidebar" style="height:240px;">固定寬度區</div>
<div id="space"></div>
<div id="content" style="height:340px;">自適應區,在前面</div>
</div>
css代碼如下:
#wrap {
display: table;
width: 100%;
}
#sidebar {
width: 100px;
display: table-cell;
margin-right: 10px;
background-color: #eee;
}
#space {
width: 10px;
display: table-cell;
}
#content {
display: table-cell;
background-color: #eee;
}
5.使用css3的calc計算元素寬度+浮動
calc()從字面我們可以把他理解為一個函數function。其實calc是英文單詞calculate(計算)的縮寫,是css3的一個新增的功能,用來指定元素的長度。比如說,你可以使用calc()給元素的border、margin、pading、font-size和width等屬性設置動態值。為何說是動態值呢?因為我們使用的表達式來得到的值。不過calc()最大的好處就是用在流體布局上,可以通過calc()計算得到元素的寬度。(原文: http://www.w3cplus.com/css3/how-to-use-css3-calc-function.html © w3cplus.com)。下面是html:
<div id="wrap">
<div id="sidebar" style="height:240px;">固定寬度區</div>
<div id="content" style="height:340px;">自適應區,在前面</div>
</div>
css代碼如下:
#wrap {
width: 100%;
}
#wrap::after {
content: "";
width: 0;
height: 0;
display: block;
clear: both;
}
#sidebar {
float: left;
width: 300px;
background: #eee;
}
#content {
float: left;
width: calc(100% - 300px);
background: rgb(13, 196, 68);
}