首頁 web前端 html教學 从三栏自适应宽度布局到css布局的讨论_html/css_WEB-ITnose

从三栏自适应宽度布局到css布局的讨论_html/css_WEB-ITnose

Jun 24, 2016 am 11:32 AM

      如何实现一个三栏自适应布局,左右各100px,中间随着浏览器宽度自适应?

      第一个想到的是使用table布局,设置table的宽度为100%,三个td,第1个和第3个固定宽度为100px,那么中间那个就会自适应了,下面是一个实时的demo:

left  middle  right 

      但是table布局是不推荐的,table布局是css流行之前使用的布局,有很多缺点:当table加载完之前,整个table的都是空白的,table将数据和排版参和在一起,使得页面混乱,并且table布局修改排版十分麻烦和困难。

      如果不用table布局,那么第二个想到的办法是采用float,让左边的div float left,右边的div float right,如下边所示:

Action 1 先让左右两个div浮动

float left 

float right 

      中间还有一个div,如果将中间的div排在第二:

<div style="float:left;">left</div><div>middle</div><div style="float:right;">right</div>
登入後複製

那么效果是这样的:

Action 2 右边的div浮动到了第二行

left

middle

right

因为div默认的display为block,如果不设置width的话,块级元素会尽可能多地占用水平空间。如果设置了width: 200px,效果是这样的:

Action 3 右边的div仍然浮动到了第二行

float left

middle

right

第三个div仍然会换行,因为float right会排到当前行尽可能右边的位置,即它的容器盒的边缘或者挨着的上一个float的元素,如果当前行没有空间的话,会不断地往下移,直到有足够的空间。由于middle是一个块盒,即使设置了width,当前行的空间也会被占用,所以right只能到下一行才有空间。

同时注意到middle虽然设置了200px,但是看起来和left一样是100px宽了。这是因为float了的元素虽然在正常的文档流之内,但是只是让相邻(非float)的元素的内容围绕着它排列,它仍然占据相邻元素的background和border空间。如果给middle添加一个白色的border,那么看起来是这样的:

Action 4 浮动的元素占据了文档流相应元素的背景和边缘空间

float left

middle

right

明显看到,float left的元素占据了middle的background和border的空间,同时middle的内容围绕着left排列。理解这点很重要。

假设middle里面有个p标签,而p标签的内容比较长,那么围绕的效果是这样的:

Action 5 浮动的环绕效果

float left

middle

环绕的元素一旦超出float元素高度之后,会以正常的宽度显示

float right

正如上面的注释一样,在float元素的那一行,相邻的元素的内容的宽度将会缩短,以适应float元素占去的宽度,而一旦超过float元素的区域,相邻元素的内容显示宽度就会正常。

由于默认的div会占一行,所以不能将middle放在第二个div,得放到第三个div。把第二个div和第三个div换一下顺序:

<div style="float:left;">left</div><div style="float:right;">right</div><div>middle</div>
登入後複製

先让float right的div渲染,再渲染middle的div。因为渲染left之后,left的那一行仍然有空间,这是由于float left之后,只会占据当前行的background和border,而当前行还有很大的空间,于是第二步渲染right时就和left同一行了,效果:

Action 6 先渲染左右两个div,再渲染中间的div

left

right

middle

如果不设置middle的width,那么middle将围绕着left和right环绕,和left一样,right也会占用middle的空间。

Action 7 中间的div围绕着左右的div环绕

left

right

~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ middle围绕着left和right环绕,同时left和right占据着middle的空间 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~

为了让middle和left/right中间有一个margin值,设置下middle的左右margin各为110px,这样就和左右和中间就各有10px的间距:

Action 8 设置中间div的margin值为100px + 10px

left

right

middle 设置margin: 0 110px;

这种办法的优点是实现简单,支持性好。

这种自适应宽度的原理是利用了float的围绕特性,占据自然文档流的background/border位置。这个围绕特性不仅会影响当前行的内容,还会影响下一行的内容,如下说明:

