前端css布局知识复杂,实现方法五花八门。要想写出高效合理的布局,必须要有扎实的CSS基础。为了方便记忆和复习,将CSS布局的要点记录如下。内容很多,应用不是很详细,但都是很实用的点。所谓布局,就是把元素设置成我们想要的大小,放在我们想要的位置上。位置和尺寸是核心的两个要素。这些元素其实就是一些方块,页面就是由各种方块组成的。现在主要有三种布局方式:传统的CSS布局方案(position、float、line-height等)。实现复杂,需要多个属性一起使用,兼容性最好。弹性布局方案。布局灵活,易于实施,兼容性好。网格布局方案。使用哪种布局方式取决于项目的具体要求。如果不需要兼容IE,推荐使用flex或者grid。这两个是未来的趋势。如果要考虑兼容性,最好使用传统的css布局方案。传统的css布局方案css标准盒模型前面说了,一个html元素就是一个盒子,再仔细一点,就是盒模型。盒子模型是这样的:我们可以在chrome开发者工具的styles中查看:css盒子模型,分为4部分:content:显示元素内容区域,包括子元素padding:内容区域到的距离border,又称内边距border:显示自己的外边距margin:用来设置元素本身与同级元素或父元素之间的距离。所有的html元素都是按照一定的规则排列和渲染的。在HTML中,不仅有一种规则,而且有多种规则。了解这些渲染规则以及这些规则生效的条件,对我们理解css有很大的帮助。文档流文档流可以理解为所有元素的默认渲染规则。它的规则很简单:元素按照各自类型的布局特点从左到右,从上到下排列。元素在布局上分为三种:块级元素:默认占据一整行,即使设置了宽度,仍然占据一整行,辅以margin(霸道总裁)、block、table、flex、grid,list-item内联元素:宽度被内容扩展,只占自己的位置。即使设置了宽度,它也不起作用。边距也适用于左右,但不适用于上下(每位女士)。inline内联块级元素有:width由内容打开,它只占据自己的位置,可以设置自己的宽度(两人的孩子?),有inline-block,inline-table,inline-flex,和内联元素上方的内联网格。其实是不对的,这里要特别说一下,内联元素分为两种:可替换内联元素:该元素显示的内容不在css范围内,典型的如img、video、object、input、textarea等,显示内容由src、value等决定,这个元素可以设置宽高。不可替换的内联元素:普通的内联元素,比如span、a、i、em等,可以通过两种方式脱离文档流,绝对定位和浮动,我们下面详细说说。BFCBFC的全称是BlockFormattingContext,块级格式化上下文。BFC环境中的元素按照以下规则进行渲染:和文档流一样,元素按照自身类型的布局特点从左到右,从上到下依次排列。BFC是一个独立的、封闭的渲染区域。子元素的样式对BFC的外部有影响。BFC可以识别浮动子元素。BFC可以识别浮动的兄弟元素。使用它来制作灵活的布局。那么BFC是什么样的渲染区域呢?一个BFC的渲染区域可以通过以下方式显示和声明:根元素或包含根元素的元素的值不是noneposition是absolute的或者fixedoverflow的值不是visibledisplay是inline-block,table-cell,table-captionsizeelement的大小有两种情况:默认情况:块级元素默认宽度为100%,高度被内容展开;内联元素和内联块级元素的宽度和高度默认按内容扩展。DeveloperSettings:主动设置width,height,line-height等。先搞清楚元素的尺寸概念。我们都知道元素的盒子模型。元素由四个区域组成:内容、填充、边框和边距。那么大小到底是什么意思呢?我们可以将大小分为三类:元素大小:由内容、填充和边框组成。在原生DOMAPI中,使用offsetWidth和offsetHeight获取元素的内部尺寸:由content和padding组成。在原生DOMAPI中,使用clientWidth和clientHeight获取元素的外部尺寸:由content、padding、border和margin组成。没有对应的DOMAPI,但是理解这个对布局很有帮助。我们在css中设置的宽度和高度代表哪部分区域是模糊的。我们可以通过设置box-sizing来切换width和height所代表的区域。box-sizingbox-sizing,可以切换宽高表示的区域。box-sizing主流浏览器有两个值:content-box:width和height设置内容的宽度和高度border-box:width和height设置内容的宽度和高度,padding,border结合这两个属性导致歧义width和height,很多情况下是全局设置的,非常隐蔽,新手容易混淆。这两个属性的产生有一定的历史原因。最初的盒子模型默认使用border-box,早期的IE就是这样,也称为IE盒子模型。后来W3C觉得content-box更好,把盒子模型改成了默认的content-box模式。后来随着灵活布局的流行,border-box的优势越来越明显。大家更愿意用border-box来布局,W3C也想找回border-box。但是,现在已经有很多基于内容框的网站,不能为了兼容而随便改动。所以W3C想出了box-sizing的方法,支持border-box,但默认还是content-box。使用box-sizing需要注意的地方:全局添加box-sizing:border-box,注意第三方组件库的侵入,因为第三方组件很可能是基于content-box布局,设置所有元素的box-sizing属性是inherit:*,*:before,*:after{box-sizing:inherit;}这样我们就可以设置父元素的box-sizing,控制所有元素的box-sizing属性子元素。对于我们封装的Components来说,搭建整个组件环境是非常方便的,只要我们在封装组件的时候强行设置box-sizing,就不怕全局样式入侵了。content-box模式可以使用calc属性辅助设置弹性布局,或者设置两层div的大小百分比来设置包含块。我们知道宽高可以用百分比来设置,那么这个百分比的参考对象是谁呢?这里有一个概念叫做包含块(CB,ContainingBlock)。元素的包含块是元素的宽高百分比的引用对象。很多新手同学在设置宽高百分比的时候有时会觉得莫名其妙,各种奇怪的现象怎么设置都不行。其实并没有包含块的概念。谁是一个元素的包含块主要取决于该元素的position属性,总结如下:对于position为static和relative的元素,包含块是父元素的content-box位置为absolute的元素,而thecontainingblock是它最近的位置非静态祖先元素的padding-box,如果非静态祖先元素没有定位,它是初始包含块(后面解释)位置固定的元素,包含块是当视口位置是绝对且固定时的视口,包含块也可能是满足以下条件的最近父元素的填充框:除none之外的变换或透视值变换或透视的will-change值过滤器valueotherthannoneorawill-changevalueoffilter(onlyworksonFirefox)这一项比较特殊,遇到的情况比较少。除了width和height相对于包含块的百分比之外,margin和padding的百分比也是相对于包含块设置的,只不过margin和padding的百分比是相对于包含块的。宽度设置(在水平模式下)。绝对定位的偏移属性top、left、right、bottom也是相对于包含块设置的,后面会详细介绍。初始包含块元素的包含块是自己的祖先元素,那么hmtl元素没有祖先元素,其百分比设置是相对的?是初始包含块,根元素(hmtl)所在的包含块是一个矩形,称为初始包含块。这个矩形的大小就是浏览器视口的大小。需要注意的一件事是那些不以非静态祖先元素为目标的引用是初始包含块,而不是html元素。Margin因为margin在布局中有一些重要的特点和特殊情况,所以我们单独说一下。margin:auto我们知道,即使设置了块级元素的宽度,它也会占据一整行。为什么会这样?谁占据了剩余的空间?这里要明确一点,一个块级元素占一行,也就是说块级元素的外部尺寸占一行,也就是margin-box。当margin设置为auto时,margin将自动填充剩余空间。margin-left:默认为0,当为auto时,会自动填充剩余空间margin-right:默认为0,当为auto时,会自动填充剩余空间margin-top:默认为0,当为auto时,该值仍为0margin-bottom:默认为0。当为auto时,该值仍为0。当margin-left和margin-right同时为auto时,剩余空间将平分。这就是margin:auto将元素水平居中的原因。那么margin:auto不能让元素垂直居中,因为在垂直方向上,块级元素不会自动展开,它的外部尺寸不会自动填满父元素,没有剩余空间可言。如果我们在父元素上设置writing-mode:vertical-lr,那么margin:auto会使子元素垂直居中,但是水平居中无效。有什么方法可以使用margin:auto使元素水平和垂直居中?答案是肯定的,就是在绝对定位的情况下。.father{宽度:300px;高度:150px;位置:相对;}.son{位置:绝对;顶部:0;右:0;底部:0;左:0;宽度:200px;高度:200px;;}这时候son的外部尺寸会自动填满它的包含块,效果和块级元素差不多。这时候如果给.son元素设置宽高,就会有剩余空间,margin:auto会自动平分剩余空间,让.son水平和垂直居中。Margin对元素的布局有两个影响:影响内部尺寸,影响外部尺寸,影响元素内部尺寸,块级元素,是一种布局特性,会自动填充宽度方向的空间,当没有设置宽度,设置margin-left和margin-right来影响元素的内部空间。当margin为正值时,元素尺寸减小;当边距为负值时,元素大小增加。因为元素的外部尺寸已经确定,就是它的包含块的尺寸,外部尺寸等于元素尺寸加上边距。如果边距为负,元素大小自然会增加。利用内部尺寸增加而外部尺寸不变的特性,我们可以对等距列表进行布局。比如我们实现一个一行三列的布局,两边没有空隙,中间有20px的空隙:.father{margin-right:-20px;}.son{width:calc(calc(100%-20px*3)/3);margin-right:20px;}影响元素的外部尺寸当元素的宽高固定时,相当于元素固定尺寸,margin开始影响元素的外部尺寸。正边距会增加元素的外部尺寸,负边距会缩小元素的外部尺寸。这很容易理解,我就不说了。主要讲负值。这时候margin-top、margin-left、margin-right、margin-bottom的表现看似不同,其实本质是一样的。当margin-top和margin-left为负值时,表示元素向上或向左移动;当margin-right和margin-bottom为负值时,表示右边或下面的元素将相应地向左或向上移动。仔细想想,这是元素外部尺寸缩小的一种表现。margin-top和margin-left使得左边上边和上边的尺寸缩小,自然会向左或向上移动。margin-right和margin-bottom缩小了右边和底边的尺寸,旁边和下面的元素自然会占据左边或上面的空间。margin在某些情况下合并块级元素的顶部和底部边距。需要注意的是,浮动元素和绝对定位元素不会合并,合并只会发生在垂直方向。有以下3种合并场景。当相邻兄弟元素的父元素和第一个/最后一个元素为空时,高度为0,用户的上下外边距将合并。保证金合并的计算规则有正负之分。添加negativeparent和取small(-20px,-50pxmergeandtake-50px)防止marginmerge把合并后的元素变成BFC,比如设置display:inline-block,overflow:hidden,float:left和其他父子合并/空元素合并时,给父元素/空元素设置border和padding可以防止合并内联元素的大小。主要想说两个属性,line-height和vertical-align。这两个属性对高度有重要的影响,如果不了解这两个属性的作用,往往会遇到一些比较奇怪的布局问题,不好解决。ghostblanknode这个名字是张新旭定义的,在W3C规范中也可以找到。一书中,为了证明ghostblank节点的存在,举了一个例子:div{background-color:#cd0000;}span{display:inline-block;}
