内容简介:前言:前 10 篇文章,我们基本上都是在用“理论”学习“理论”,那从这篇开始,我们试着用“实践”来学习理论,然后又用于实践。一个原则:把代码拷贝到 JS Bin 上,对照效果搞懂每行代码的“是什么”、“为什么”、“怎么样”?假设我们需要有个东西,然后它的排版不是依照盒模型的定义——从上往下依次排列,而是从左到右这种结构,那么我们需要考虑到使用“浮动”。
本文推荐 PC 端阅读~ 本文版权归 “公众号 | 前端一万小时” 所有,未经授权,请勿转载! 复制代码
css_10 复制代码
1. 浮动元素有什么特征?对父容器、其他浮动元素、普通元素、文字分别有什么影响? 2. 清除浮动指什么?如何清除浮动?两种以上方法。 复制代码
前言:前 10 篇文章,我们基本上都是在用“理论”学习“理论”,那从这篇开始,我们试着用“实践”来学习理论,然后又用于实践。
一个原则:把代码拷贝到 JS Bin 上,对照效果搞懂每行代码的“是什么”、“为什么”、“怎么样”?
1 为什么需要“浮动”?
假设我们需要有个东西,然后它的排版不是依照盒模型的定义——从上往下依次排列,而是从左到右这种结构,那么我们需要考虑到使用“浮动”。
例如一个网站的头部,一部分在左边,一部分在右边。首先,“ 部分 ”的表示我们会用 div ,而 div 是块级元素,按理说它会从上到下,占据一整行,不可能整列排列。那这个时候我们就需要“浮动”。
2 “浮动”是怎么用的,有什么表现效果?
2.1 放不下会换行
一个“浮动盒”会向左或向右移动,直到其外边(outer edge)挨到 包含块边沿 或者另一个浮动盒的外边。如果没有足够的水平空间来浮动,它会向下移动,直到空间合适或者不会再出现其它浮动了。
html
<div class="ct"> <div class="box box1">1</div> <div class="box box2">2</div> <div class="box box3">3</div> </div> 复制代码
css
.ct { width: 280px; height: 300px; border: 1px solid; margin: 100px; } .box { color: #fff; width: 100px; height: 100px; background: red; float: left; /*:rocket:直接在你需要浮动的元素上加 float 属性。*/ } .box1{ background: blue; } .box2{ background: pink; } 复制代码
:vs:对比:
css
.ct { width: 280px; height: 300px; border: 1px solid; margin: 100px; } .box { color: #fff; width: 100px; height: 100px; background: red; float: right; } /*:rocket:站在浏览器的角度看,它会挨着顺序依次渲染*/ .box1{ background: blue; } .box2{ background: pink; } 复制代码
2.2 被卡住的情况
html
<body> <div class="ct"> <div class="box box1">1</div> <div class="box box2">2</div> <div class="box box3">3</div> </div> </body> 复制代码
css
.ct { width: 280px; height: 300px; border: 1px solid; margin: 100px; } .box { color: #fff; width: 100px; height: 100px; background: red; float: left; } .box1{ background: blue; height: 120px; } .box2{ background: pink; } /*依然站在浏览器的角度,从上往下渲染文档, 当依次渲染完 1、2 后,渲染 3 的时候,右边放不下, 然后他要被挤下去,挤下去后它会和 2 的下边缘开始向左移动移动碰到 1 右下角时,动不了了, 1 被卡住了。所以我们在设置高度不一样时,会出现一个“卡住”的问题。*/ 复制代码
2.3 当浮动元素与文本有交集的时候
html
<body> <div class="ct"> <div class="box box1">1</div> <p>挨到包含块边沿或者另一个浮动盒的外边。 如果存在行盒,浮动盒的外 top (边)会与当前行盒的 top (边)对齐。 如果没有足够的水平空间来浮动,它会向下移动,直到空间合适或者不会再出现其他浮动了。 </p> <div class="box box2">2</div> <div class="box box3">3</div> </div> </body> 复制代码
css
.ct { width: 280px; height: 300px; border: 1px solid; margin: 100px; } .box { color: #fff; width: 100px; height: 100px; background: red; float: left; } .box1 { background: blue; width: 140px; height: 120px; } .box2 { background: pink; } 复制代码
:trophy:可以得到:
普通流中的一个元素,如果没有设置定位和浮动,那它和浮动元素在一起之后,它会被浮动元素所遮挡。
:bulb:进一步验证:
css
.ct { width: 280px; height: 300px; border: 1px solid; margin: 100px; } .box { width: 100px; height: 100px; background: red; float: left; } .box1 { background: blue; height: 120px; width: 140px; opacity: 0.2; /*:rocket:设置透明度来观察*/ } .box2 { background: pink; } /*:rocket:但里边的文字并没有被这个浮动元素所遮挡,那他呈现的这个效果是: 这个段落 p 是看不到这个浮动元素的,而文字看得到,并且围绕这个浮动元素排列。 */ /*:rocket:即展现出来的一个规则就是: 当一个普通元素碰到一个浮动元素后,这个普通元素看不见这个浮动元素, 但普通元素里边的文字看得见这个浮动元素。 */ 复制代码
2.4 浮动元素脱离了普通流
脱离普通流是指:他的父容器在去计算宽高的时候,发现不了浮动元素。即,父容器不会被里面的浮动元素撑开;
:warning:注意:和 absolute 不一样。
html
<div class="ct"> <div class="box box1">1</div> <div class="box box2">2块盒看不见浮动的 box1,但我是文本我能看见</div> <div class="box box3">3</div> </div> 复制代码
css
.ct { width: 280px; height: 300px; border: 1px solid; margin: 100px; } .box { color: #fff; width: 100px; height: 100px; background: red; } .box1 { background: blue; float: left; opacity: 0.6; } .box2 { background: pink; height: 110px; width: 110px; } 复制代码
2.5 块级元素浮动宽度收缩,行内元素浮动以块级特性去呈现
html
<body> <div class="box">这是div</div> <span>这是span</span> </body> 复制代码
css
.box { color: #fff; float: left; background: red; } span { color: #fff; float: left; background: blue; width: 100px; height: 50px; margin: 10px; } /*:rocket:块级元素设置浮动之后,它就呈现出 inline-block 这种感觉,他的宽度会收缩。*/ /*:rocket:行内元素设置为浮动之后,它就呈现了块级的特性, 也有 inline-block 的感觉,就把行内元素变成可以设置宽高、margin 等, 但没有居中这些东西。 */ 复制代码
3 “浮动”的使用场景
3.1 两栏布局(左侧固定宽度,右侧自适应; 右侧固定宽度,左侧自适应)
html
<div class="aside">侧边栏固定宽度</div> <div class="main">内容区块自适应宽度</div> 复制代码
css
.aside { color: #fff; width: 150px; height: 400px; background: red; float: left; } .main { color: #fff; margin-left: 160px; /*:rocket:表示左边的这 160px 的范围我不用了*/ background: blue; height: 500px; } 复制代码
:vs:对比(右侧固定宽度,左侧自适应):
html
<div class="aside">侧边栏固定宽度</div> <div class="main">内容区块自适应宽度</div> 复制代码
css
.aside { color: #fff; width: 150px; height: 400px; background: red; float: right; } .main { color: #fff; margin-right: 160px; /*:rocket:表示右边的这 160px 的范围我不用了*/ background: blue; height: 500px; } 复制代码
3.2 三栏布局——两侧宽度固定,中间自适应(注意 HTML 中的 menu aside main 的顺序!)
html
<div class="menu">侧边栏固定宽度</div> <div class="aside">侧边栏固定宽度</div> <div class="main">内容区块自适应宽度</div> 复制代码
css
.menu { color: #fff; width: 150px; height: 400px; background: red; float: left; } .aside { color: #fff; width: 150px; height: 400px; background: red; float: right; } .main { color: #fff; margin-right: 160px; margin-left: 160px; /*:rocket:加左右 margin 就把位置撑开了*/ background: blue; height: 500px; } 复制代码
:warning:如果 HTML 中的 menu aside main 的顺序变了:
html
<div class="menu">侧边栏固定宽度</div> <div class="main">内容区块自适应宽度</div> <div class="aside">侧边栏固定宽度</div> <!--顺序一旦变了,后边的 aside 就会跳行,跑到下边去了。 原因:假设我是浏览器,我需要对着 html 来画出对应的图像, 首先画 menu ,结合其样式,左浮; 但这里我们遇到了 main ,这个 main 是一个块级元素,它会占据一整行的宽度; 那接下来的 aside 就只有在 main 的基础上往右下流动。--> 复制代码
css
.menu { color: #fff; width: 150px; height: 400px; background: red; float: left; } .aside { color: #fff; width: 150px; height: 400px; background: red; float: right; } .main { color: #fff; margin-right: 160px; margin-left: 160px; /*加左右 margin 就把位置撑开了*/ background: blue; height: 500px; } 复制代码
3.3 利用浮动实现“导航条”
3.3.1 “导航条”靠左
html
<ul class="navbar"> <li><a href="#">1首页</a></li> <li><a href="#">2产品</a></li> <li><a href="#">3服务</a></li> <li><a href="#">4关于</a></li> </ul> 复制代码
css
.navbar { list-style: none; } .navbar>li { float: left; margin-left: 15px; } /*:rocket:当然我们用 inline-block 也可以实现效果, 但不同方式需要注意的问题不一样: 使用浮动我们需要注意撑开容器;而用 inline-block 我们需要注意它的缝隙。 */ 复制代码
3.3.2 “导航条”靠右
html
<body> <ul class="navbar"> <li><a href="#">1首页</a></li> <li><a href="#">2产品</a></li> <li><a href="#">3服务</a></li> <li><a href="#">4关于</a></li> </ul> </body> 复制代码
css
.navbar { float: right; /*:rocket:把 ul 整体进行右浮动*/ list-style: none; } .navbar>li { float: left; /*:rocket:但 ul 里边的东西都是靠左的*/ margin-left: 15px; } 复制代码
:vs:对比:
html
<ul class="navbar"> <li><a href="#">1首页</a></li> <li><a href="#">2产品</a></li> <li><a href="#">3服务</a></li> <li><a href="#">4关于</a></li> </ul> 复制代码
css
.navbar { list-style: none; } .navbar>li { float: right; /*:rocket:直接改这里是不行的,因为站在浏览器的立场是按文档顺序来渲染的*/ margin-left: 15px; } 复制代码
4 清除“浮动”
4.1 为什么要清除浮动?
因为任何东西有利有弊。
4.1.1 第一,浮动对后续元素位置产生影响(渲染时,因为块元素看不见,但里边的文字看的见)
html
<div id="content"> <div class="menu">侧边栏固定宽度</div> <div class="aside">侧边栏固定宽度</div> <div class="main">内容区块自适应宽度</div> </div> <div id="footer">我是 footer,但我的样式出现了问题</div> 复制代码
css
.menu { color: #fff; width: 150px; height: 300px; background: red; float: left; } .aside { color: #fff; width: 150px; height: 300px; background: red; float: right; } .main { color: #fff; margin-right: 160px; margin-left: 160px; background: blue; height: 200px; } #footer { color: #fff; background: grey; } 复制代码
4.1.2 第二,父容器高度计算出现问题
html
<ul class="navbar"> <li><a href="#">1首页</a></li> <li><a href="#">2产品</a></li> <li><a href="#">3服务</a></li> <li><a href="#">4关于</a></li> </ul> 复制代码
css
.navbar { list-style: none; border: 1px solid #ccc; /*加一个背景色也没效果: background: pink;*/ } .navbar>li { float: left; margin-left: 15px; } /*:rocket:由于浮动元素脱离了文档流,所以他的父元素是看不见他的。 这里对于 navbar 来说,他认为里边没有什么 li 来把它撑开, 因为 li 已经浮动了,那没有东西撑开它,它就会认为高度为 0。*/ 复制代码
4.2 清除浮动的方法
4.2.1 清除浮动实现的原理和方法
html
<ul class="navbar"> <li><a href="#">1首页</a></li> <li><a href="#">2产品</a></li> <li><a href="#">3服务</a></li> <li><a href="#">4关于</a></li> <li class="clear"></li> <!-- :rocket:想解决这个没办法撑开的问题, 那么就要求这个源文档中要有一个没有被浮动的的元素——普通元素。--> </ul> 复制代码
css
.navbar { list-style: none; border: 1px solid #ccc; } .navbar>li { float: left; margin-left: 15px; } .navbar .clear { float: none; clear: left; } /*:rocket:通过清除浮动来获得一个普通元素,进而撑开这个父容器*/ 复制代码
- 清除浮动
clear: left;
——这个 clear 可以用在任何元素上,不管你是不是浮动元素。要求该盒的 top 、border 边位于源文档(就是 html 文档结构中)中 在此之前的元素形成的所有左浮动盒的 bottom 外边下方 (如果没有左浮动盒,那你清除左浮动也就没有意义)。 - 清除浮动
clear: right;
——要求该盒的 top border 边位于源文档中在此之前的元素形成的所有右浮动盒的 bottom 外边下方。 - 清除浮动
clear: both;
——只要源文档中该盒前边有浮动元素,那么就在这个浮动元素下方。
1. :vs:对比
我们上边是用一个造了一个 li
来实体化普通元素,那我们可否有更简化的方法——伪元素(伪元素的一个作用就是去代替标签)。
html
<ul class="navbar"> <li><a href="#">1首页</a></li> <li><a href="#">2产品</a></li> <li><a href="#">3服务</a></li> <li><a href="#">4关于</a></li> </ul> 复制代码
css
.navbar { list-style: none; border: 1px solid #ccc; } .navbar>li { float: left; margin-left: 15px; } .navbar::after { content: ''; /*:rocket:写了一个元素,你必须要有 content */ display: block; /*:rocket:注意这里如果没有这个 block ,是不会生效的, 因为写了 after ,只是表示是一个匿名的行盒,即一个字符串。 然而他必须是块级元素,他才会下去。*/ clear: both; } /*:rocket:用伪元素这样写就是表示: 我在源文档 navbar 的最后生成了一个 block 元素, 然后清除浮动,他就会位于浮动盒子的下方, 进而撑开了 navbar 这个父容器。*/ 复制代码
2. :vs:再对比
为了通用性,我们常常 .clearfix::after;
——就是为了修复浮动所产生的问题。
html
<ul class="navbar clearfix"> <!--:rocket:凡是需要清除浮动的地方我们都可以加一个这个样式就可以通用--> <li><a href="#">1首页</a></li> <li><a href="#">2产品</a></li> <li><a href="#">3服务</a></li> <li><a href="#">4关于</a></li> </ul> 复制代码
css
.navbar { list-style: none; border: 1px solid #ccc; } .navbar>li { float: left; margin-left: 15px; } .clearfix::after { /*:rocket:为了通用性,我们直接 clearfix ,然后在 HTML 文档中, 哪里需要清除浮动,就直接加一个这个类名进去就可以了。*/ content: ''; display: block; clear: both; } 复制代码
4.2.2 解决上边由“浮动”带来的问题
html
<div id="content" class="clearfix"> <!--:rocket:意思就是:这三个元素下边还有一个元素, 然后这个元素会在这三个元素的下方,进而就会撑开这个 content 。--> <div class="menu">侧边栏固定宽度</div> <div class="aside">侧边栏固定宽度</div> <div class="main">内容区块自适应宽度</div> </div> <div id="footer">我是 footer,但我的样式出现了问题</div> 复制代码
css
.menu { color: #fff; width: 150px; height: 300px; background: red; float: left; } .aside { color: #fff; width: 150px; height: 300px; background: red; float: right; } .main { color: #fff; margin-right: 160px; margin-left: 160px; background: blue; height: 200px; } #footer { color: #fff; background: grey; } .clearfix::after { /*:rocket:为了通用性,我们直接 clearfix , 然后在 HTML 文档中,哪里需要清除浮动,就直接加一个这个类名进去就可以了。*/ content: ''; display: block; clear: both; } 复制代码
:trophy:小总结:
所以以后我们想去实现一个水平布局,就有了两种方法:
- 第一,inline-block——不需要清除浮动,简单,在设置居中时更方便,适合子内容不多的元素水平排列。但要注意缝隙问题,以及对齐(上对齐);
- 第二,float——没缝隙问题,适合稍大的布局。但需要解决的问题是父元素不会被撑开而导致的很多问题。
5 浮动和负 margin
两个浮动元素,如果因放不下导致其中一个下移,对下移的元素设置负 margin 值大于自身的宽度可将其上移。
html
<div class="container"> <div class="box box1">box1</div> <div class="box box2">box2</div> </div> 复制代码
css
* { margin: 0 } .container { width: 400px; height: 400px; border: 1px solid red; } .box1 { width: 300px; height: 100px; background: pink; float: left; } .box2 { width: 110px; height: 100px; background-color: red; float: left; margin-left: -10px; /*:rocket:浏览器计算的时候就相当于宽度减去这个 10 ,然后就是 100,那就正好放上去。*/ } 复制代码
后记:下篇我们将讨论与“浮动”对应的“定位”是怎样让“盒子”动起来的。后续文章都是重中之重,每一篇都干货满满!
加油!
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
ASP.NET 4高级程序设计(第4版)
Matthew MacDonald / 博思工作室 / 人民邮电出版社 / 2011-6 / 148.00元
《ASP.NET 4高级程序设计(第4版)》,本书是ASP.NET领域的鸿篇巨制,全面讲解了ASP.NET4的各种特性及其背后的工作原理,并给出了许多针对如何构建复杂、可扩展的网站从实践中得出的建议。一起来看看 《ASP.NET 4高级程序设计(第4版)》 这本书的介绍吧!