<p>第一段内容,略<img  src="/static/imghw/default1.png"  data-src="..."  class="lazy"   style="max-width:90%"从三栏自适应宽度布局到css布局的讨论_html/css_WEB-ITnose" >float:left;</strong>"></img></p><p>第二段内容,略</p>
登入後複製

Action 8 float元素占据了下一行的空间

第一段落围绕着图片排列

图片的float属性也影响了第二段落,也就是说float会占据自然文本流相应位置元素的背景和边框,即使和float的元素不在同一行

网上还有一种margin负值法。margin负值法的步骤是:第一步让中间的middle占100%的宽度,而middle的内容设置左右margin各为100px,这样就实现了middle居中自适应宽度的效果:

<div style="width:100%;">      <div style="margin: 0 100px;">middle</div></div>
登入後複製

middle

接下来让left的margin-left值为-100%,由于这个比例是相对于浏览器窗口大小的,所以要是left和middle是在同一行的话,left就可以跑到middle的最左边。但是因为middle的容器盒是一个普通的div,会占据一整行,left就会排到下一行,这个时候设置margin-left为一个负数时就跑出屏幕了。所以让middle float一下,left就会排到第一行最左边,同时middle覆盖在上面:

<div style="width:100%; <strong>float:left</strong>;">      <div style="margin: 0 100px;">middle</div></div><div style="margin-left: 0">left</div>
登入後複製

middle

left

从上面可以看到:这样实现,导致left的内容被挤出目标区域,因为正如上面所说,middle占据了left的背景空间,上面的情况是把它占满了,left内容只能overflow了。所以这样实现是有问题的,得让left也向左float一下,这样left就紧挨在middle后面了,由于middle占了100%的宽度,所以再让left向左边margin了-100%后,left就刚好在最左边了。

<div style="width:100%; float:left;">      <div style="margin: 0 100px;">middle</div></div><strong><div style="float: left; margin-left: -100%;">left</div></strong>
登入後複製

middle

left

注意这里,虽然left float之后看起来也是被排到下一行了,但和默认的div独占一行是不一样的。float之后的left仍然和middle是同一行的,因为空间不足的时候,float只是把当前行盒的空间撑大,就和一个div块盒里面有很多个display为inline-block的行内级盒是同样的道理。例如:

<style>     button{ width: 150px; }</style><div style="width: 300px;">    <button>按钮1</button>     <button>按钮2</button>     <button style="margin-left: -200px;">按钮3</button></div>
登入後複製

按钮3设置了一个很大的margin-left的负值后并不是跑到屏幕外了,而是在和其它两个按钮同一行的位置,显示如下:

按钮1 按钮2 按钮3

注意,设置了float的元素并不是把display改成了 inline-block,大部份display的css计算值都变成了block,同时对原本是display: flex的没有改变:

指定值 计算值
inline block
inline-block block
inline-table table
table-row block
table-row-group block
table-column block
table-column-group block
table-cell block
table-caption block
table-header-group block
table-footer-group block
flex flex, but float has no effect on such elements
inline-flex inline-flex, but float has no effect on such elements
other unchanged

来自MDN

由上表可看出,一个span设置了float: left/right之后,就不需要再设置成display: block/inline-block了,直接设置宽高即可。

回归正题,left的div设置了margin-left: -100%之后就跑到左边去了,而right也是同样道理,将right的margin-left相应地设置为-100px,就跑到最右边去了:

<div style="width:100%; float:left;">      <div style="margin: 0 100px;">middle</div></div><div style="margin-left: -100%;">left</div><strong><div style="margin-right: -100px;"</strong>>right</div>
登入後複製

Action 9 margin负值法

middle

left

right

下面讨论第三种方法,使用display: table-cell

由于table的展示拥有自适应的特点,因此把需要自适应宽度的middle的display属性设置为table-cell。

<div style="float:left;">left</div><div style="float:right;">right</div><div style="display:table-cell;">middle</div>
登入後複製

效果如下:

left

right

middle

发现table-cell的宽度是根据内容自适应的,这里是要根据浏览器窗口自适应,因此给middle添加一个很大的width就可以了,例如width:2000px:

Action 10 让中间的div使用table-cell自适应宽度

left

right

middle

