ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

CSS 浮动(float)详解:从标准文档流到四种清除浮动方案——千古前端图文教程实战篇

CSS 浮动(float)详解:从标准文档流到四种清除浮动方案——千古前端图文教程实战篇 文档教程前端【免费下载链接】Web千古前端图文教程超详细的前端入门到进阶知识库。从零开始学前端做一名精致优雅的前端工程师。项目地址https://gitcode.com/gh_mirrors/we/Web点击查看免费下载本文是「千古前端图文教程」仓库中 02-CSS基础/07-浮动.md 的系统化实战解读。全文围绕「浮动float」这一个主题展开先讲清浮动的舞台——标准文档流再逐一剖析浮动的四大性质与真实布局案例随后给出工作中最高频的四种清除浮动方案及各自适用场景最后覆盖 IE6 时代的两个兼容性坑微型盒子、双倍 margin与浮动场景下的 margin 使用规范。读完本文你将能独立用浮动完成门户网站级的复杂页面布局并在面试中被问到「如何清除浮动」时给出完整、有层次的答案。一、前置基础标准文档流宏观地讲Web 页面和 Photoshop 等设计软件有本质区别Web 页面的制作是一个「流」必须从上而下、像「织毛衣」一样逐行排布而设计软件里想往哪儿画东西就能往哪儿画。理解了这个「流」才能理解浮动为什么存在。1. 标准文档流的三个特性1空白折叠现象无论多少个空格、换行、tab在标准流中都会被折叠为一个空格。比如想让img标签之间没有空隙就必须让它们紧密连接不能换行img srcimages/0.jpg /img srcimages/1.jpg /img srcimages/2.jpg /2高矮不齐底边对齐同一行里的元素即使高度不同其底边也会保持对齐。3自动换行一行写不满就换行继续写宽度占满时内容自动折到下一行。2. 行内元素和块级元素标准文档流「等级森严」标签分为两种等级行内元素与块级元素。例如h1是块级元素占据整行span是行内元素只占据内容本身的宽度。若给两者设置宽高会发现宽高属性只对块级元素h1生效。行内元素与块级元素的区别非常重要行内元素与其他行内元素并排不能设置宽、高默认宽度就是文字的宽度。块级元素霸占一行不能与其他任何元素并列能接受宽、高若不设置宽度则默认变为父亲宽度的 100%。两种分类口径从 HTML 角度标签分为文本级标签p、span、a、b、i、u、em容器级标签div、h系列、li、dt、dd。为什么p是文本级标签因为p里面只能放文字、图片、表单元素不能放h和ulp里面也不能再放p。从 CSS 角度分类与上面很像唯独p不同行内元素除p之外的所有文本级标签都是行内元素p是文本级但它是块级元素块级元素所有容器级标签都是块级元素再加上p标签。3. 行内元素和块级元素的相互转换通过display属性即「显示模式」可以在两者之间互相转换。块级元素转行内元素给一个div设置display: inline;这个标签立即变为行内元素此时它和一个span无异不能设置宽高但可以和别人并排。行内元素转块级元素给一个span设置display: block;这个标签立即变为块级元素此时它和一个div无异能够设置宽高必须霸占一行若不设置宽度则撑满父亲。标准流里面的限制非常多导致很多页面效果无法实现。如果既要并排、又要设置宽高该怎么办办法是「移民」——脱离标准流。CSS 中一共有三种手段使元素脱离标准文档流浮动float绝对定位absolute固定定位fixed定位相关的详细内容可参见仓库中 08-CSS属性定位属性.md。本文聚焦第一种手段浮动。二、浮动的性质浮动是 CSS 布局中用得最多的属性。两个设置了宽高的div默认上下排列一旦给它们加上float: left;两个元素立即并排并且都能设置宽度和高度——这在标准流中无法实现。要学好浮动必须掌握以下四个性质。性质1浮动的元素脱标「脱标」即脱离标准流。证明1默认情况下两个div上下排列给第一个div设置浮动后它跑到另一个层面上去排列而第二个div仍在自己的层面遵从标准流排列。证明2span在标准流中是行内元素不能设置宽高一旦设置为浮动即使不转成块级元素也能设置宽高了。由此可以总结一旦一个元素浮动了它就能并排、能设置宽高无论它原来是个div还是个span。所有标签浮动之后已经不再区分行内、块级。性质2浮动的元素互相贴靠给三个div均设置float: left;并指定宽高后改变浏览器窗口大小可以看到贴靠效果3 号如果有足够空间就靠着 2 号没有足够空间就靠着 1 号大哥连靠着 1 号的空间都不够3 号自己去贴左墙。注意3 号贴左墙的时候并不会往 1 号里面挤不会钻进 1 号的内部空间。float还有一个对称的属性值right逻辑与left完全镜像。性质3浮动的元素有「字围」效果让div浮动、p不浮动会发现div挡住了p但不会挡住p中的文字形成「字围」效果。总结成一句话标准流中的文字不会被浮动的盒子遮挡住文字就像水一样会绕着盒子流动。这一点在仓库 03-CSS进阶/02-CSS布局.md 中被更精确地概括为float 脱离文档流但不脱离文本流。div1浮动后不会对div2的布局造成影响但会影响div2中文字的排列——这正是 float 的原始设计用途图文混排、文字环绕。使用浮动时为避免混乱初期一定要遵循一个原则永远不是一个东西单独浮动要浮动大家都浮动。性质4收缩一个浮动的元素如果没有设置width会自动收缩为内容的宽度这点非常像行内元素。例如div本身是块级元素不设置width时会单独霸占整行设置浮动后它会收缩到与内容同宽。浮动的补充做网站时注意把para1、para2设为浮动它们是父div的儿子。若para1 para2的宽度小于父div的宽度两者并排显示若para1 para2的宽度大于父div的宽度para2就会掉下来换行——这印证了性质 2 中「空间不足就贴靠上一级/换行」的规则。实战作业用浮动还原一个门户网站的头部布局下面的作业要求用浮动实现一个典型的门户页面头部左侧 logo、右侧语言选择与导航条下方再排 banner、新闻区、热点图与页尾。这是理解「浮动 并排 宽高可设」的最佳练习完整代码如下!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd html xmlnshttp://www.w3.org/1999/xhtml xml:langen head meta http-equivContent-Type contenttext/html;charsetUTF-8 titleDocument/title style typetext/css *{ margin: 0; padding: 0; } .header{ width: 970px; height: 103px; /*居中。这个语句的意思是居中*/ margin: 0 auto; } .header .logo{ float: left; width: 277px; height: 103px; background-color: red; } .header .language{ float: right; width: 137px; height: 49px; background-color: green; margin-bottom: 8px; } .header .nav{ float: right; width: 679px; height: 46px; background-color: green; } .content{ width: 970px; height: 435px; /*居中这个语句今天没讲你照抄就是居中*/ margin: 0 auto; margin-top: 10px; } .content .banner{ float: left; width: 310px; height: 435px; background-color: gold; margin-right: 10px; } .content .rightPart{ float: left; width: 650px; height: 435px; } .content .rightPart .main{ width: 650px; height: 400px; margin-bottom: 10px; } .content .rightPart .links{ width: 650px; height: 25px; background-color: blue; } .content .rightPart .main .news{ float: left; width: 450px; height: 400px; } .content .rightPart .main .hotpic{ float: left; width: 190px; height: 400px; background-color: purple; margin-left: 10px; } .content .rightPart .main .news .news1{ width: 450px; height: 240px; background-color: skyblue; margin-bottom: 10px; } .content .rightPart .main .news .news2{ width: 450px; height: 110px; background-color: skyblue; margin-bottom: 10px; } .content .rightPart .main .news .news3{ width: 450px; height: 30px; background-color: skyblue; } .footer{ width: 970px; height: 35px; background-color: pink; /*没学就是居中*/ margin: 0 auto; margin-top: 10px; } /style /head body !-- 头部 -- div classheader div classlogologo/div div classlanguage语言选择/div div classnav导航条/div /div !-- 主要内容 -- div classcontent div classbanner大广告/div div classrightPart div classmain div classnews div classnews1/div div classnews2/div div classnews3/div /div div classhotpic/div /div div classlinks/div /div /div !-- 页尾 -- div classfooter/div /body /html本案例的布局思路在仓库 08-前端基本功/01-CSS基础练习JD首页的制作顶部和底部.md 中有完整工业化复现——京东首页正是典型的「版心 左浮动 右浮动」组合其中定义了公共类.fl { float: left; } .fr { float: right; } .w { /* 版心可视区 */ width: 1210px; margin: 0 auto; }这种把.fl/.fr提取为公共类的做法正是「浮动都是一起浮动」原则在工程中的落地。三、浮动的清除这里所说的「清除浮动」指的是清除浮动与浮动之间的影响。从学习浮动的第一天起就要明白浮动有开始就要有清除。问题实验为什么会互相影响先看一个简单实验两个块级元素div每个div里各有一组li默认上下排列。可如果给里面的li加浮动效果完全变了!DOCTYPE html html langen head meta charsetUTF-8 titleDocument/title style typetext/css li{ float: left; width: 100px; height: 20px; background-color: pink; } /style /head body div classbox1 ul li生命壹号1/li li生命壹号2/li li生命壹号3/li li生命壹号4/li /ul /div div classbox2 ul li许嵩1/li li许嵩2/li li许嵩3/li li许嵩4/li /ul /div /body /html结果发现第二组中的第 1 个li跑去贴靠第一组中的最后一个li了——我们本以为这些li会分成两排。由此引出清除浮动的第一种方式。方法1给浮动元素的祖先元素加高度造成上述现象的根本原因是li的父亲div没有设置高度导致两个div的高度均为 0px可通过浏览器审查元素查看。div高度为零就不能给自己浮动的孩子撑起一个容器孩子也就无法在自己的内部正确浮动。即便给div设置了高度如果高度小于孩子的高度仍会出现不正常现象给div设置一个合适的高度至少大于儿子高度现象即恢复正常。总结过来人的经验之语如果一个元素要浮动那么它的祖先元素一定要有高度。有高度的盒子才能关住浮动。只要浮动在一个有高度的盒子中这个浮动就不会影响后面的浮动元素也就清除了浮动带来的影响。方法2clear: both;实际网页制作中height其实很少出现——因为盒子能被内容撑高方法 1 在工作中用得很少。那么能不能不写height也清除浮动、让浮动之间互不影响答案是用clear: both;clear: both;clear就是清除both指左浮动、右浮动都要清除。clear: both;的意思是不允许左侧和右侧有浮动对象。但这种方法有一个非常大的、致命的问题它所在的标签margin属性失效了读者可以亲自验证。margin失效的本质原因是示例中的box1和box2高度为零。方法3隔墙法外墙法与内墙法既然新的清除元素无法设置margin可以在两个div中间用一个新div隔开给新div设置clear: both;同时因为新div无法设置margin就给它设置height以达到margin的效果曲线救国。这便是隔墙法外墙法。近些年又演化出内墙法一个父亲是不能被浮动的儿子撑出高度的。比如在一个div里放一个有宽高的p正常显示给p设置浮动后父亲的div却没有高度了此时在div的里面放一个div作为内墙父亲div就能恢复高度。与外墙法相比内墙法的优势本质区别在于内墙法可以给它所在的家撑出高度让box1有高即box1的高度可以自适应内容而外墙法虽然一道墙能把两个div隔开但这两个div依然没有高度无法 wrap_content。方法4overflow: hidden;overflow即「溢出」hidden即「隐藏」该属性的本意是「溢出隐藏」——所有溢出边框的内容都要隐藏掉。前端工程师发现它能当偏方用一个父亲不能被自己浮动的儿子撑出高度但只要给父亲加上overflow: hidden;父亲就能被儿子撑出高了。对于前言中的例子同样可以使用这一属性且它能让margin生效。这一招实际上生成了BFCBlock Formatting Context块级格式化上下文。关于 BFC 的详细解释可参见仓库 03-CSS进阶/CSS面试题.md其中还提到overflow:hidden可以取消父子 margin 合并与 03-CSS进阶/02-CSS布局.md。四种清除浮动方法的总结与对比浮动的元素只能被有高度的盒子关住——如果盒子内部有浮动、这个盒子有高那么浮动不会互相影响。四种方法对比如下1、加高法div //设置height p/p p/p p/p /div div //设置height p/p p/p p/p /div工作上绝不会给所有盒子加高度麻烦且不能适应页面的快速变化。2、clear: both; 法最简单的清除浮动方法给盒子增加clear: both;表示自己的内部元素不受其他盒子的影响div p/p p/p p/p /div div //clear:both; p/p p/p p/p /div浮动确实被清除了不会互相影响但margin失效两个div之间没有任何间隙。3、隔墙法在两部分浮动元素中间建一堵墙隔开两部分浮动让后面的浮动元素不去追前面的浮动元素墙用自己的身体当作间隙div p/p p/p p/p /div div classcl h10/div div p/p p/p p/p /div隔墙法好用但第一个div还是没有高度。想让第一个div自动根据儿子撑出高度就用内墙法div p/p p/p p/p div classcl h10/div /div div p/p p/p p/p /div内墙法的优点不仅让后部分的p不去追前部分的p还能把第一个div撑出高度使背景、边框能根据p的高度撑开。4、overflow: hidden;本意是将所有溢出盒子的内容隐藏掉但可用于清除浮动一个父亲不能被自己浮动的儿子撑出高度加上overflow: hidden;后父亲就能被儿子撑出高度浏览器偏方原理层面由 BFC 解释。并且overflow:hidden;能够让margin生效。清除浮动的经典应用场景无序列表要求实现无序列表两行排列的效果时ul中不能插入div墙ul中只能插入li插li当墙会浪费语义内墙法也不美观。综合对比用第四种方法最合适标签极其干净整洁ul { overflow: hidden; } ul li { float: left; }如果没有加overflow: hidden;第二行的li会紧跟在第一行li的后面。现代推荐做法clearfix仓库中的京东首页实战 08-前端基本功/01-CSS基础练习JD首页的制作顶部和底部.md 使用的正是工程界最主流的 clearfix 方案写在爸爸身上左浮动、右浮动都清除盒子刚好达到闭合状态/*start:清除浮动【推荐此方式进行清除浮动】*/ .clearfix:before, .clearfix:after { content: ; display: table; } .clearfix:after { clear: both; } .clearfix { *zoom: 1; /*IE/7/6*/ } /*end清除浮动*/而 03-CSS进阶/CSS面试题.md 给出了精简面试版.clearfix::after { content: ; display: block; clear: both; } /* 兼容 IE */ .clearfix { zoom: 1; }两者的核心思想一致通过::after伪元素在父元素末尾生成一个clear: both的块级「内墙」从而让父元素被浮动的子元素撑出高度同时用zoom: 1触发 IE 的 hasLayout 机制做兼容。四、浏览器的兼容性问题下面讲上述知识点涉及到的浏览器兼容问题主要是 IE6 时代遗留的两个经典坑。兼容性1IE6 不支持微型盒子IE6 不支持小于 12px 的盒子任何小于 12px 的盒子在 IE6 中看起来都会变大。例如一个height: 5px; width: 200px的盒子IE8 与 IE6 显示效果不同。解决办法将盒子的字号大小设置为小于盒子的高。比如盒子高为 5px就把font-size设置为 0px0px 5pxheight: 5px; _font-size: 0px;这里用到了浏览器 hack。hack 就是「黑客」指使用浏览器留下的后门针对某一种浏览器做兼容。IE6 留了一个后门只要给 CSS 属性之前加上下划线这个属性就是 IE6 的专有属性如_background-color: green;只对 IE6 生效。于是微型盒子的正确写法注意不要忘记下划线height: 10px; _font-size:0;兼容性2IE6 不支持用 overflow: hidden 清除浮动overflow: hidden;的本意是让溢出盒子 border 的内容隐藏这个功能 IE6 是兼容的不兼容的是「用overflow:hidden;清除浮动」这一用法。解决办法是以毒攻毒追加一条_zoom:1;overflow: hidden; _zoom:1;实际上_zoom:1;能触发浏览器的hasLayout机制该机制只有 IE6 涉及具体实现可自行查阅不必深究让 IE6 也能正常清除浮动。总结上述两个 IE6 兼容问题都是通过多写一条 hack 解决的这被称为伴生属性——两个属性要写一起写/* 属性1微型盒子 */ height:6px; _font-size:0; /* 属性2overflow 清除浮动 */ overflow:hidden; _zoom:1;五、浮动中的 margin 相关1. margin 塌陷 / margin 重叠标准文档流中竖直方向的 margin 不叠加取较大的值作为 margin水平方向的 margin 可以叠加即水平方向没有塌陷现象。如果不在标准流中——比如盒子都浮动了——那么两个盒子之间就没有塌陷现象。2. 盒子居中 margin: 0 auto;margin的值可以为auto表示自动。当left、right两个方向都是auto时盒子居中margin-left: auto; margin-right: auto;简写为margin: 0 auto;理解上下的 margin 为 0左右的 margin 都尽可能大于是盒子就居中了。注意三点1只有标准流的盒子才能使用margin:0 auto;居中。当一个盒子浮动了、绝对定位了、固定定位了都不能使用margin:0 auto;。2使用margin:0 auto;的盒子必须有明确的 width若没有明确的 width它的 width 就是霸占整行居中没有意义。3margin:0 auto;是让盒子居中不是让盒子里的文本居中。文本居中要使用text-align:center;。对第三条总结非常重要margin:0 auto; /* 让这个div自己在大容器中的水平方向上居中 */ text-align: center; /* 让这个div内部的文本居中 */顺带补充text-align还有text-align:left; //没啥用因为默认居左 text-align:right; //文本居右3. 善于使用父亲的 padding而不是儿子的 margin来看一个奇怪的现象。结构为「div中放一个p」时尝试通过给儿子p一个margin-top:50px;让其与父亲保持 50px 上边距结果却看到父亲整体掉下来了。而给父亲div加一个border属性后现象就正常了。原因如果父亲没有border儿子的margin实际上「踹」的是流、踹的是这一行所以父亲整体也掉下来了。margin这个属性本质上描述的是兄弟和兄弟之间的距离最好不要用margin表达父子之间的距离。如果要表达父子之间的距离一定要善于使用父亲的padding而不是儿子的margin。盒模型的 padding、border、margin 体系可参见 06-CSS盒模型详解.md。六、关于 margin 的 IE6 兼容问题1. IE6 的双倍 margin bug当出现连续浮动的元素携带与浮动方向相同的 margin时队首的元素会双倍 margin。例如ul li/li li/li li/li /ul解决方案有两个1使浮动的方向和 margin 的方向相反。这也是前端工程师特别喜欢的写法并已形成习惯float: left; margin-right: 40px;2使用 hack没必要别惯着 IE6单独给队首的元素写一个一半的 marginli classno1/liul li.no1{ _margin-left:20px; }PS双倍 margin 的问题面试经常问。2. IE6 的 3px bugIE6 在浮动元素相邻处会出现约 3px 的间隙 bug。解决办法不用管——因为代码规范本就不允许用儿子踹父亲描述父子之间的距离请用padding而不是margin。如果出现了 3px bug说明你的代码不标准。总的来说IE6 不要跟它死坑、较劲。讲 IE6 的兼容性问题是为了增加面试的成功率而不是为了成为 IE6 的专家。七、补充知识Fireworks 与文本细节Fireworks 标尺快捷键Ctrl Alt R。Fireworks 是 Adobe 公司的设计软件功能非常多默认文件格式是 png。首行缩进两个汉字text-indent: 2em;em是一个汉字当前字号的宽度indent的意思是缩进。八、小结与延伸阅读本文完整覆盖了浮动的完整知识链标准文档流的三个特性与行内/块级元素体系 → 浮动的四大性质脱标、贴靠、字围、收缩→ 四种清除浮动的方法加高法、clear: both;、隔墙法/内墙法、overflow: hidden;及其工程化升级版 clearfix → IE6 的两个兼容性坑微型盒子、overflow:hidden清除浮动失效→ 浮动场景下的 margin 规则塌陷、居中三注意、父子距离用 padding→ IE6 的双倍 margin 与 3px bug。在此基础上若想继续深入推荐按以下路径延伸阅读仓库内的关联文档02-CSS布局.mdfloat 布局的工程定位float margin 兼容低版本 IE曾被腾讯新闻、网易新闻、淘宝等大量采用、float 对自身/兄弟/父级元素的完整影响清单以及 inline-block、flex 等替代布局方案。CSS面试题.mdBFC 的面试答案与 clearfix 精简写法。JD首页的制作顶部和底部.md在真实门户级页面上综合运用浮动、clearfix 与版心布局。06-CSS盒模型详解.md理解 padding、border、margin 对盒子真实占有宽高的影响是掌握本文 margin 规范的前提。08-CSS属性定位属性.md掌握与浮动并列的另外两种脱标手段绝对定位、固定定位。赞分享文档教程前端【免费下载链接】Web千古前端图文教程超详细的前端入门到进阶知识库。从零开始学前端做一名精致优雅的前端工程师。项目地址https://gitcode.com/gh_mirrors/we/Web点击查看免费下载相关推荐CSS 布局全攻略display、position、float 与 Flex 布局实战千古前端图文教程CSS 布局全攻略display、position、float 与 Flex 布局实战千古前端图文教程 本文是「千古前端图文教程」中 03 CSS进阶/0文档教程前端assistant-ui 接入 AG-UI 协议使用 assistant-ui/react-ag-ui 驱动标准 React 聊天组件assistant ui 接入 AG UI 协议使用 assistant ui/react ag ui 驱动标准 React 聊天组件 本指南围绕 assi文档教程前端华为/CANN分配块缓存函数 allocate\_blocks\_cache 产品支持情况 Atlas A3 训练系列产品/Atlas A3 推理系列产品支持 Atlas A2 推理系人工智能深度学习模型编译模型优化编译器Ascend上一篇终极Android图片处理指南使用TakePhoto轻松实现拍照、裁剪与压缩下一篇archinstall数字取证Autopsy与The Sleuth Kit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表