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

      如何实现一个三栏自适应布局,左右各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/imghwm/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/imghwm/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/imghwm/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
HTML的角色:构建Web内容HTML的角色:构建Web内容Apr 11, 2025 am 12:12 AM

HTML的作用是通过标签和属性定义网页的结构和内容。1.HTML通过到、等标签组织内容,使其易于阅读和理解。2.使用语义化标签如、等增强可访问性和SEO。3.优化HTML代码可以提高网页加载速度和用户体验。

HTML和代码:仔细观察术语HTML和代码:仔细观察术语Apr 10, 2025 am 09:28 AM

htmlisaspecifictypefodyfocusedonstructuringwebcontent,而“代码” badlyLyCludEslanguagesLikeLikejavascriptandPytyPythonForFunctionality.1)htmldefineswebpagertuctureduseTags.2)“代码”代码“ code” code code code codeSpassSesseseseseseseseAwiderRangeLangeLangeforLageforLogageforLogicIctInterract

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 08, 2025 pm 07:05 PM

HTML定义网页结构,CSS负责样式和布局,JavaScript赋予动态交互。三者在网页开发中各司其职,共同构建丰富多彩的网站。

HTML容易为初学者学习吗?HTML容易为初学者学习吗?Apr 07, 2025 am 12:11 AM

HTML适合初学者学习,因为它简单易学且能快速看到成果。1)HTML的学习曲线平缓,易于上手。2)只需掌握基本标签即可开始创建网页。3)灵活性高,可与CSS和JavaScript结合使用。4)丰富的学习资源和现代工具支持学习过程。

HTML中起始标签的示例是什么?HTML中起始标签的示例是什么?Apr 06, 2025 am 12:04 AM

AnexampleOfAstartingTaginHtmlis,beginSaparagraph.startingTagSareEssentialInhtmlastheyInitiateEllements,defiteTheeTheErtypes,andarecrucialforsstructuringwebpages wepages webpages andConstructingthedom。

如何利用CSS的Flexbox布局实现菜单中虚线分割效果的居中对齐?如何利用CSS的Flexbox布局实现菜单中虚线分割效果的居中对齐?Apr 05, 2025 pm 01:24 PM

如何设计菜单中的虚线分割效果?在设计菜单时,菜名和价格的左右对齐通常不难实现,但中间的虚线或点如何...

在线代码编辑器究竟用什么HTML元素实现代码输入?在线代码编辑器究竟用什么HTML元素实现代码输入?Apr 05, 2025 pm 01:21 PM

网页代码编辑器中的HTML元素分析许多在线代码编辑器允许用户输入HTML、CSS和JavaScript代码。最近,有人提出了一...

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境