由于ie6/7不支持display: table-cell,所以如果要支持ie6/7的话,就得用display: inline-block,ie6/7的inline-block和标准不一样,它是用来触发hasLayout特性,使元素拥有布局属性。作用在行内元素,可以使得宽高等设置生效,如果作用在块元素,仅是触发布局特性,还要再设置成inline才是行内块元素,如果不设置inline效果就跟table-cell很像。不一样的地方是:设置了width:2000px,导致太长会换行,因此得用ie6/7的hack,设置*width: auto重新改会width值就可以了:

<style>    .middle{         display: table-cell;         *display: inline-block; /* _和*开头的只有ie6/7会识别 */         width: 2000px;         *width: auto;    }</style><div style="float:left;">left</div><div style="float:right;">right</div><div class="middle">middle</div>
登入後複製

但是笔者认为:为了互联网的美好,不要再兼容ie6/7了,甚至ie8。

接下来,继续第四种方法,使用flex布局,十分简单:只需要将容器设置为display: flex,然后再设置middle的flex-grow为1即可:

<section style="display:flex;"></section><div>left</div>   <!--宽度为100,省略--><div style="flex-grow: 1;">middle</div><div>right</div>
登入後複製

Action 11 使用flex-grow自适应宽度

left

middle flex-grow: 1

right

flex-grow: 1的作用是把middle的宽度置为flex容器的剩余宽度,就达到了自适应的目的。flex的使用不作全面介绍,详情可查看CSS-Tricks: A Complete Guide to Flexbox

但是flex布局ie的支持性较差,具体查看caniuse.

最后再分析另外一个自适应的例子,某个元素的宽度要根据其它元素的宽度自适应。如下图所示,排名的位数变化可能会很大,导致最右边的文字要自适应:

根据上面的一番分析,这个例子就不难实现了,如下面的分析,p标签里的文字宽度就能自适应了:

    <div style="width:320px;">        <span style="width:14px;<strong>float:left;</strong>">排名</span>        <span style="font-size:40px;<strong>float:left;</strong>">89</span>        <br />        <img  src="/static/imghw/default1.png"  data-src="..."  class="lazy"    style="max-width:90%"从三栏自适应宽度布局到css布局的讨论_html/css_WEB-ITnose" >float:left;</strong>"></img>        <p>你的好友会编程的银猪在土壕榜中排名89</p>    </div>
登入後複製

实际效果:

排名 1

你的好友会编程的银猪在土壕榜中排名1

排名 6783

你的好友会编程的银猪在土壕榜中排名6783

使用float是最简单的,还可以尝试使用flex布局,主要用到flex-shrink属性,flex-shrink的作用是定义收缩比例,容器内的子元素的宽度和若超出容器的宽度时,将按比例收缩子元素的宽度,使得宽度和等于容器的宽度。如下所示,将前面三个span/img的flex-shrink设置为0,而p的flex-shrink设置为1,这样子使得溢出的宽度都在p标签减去,就能够达到p标签宽度自适应的效果。

   <style>        span,img{<strong> flex-shrink: 0;</strong> }        p{<strong> flex-shrink: 1; </strong>}   </style>    <div style="display:flex;width:320px;">                                       <span style="width:14px;">排名</span>        <span style="font-size:40px;line-height:45px;">89</span>                <img  src="/static/imghw/default1.png"  data-src="..."  class="lazy"    style="max-width:90%" alt="从三栏自适应宽度布局到css布局的讨论_html/css_WEB-ITnose" ></img>        <p>你的好友会编程的银猪在土壕榜中排名89</p>    </div>
登入後複製

      实时效果:

排名 89

你的好友会编程的银猪在土壕榜中排名89

排名 1890

你的好友会编程的银猪在土壕榜中排名1890

 

 

       上文综合分析了最原始的table布局,然后就是float布局、table-cell、margin负值法、以及flex布局来实现自适应宽度的实现和原理,重点讨论了float的一些特性。如果上面的分析有错误,还望指正。

 

参考:

1. CSS Float Theory: Things You Should Know

2. CSS Tricks: All About Floats

3. CSS-Tricks: display

4. Understanding Floats

