CSS 中,用 float 和 position 的区别是什么?
CSS 中,用 float 和 position 的区别是什么?
呃,其实这个命题有误,只有position才是定位,float不能说是定位,不过你可以说这两种布局方式有什么不同。
float和position这两者并没有孰好孰不好的问题,两者按需使用,各得所需的效果。
float从字面上的意思就是浮动,这种在印刷排版之类中可能解释的更加贴切。float能让元素从文档流中抽出,它并不占文档流的空间,典型的就是图文混排中文字环绕图片的效果了。并且float这也是目前使用最多的网页布局方式。不过需要注意的是清除浮动是你可能需要注意的地方。并且如果你要考虑到古老的IE6之类的还会有一些bug诸如双边距等等问题。
而position顾名思义就是定位。他有以下这几种属性:static(默认),relative(相对定位),absolute(绝对定位)和fixed(固定定位)。其中static和relative会占据文档流空间,他们并不是脱离文档的。absolute和fixed是脱离文档流的,不会占据文档流空间。
比较可以发现,float和position最大的区别其实是是否占据文档流空间的问题。虽然position有absolute和fixed这两个同样不会占据文档流的属性,但是这两个并不适合被用来给整个网页做布局。为什么?因为这样你就得为页面上的每一个元素设置一个xy坐标来定位。
float布局就显得灵活多了。但是一些特殊的地方搭配relative和absolute布局可以实现更好的效果。因为absolute是基于父级元素的定位,当父级元素是relative的时候,absolute的元素就会是基于它的定位了。比如你可以让一个按钮始终显示在一个元素的右下角。
如果说到性能问题reflow问题,将元素的position设置为absolute和fixed可以使元素从DOM树结构中脱离出来独立的存在,而浏览器在需要渲染时只需要渲染该元素以及位于该元素下方的元素,从而在某种程度上缩短浏览器渲染时间。所以如果是制作js动画等,用absolute或者fixed定位会更好。
说得不好的地方请大家补充。总结一句就是不推荐用position来布局整个页面的大框架,而推荐用float或者文档流的默认方式。
贺师俊
在已有的回答中,我最赞同田乐。这里稍作补充。
在绝大多数Web开发者的语境中,“布局”这个术语和“排版”是有差异的。“布局”偏向于指宏观的GUI区域划分,比如双栏布局或三栏布局等。从这一点出发,float其实本不是一项用于“布局”的属性。float对应的其实是传统印刷排版中图文混排中的环绕。这其实可以理解,因为CSS的模型和术语脱胎于传统排版,故而与计算机GUI技术通常基于组件的模型相差甚远。除了float之外,另一个例子是CSS中上下margin的collapse,显然这是为了满足段落排版的需求。所以像float、margin collapse等,在典型的GUI技术中是没有的。还有,CSS box model中,width/height不算入padding和border,许多开发者对这点很不适应,这实际上是GUI的控件思维与CSS排版思维的冲突。这个冲突在浏览器技术实现上的遗迹就是IE臭名昭著的“hasLayout”。元素“has layout”的真实意思是这样的元素直接对应一个控件。也正是由于IE很naive的在实现中直接结合了这两种矛盾的模型,从而导致了无数的布局bug。
言归正传,CSS1时代的网页还很简陋,但是随着万维网的迅猛发展,Web界面也迅速进化,当初简单的如同书页般的通栏式网页迅速绝迹,frameset由于天生存在的一堆问题也很快退出主流,这时CSS在GUI布局方面就显出了缺陷,开发者被迫使用各种trick。比如历史悠久的table布局。后来table布局被鄙视,开发者逐渐转向了float布局。
要说float布局之所以流行,IE“功”不可没。在IE中,has layout的元素是不会环绕float元素的(因为has layout的元素自己是一个控件,所以总是保持一个矩形区域)。这本来是一个bug,但是其效果却正好符合常见的双栏布局的需要。另外IE下float元素会自动撑开其父级container元素(当然前提是container元素也是has layout的),这其实也是bug,但是也恰好符合模块布局的需求。后来所谓inline-block布局其实正是这些bug的合理化。
站在今天回望过去十多年的CSS实践,我们可以发现,无论float布局还是后来的inline-block布局,其实都是trick。所谓trick,就是将一些特性挪作他用,以很曲折的方式实现出想要的效果。CSS作为样式语言,其可维护性的最终来源,就是代码能清晰的表达出设计意图。而CSS trick当然不能很好的满足这一点。
那么如何才能真正用CSS来表达布局?如田乐所说,这有赖于“CSS3的进化”。如multiple column、flex box、grid layout等。其中直接对应目前float布局/inline-block布局所要达到效果的,是flex box。当然,考虑到兼容性问题(IE9仍不支持flex box模块,IE10才支持),我们可能很长时间内还是会继续使用float布局,不过必须始终牢记这是trick,是workaround。如有可能,最好引入SCSS/LESS之类的CSS框架来对此种布局trick做进一步抽象和解耦。
再说position布局。position其实比float要更接近“布局”属性。但是position的问题是,所谓布局是设定各区域(元素)的关联和约束,而定位只是设定单一元素的位置大小。要实现一个布局,要对多个定位元素中手动设定相关的参数(如左栏width:200px,右栏left:200px),相当于人为的把大小和位置参数计算出来。这违背了DRY原则,也无法真正实现关联约束。(如左栏设了max/min-width之后,最终实际width未必是200px,此时右栏怎么设left值?又如一个水平固定width、垂直自适应height的绝对定位元素,我们如何从它的底部继续排下一个元素?)除非我们引入JavaScript脚本来进行计算。因此运用position布局的限制条件相当多,通常只适合那些相对孤立的部件(如页头页脚)或较为简单且各区域大小位置固定的布局。至于说以JavaScript实现的布局管理器,是将position作为实现布局的底层技术,已经算不得CSS了(因为你也不写CSS)。
田乐
我补充一下float的问题。我们常说的文档流其实是指默认文档流。基本显示模型block和inline分别是块狀换行和连续多行模型,前者可以设定尺寸,后者不可以设定尺寸(根据内容决定尺寸和折行)。
不过我们总是遇到固定尺寸,或者固定部分尺寸且不折行的场景,这个时候我们马上会想到使用float来做布局,因为float会触发shrink to fit特性,实现根据内容决定尺寸,float还不会产生折行,我们通过clear来手工模拟折行。这个现状我觉得主要是因为对inline-block的兼容性顾忌产生的,在IE6的时候它没有被广泛支持。使用position实现这样的布局需要配合javascript修正,在某些场景它比float强,因为float模拟的流动布局不是多行连续布局,一些浮动元素经常因为意外的尺寸改变被卡在我们不希望它出现的位置。所以我们可以看到像pinterest这样的网站使用了javascript配合absolute position的方式,讲布局引擎的任务完全交给javascript来实现。从表现与行为分离的角度它不太合理,但是从结果上来说它很让人满意。
但是,我写这段的意思是说,很多时候我们希望控制的布局流问题不需要float和position实现,而应该通过显示模型定义来解决。比如现在的column layout、flex box等等,都是在这个角度解决我们遇到的问题,它们应该才是正解。而我们犯这个错误的最初原因也许就是对像inline-block这样的显示模型的不信任开始的。
希望CSS3的进化能够让我们重建这样的信任。
UPDATE: 我忘记说的就是如果你做移动的Web开发,那么你就知道为啥float很少在布局上使用。Android和iOS里面的flex box已经非常稳定了,很低版本(Android 1.6,iOS 3)就已经很好支持了,用这些布局模型在窄小且多样的手机屏幕上面相当可靠,而float在这些情况下则问题层出不穷。所以我现在相信mobile first,也相信移动设备的Web能够更好的推广CSS3的众多新特性的采用。比如新的CSS3 background and box module在移动设备里面几乎是必备的,因为background-size是retina display必用的,而border-image则是解决复杂的按钮和面板的最佳解决方案。如果你做Mobile Web,那么你就会爱上CSS3新特性,也会享受它带来的标准化的世界的好处。
来源: <http://www.zhihu.com/question/19588854>
CSS 中,用 float 和 position 的区别是什么?的更多相关文章
- [转][译]关于CSS中的float和position和z-index
原文:http://learn.shayhowe.com/advanced-html-css/detailed-css-positioning 当构建页面排版时,有不同的方法可以使用.使用哪一种方法取 ...
- [译] 关于CSS中的float和position
原文 http://learn.shayhowe.com/advanced-html-css/detailed-css-positioning 当构建页面排版时,有不同的方法可以使用.使用哪一种方法取 ...
- css中的float和position
1.float <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- css中的定位属性position(转)
css中的定位属性position 同样的也是上课的时候发现学生难以理解的一些问题拿出来记录一下,希望帮助初学者. 在css中定位属性position的运用在页面中是很常用的,特别是一些结合js来 ...
- 关于CSS中的float可能出现的小问题
关于CSS中的float可能出现的小问题 前言:最近学习CSS的float所遇到点小问题,然后顺便分享给大家. 一.什么是CSS以及float (一) CSS概述 CSS是层叠样式表(英文全称:Cas ...
- 如何理解css中的float
最近一段时间一直在为一个即将上线的新站进行一些前端开发.自然,对CSS的使用是必不可少的了.我们在CSS 中很多时候会用到浮动来布局.常见的有 float:left 或者 float:right .简 ...
- CSS中盒子模型和position(一)
今天遇到几个css中的重要的知识点,记得这些都是以前看过的:margin.padding.border和position.可是用起来还是有很多的问题,以前自己看过去总是懒得记录,等到用起来了都不知道自 ...
- css 中 的 float :left 和 clear :both
float:left;(左浮动)他使得指定元素脱离普通的文档流而产生的特别的布局特性.并且FLOAT必需应用在块级元素之上,也就是说浮动并不应用于内联标签.或者换句话来说当应用了FLOAT那么这个元素 ...
- css中的float属性以及清除方法 (2011-09-03 17:36:26)
CSS里面的浮动属性是布局的常用工具,只有真正了解它并熟练使用才能将它的优点发挥到极致. 许多页面中都有文字绕图效果,并且各区块分布得错落有置,很多朋友在自学CSS布局时为了做出这些效果往往会被div ...
随机推荐
- FFmpeg常用命令 (一)
常用参数说明: 主要参数:-i 设定输入流-f 设定输出格式-ss 开始时间视频参数:-b 设定视频流量,默认为200Kbit/s-r 设定帧速率,默认为25-s 设定画面的宽与高-aspect 设定 ...
- 升级后,使用dynamic报错
程序升级为.NET 4.0后,在程序中使用dynamic时出现下列错误 错误 5 预定义的类型“Microsoft.CSharp.RuntimeBinder.Binder”未定义或未导入错误 4 找不 ...
- java 内存管理机制
垃圾收集算法 1.标记清理算法:效率不高(标记和清理过程效率都不高).会形成内存碎片 2.复制算法:把内存分为两部分,当进行回收时,把使用部分的存活对象复制到未使用部分,然后两部分内存角色互换(一个为 ...
- Ladies' Shop
题意: 有 $n$ 个包,设计最少的物品体积(可重集),使得 1. 对于任意一个总体积不超过给定 $m$ 的物体集合有其体积和 恰好等于一个包的容量. 2.对于每一个包,存在一个物品集合能恰好装满它. ...
- Jacob开发文件转PDF
这三种方法我都有试过word转PDF,第2种.第3种对于图片,表格.中文转换效果都不好,方法1效果最好.但方法1 只支持Windows环境下. 1.开发环境 Windows系统: 2.准备工作: st ...
- nohup不输出日志信息的方法及linux重定向
最近使用nohup创建了一个后台进程,默认日志输出到了nohup.out文件中,程序跑起来也就没再管,过了大约一周,发现硬盘空间不够了,于是查找原因,发现这个nohup.out文件已经到了70G了,导 ...
- swift日期操作
简介:本文将介绍一些关于swift中对于日期的格式化与获取,支持swift4.0 extension Date { //格式化日期 func getDateString() -> String{ ...
- vue仿淘宝地址选择组件
Vue组件:省市区地址选择组件 <template> <div v-show="addressSelectShow" :style="{'left': ...
- CentOS Linux 7 提示 lsof: 未找到命令
我们常使用 lsof -i:端口号 命令来查看某端口是否开放,如使用下面的命令,查看8080端口: lsof -i: 结果: 提示:lsof:未找到命令 解决办法 使用yum来安装lsof,命令如下: ...
- Android真机调测Profiler
U3D中的Profile也是可以直接在链接安卓设备运行游戏下查看的,导出真机链接U3D的Profile看数据,这样能更好的测试具体原因. 大概看了下官方的做法,看了几张帖子顺带把做法记录下来. 参考: ...