基础知识篇:https://blog.csdn.net/sysukehan/article/details/105927012
使子元素处于父元素的中心位置
效果图:
方法一:flex+margin
弹性元素中margin属性自动获取横向和纵向的剩余空间(margin-left: auto使行内所有剩余空间集中在左侧)。在这个例子中,横向看,行内只有一个元素,所以剩余空间左右均匀分布。纵向看,只有这一行,因此这一行撑满整个父元素的高度,同时纵向的剩余空间上下均匀分布,实现横向纵向都居中。
方法二:flex+justify-content+align-items
justify-content使行内元素水平居中,align-items使行内元素竖直居中,在只有一行的情况下实现中心居中。把父元素的align-items: center替换成在子元素中设置align-self: center,效果相同。
方法三:relative+偏移量计算
position: relative可以相对自己原本的位置进行向右向下偏移,在一些距离固定的场景下可以使用这种方法,缺点是无法自适应。
一种改进的方法是使用CSS函数calc计算偏移量来实现自适应:
这样即使父元素的宽高是动态变化的,子元素也能始终保持居中。
方法四:table-cell+margin
table-cell的设置使父元素变成一个单元格,vertical-align使子元素竖直方向上居中。子元素再使用margin: auto的方法使自己水平方向上居中,达到中心居中的效果。
这种方法不常用,限制也比较多。最大的缺陷是table-cell的设置使父元素的宽高不能以百分比形式来表示,导致无法自适应。
总结
方法一和二用了弹性盒子布局,实现简单,具备自适应能力。但如果父元素的display需要被设置为其他属性(如fixed),则无法使用这两个方法了。方法三的改进版也具备自适应能力,但如果子元素内因为一些原因无法让子元素的position被设置为relative,就无法使用了。方法四的限制较多,适用面较窄。
元素内子元素水平居中均匀分布(可换行)
效果图:
方法一:flex-wrap + justify-content
弹性布局,设置flex-wrap: wrap可换行,设置justify-content: center使行内元素水平居中。
方法二:text-align + inline-block
把子元素的display修改为inline-block,既支持共享同一行,又不影响宽高设定。父元素用text-align: center指定子元素居中排列。
把父元素分割为四(n)块等宽的区域(栅栏布局)
效果图:
方法一:flex+calc
弹性布局flex使子元素横向排列,calc计算每个子元素占有的宽度。由于每个子元素设置了margin: 10px,在左右方向上有20px的margin,因此每个子元素占有的宽度是width + 20px,因此在计算width时要先用父元素的宽度减去4 * 20px再除以4。也可以简单一点,写成calc(25% - 20px).
方法二:inline-block+calc
出乎意料的是,这种写法居然换行了,说明宽度算大了,最后一个放不下,放到第二行去了。
去掉子元素的margin后发现元素之间有缝隙,通过查资料发现inline-block元素之间存在4px的空隙,这种方法计算出来宽度略大,导致换行。
设置父元素的font-size: 0可以解决这个问题,但是子元素如果有文字展示的需要就得单独设置自己的font-size了。
方法三:float
效果有点差别,父元素背景色不见了。
因为所有子元素都float: left,导致父元素的高度没被子元素撑大,父元素高度为0,背景色自然展示不出来了。
因此这种方案不适合父元素高度需要由子元素确定的情况,如果父元素高度固定,可以使用这种方案。
总结
方法一限制最少,实现逻辑简单。方法二由于有inline-block的间隙问题,父元素需要设置font-size: 0,子元素需要设置自己的font-size,有点不方便。方法三在父元素高度未知的情况下不太好用。
表单标签右对齐、内容左对齐实现
效果图:
在表单设计中较为常见,当标签长短不一时,靠右对齐比靠左对齐视觉效果要好一些。
table+text-align
这种表单有个隐含的诉求,就是第一列的宽度由列中最宽的元素决定,否则会出现第二列内容侵入第一列的情况,因此用table实现最方便。同时给第一列的内容加上class,让它们靠右对齐。
左边导航栏+右边内容页实现
效果图:
方法一:float
如果只把内容部分float: right,因为导航部分独占一行,不能并列。如果把导航部分设置为display: inline-block再float: right,则会出现缝隙问题,一样不能并列。所以采用了两块内容都float: left的设置,既能处于同一行,又不会出现缝隙。
方法二:inline-block
由于inline-block的缝隙问题,要给它们的父元素设置font-size: 0,所以子元素的文字要正常显示就要设置自己的font-size属性了。同时内容div要设置vertical-align: top,和导航div顶部对齐。
方法三:flex
子元素的flex属性代表在这一行中站的比重,left占1份,right占4份,整体比例1:4.弹性布局还附带了一个效果,把左右两块的高度对齐了。如果不想要对齐,需要给子元素设置固定的高度。
总结
方法一和方法二差不多,方法一用float使div并列,方法二用inline-block使div并列。方法二比方法一稍微复杂一点,但是float在使用中总会遇到一些坑,所以两种方法各有利弊吧。方法三附带了高度对齐的效果,如果不需要这个效果则需要设置固定的高度。
左右固定宽度,中间撑满剩余空间实现
效果图:
方法一:inline-block
当子元素的高度不同时,要给每个子元素设置vertical-align: top,让所有的子元素顶部对齐。
方法二:float
方法三:flex
当只有一个子元素设置flex属性时,该子元素会占满该行横向所有剩余空间。
版权声明固定在浏览器底部实现
当内容不足以撑满整个浏览器窗口的高度时,版权声明在底部。当内容溢出浏览器窗口的高度时,版权声明在内容的下面。
效果图:
不能撑满时:
溢出高度时:
方法一:absolute+relative+min-height
因为声明固定在底部,考虑用absolute或者fixed,但是fixed是始终固定在浏览器的底部,页面内容滚动时不移动,不符合要求。absolute是固定在非static父元素的某个位置,可以用一个div作为内容+声明的父元素,声明固定在父元素的底部。当内容高度小时,父元素高度为浏览器高度,声明固定在父元素的底部,也就处在浏览器窗口的底部。当内容高度大时,把父元素高度撑大,声明也就跟着父元素高度的增加移动到内容的最后面。
思路上声明使用absolute,父元素要使用relative,否则无法作为声明的父元素。然后父元素的高度是浏览器窗口高度和内容高度的最大值,当内容高度小于窗口高度时,父元素高度=窗口高度;当内容高度大于窗口高度时,父元素高度=内容高度。因此设置父元素最小高度为100%,即浏览器窗口高度。
有个要注意的地方是bottom和content中间有一个32px的div,是留给声明占位用的。当content大于浏览器窗口高度时,声明在父元素的底部。但是因为声明是absolute定位,不占空间,所以会重叠到内容上方。因此需要一个和声明高度相同的div来占位,使声明不会和内容重叠。
方法二:flex+align-content+margin
flex的逻辑和实现都比较简单。父元素声明为弹性容器,允许换行,最小高度还是100%,原理同方法一。子元素就是内容和底部声明,宽度分别设置为100%,这样两个子元素呈上下排列。父元素剩余高度被两行平分,平分后的高度被放在两行内容的下方。声明需要把这部分空白放在上方,使用子元素属性maring-top: auto把空白部分移至内容上方即可。
总结
方法一比较绕,要求比较多,而且用了占位div。方法二比较贴近原生CSS,逻辑简单,实现简洁。
导航栏固定在浏览器顶部实现
效果图:
在浏览器顶部时(注意滚动条的位置):
在浏览器底部时(注意滚动条的位置):
fixed+占位div
顶部导航栏相对浏览器窗口的位置是不动的,因此考虑用fixed。但是fixed是不占空间的,因此需要一个和导航栏一样大的空白div帮导航栏占住顶部的位置,不会盖住下面content的内容。