5. 视觉格式化模型

 

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1421
52
Laravel 教程
1315
25
PHP教程
1266
29
C# 教程
1239
24
了解HTML,CSS和JavaScript:初學者指南 了解HTML,CSS和JavaScript:初學者指南 Apr 12, 2025 am 12:02 AM

WebDevelovermentReliesonHtml,CSS和JavaScript:1)HTMLStructuresContent,2)CSSStyleSIT和3)JavaScriptAddSstractivity,形成thebasisofmodernWebemodernWebExexperiences。

HTML,CSS和JavaScript:Web開發人員的基本工具 HTML,CSS和JavaScript:Web開發人員的基本工具 Apr 09, 2025 am 12:12 AM

HTML、CSS和JavaScript是Web開發的三大支柱。 1.HTML定義網頁結構,使用標籤如、等。 2.CSS控製網頁樣式,使用選擇器和屬性如color、font-size等。 3.JavaScript實現動態效果和交互,通過事件監聽和DOM操作。

HTML:結構,CSS:樣式,JavaScript:行為 HTML:結構,CSS:樣式,JavaScript:行為 Apr 18, 2025 am 12:09 AM

HTML、CSS和JavaScript在Web開發中的作用分別是:1.HTML定義網頁結構,2.CSS控製網頁樣式,3.JavaScript添加動態行為。它們共同構建了現代網站的框架、美觀和交互性。

HTML,CSS和JavaScript的未來:網絡開發趨勢 HTML,CSS和JavaScript的未來:網絡開發趨勢 Apr 19, 2025 am 12:02 AM

HTML的未來趨勢是語義化和Web組件,CSS的未來趨勢是CSS-in-JS和CSSHoudini,JavaScript的未來趨勢是WebAssembly和Serverless。 1.HTML的語義化提高可訪問性和SEO效果,Web組件提升開發效率但需注意瀏覽器兼容性。 2.CSS-in-JS增強樣式管理靈活性但可能增大文件體積,CSSHoudini允許直接操作CSS渲染。 3.WebAssembly優化瀏覽器應用性能但學習曲線陡,Serverless簡化開發但需優化冷啟動問題。

HTML的未來:網絡設計的發展和趨勢 HTML的未來:網絡設計的發展和趨勢 Apr 17, 2025 am 12:12 AM

HTML的未來充滿了無限可能。 1)新功能和標準將包括更多的語義化標籤和WebComponents的普及。 2)網頁設計趨勢將繼續向響應式和無障礙設計發展。 3)性能優化將通過響應式圖片加載和延遲加載技術提升用戶體驗。

HTML與CSS vs. JavaScript:比較概述 HTML與CSS vs. JavaScript:比較概述 Apr 16, 2025 am 12:04 AM

HTML、CSS和JavaScript在網頁開發中的角色分別是:HTML負責內容結構,CSS負責樣式,JavaScript負責動態行為。 1.HTML通過標籤定義網頁結構和內容,確保語義化。 2.CSS通過選擇器和屬性控製網頁樣式,使其美觀易讀。 3.JavaScript通過腳本控製網頁行為,實現動態和交互功能。

HTML:建立網頁的結構 HTML:建立網頁的結構 Apr 14, 2025 am 12:14 AM

HTML是構建網頁結構的基石。 1.HTML定義內容結構和語義,使用、、等標籤。 2.提供語義化標記,如、、等,提升SEO效果。 3.通過標籤實現用戶交互,需注意表單驗證。 4.使用、等高級元素結合JavaScript實現動態效果。 5.常見錯誤包括標籤未閉合和屬性值未加引號,需使用驗證工具。 6.優化策略包括減少HTTP請求、壓縮HTML、使用語義化標籤等。

HTML的角色:構建Web內容 HTML的角色:構建Web內容 Apr 11, 2025 am 12:12 AM

HTML的作用是通過標籤和屬性定義網頁的結構和內容。 1.HTML通過到、等標籤組織內容,使其易於閱讀和理解。 2.使用語義化標籤如、等增強可訪問性和SEO。 3.優化HTML代碼可以提高網頁加載速度和用戶體驗。

See all articles