所谓“设计一根线,重构一身汗”,掌握好css基础对于提高UI开发效率,提升代码质量有很大的作用。本文给大家整理一下css中布局方面的基础。不需要游艇火箭,如果看完后有收获的话,就分享一下给身边的小伙伴来一起温故而知新便是极好的。
本文的目录如下,采取的是由大到小的层面去分享:
1.css定位布局
2.css弹性布局
3.css盒子模型
4.css BFC
css定位布局
定位布局一般分为下面四类,我们常用的是相对定位,绝对定位和固定定位,而sticky定位是一个比较有趣的定位。
相对定位
相对定位是我们最常见最普通的定位了,他有这2方面的特点:
- 元素不脱离文档流
- 相对于自身元素定位。
所谓不脱离文档流,就是设置相对定位后,他还是处于原本的文档流中,保留原本占据的空间。可以看看这个示例,当我设置了和平精英这个元素为相对定位后,他还是像之前一样占据着文档流的空间。
第二个特点是相对于自身元素定位,意思是当我们设置top,left那些值时,他是相对自身原本的位置离顶部,离左边相应的距离。可以看看这个示例,我给和平精英这个容器设置属性后,他是相对原本的位置进行位移的。
绝对定位
接下来说一下绝对定位,他一般用于依赖父元素,位置随意的元素上,例如红点呀,角标啊那些。
他有以下这三点特点:
- 元素脱离文档流
- 宽高由容器里面的内容决定
- 相对于设置了定位的父级元素来定位。
设置了绝对定位后,元素会脱离文档流,不占据文档流的位置,看起来像漂浮在文档流的上方一样。
元素的宽高也会发生变化,他不再占满整行,而是里面的内容能撑起多大的面积就占多大的面积。
可以看看这个示例,当我们给和平精英的元素设置绝对定位后,他就像不占空间一样浮了起来,下面的元素就往上占据了他的位置了,而且这个元素的面积只能刚好包住里面的字吧,这就是宽高由里面的内容决定。当然你可以给他设置宽高的样式,让他变成你想要的宽高。
绝对定位还有一个特点,是它相对于上一个设置了定位的父级元素来进行定位,如果找不到,则相对于body元素进行定位。
看看这个示例,当我们给这个元素设置绝对定位和top属性后,它一下子就去到最顶部了,因为此时它的父级元素都没有设置定位,它相对于body来定位了。如果我们给最外层第二个元素设置定位,是不是就变成了相对于它来定位啦,而如果这时再给最外层第三个元素设置定位,由于它离绝对定位元素更近,所以绝对定位元素就相对于它来定位了。
固定定位
接着讲一下固定定位。它和绝对定位比较相似,设置后元素会脱离文档流,宽高由里面的内容决定。但是他不再相对于父级元素定位,而是根据浏览器窗口定位。可以看看这儿右下角的妲己图标,当页面滚动时它还停在原地不动,这就是相固定定位了。这个就不展开了。
sticky定位
最后我们说一下很有趣的sticky定位。我们看一下右边的导航栏,它一开始还是在文档流中的,向上滑动后后就黏在屏幕顶部,向下滑动后又回到文档流中。可以认为,当它在屏幕里时是相对定位,当它离开屏幕时是固定定位。设置也很简单,只需要对导航栏元素设置position:sticky和top属性就行了。当然如果你想它黏在屏幕底部,那就设置bottom属性。
用这个属性时要注意以下6点,但在我的使用经验来看,一般就是要特别注意第4第6第7点就行了。
1.sticky不会触发BFC。
2.z-index无效。
3.当父元素的height:100%时,页面滑动到一定高度之后sticky属性会失效。
4.父元素不能有overflow:hidden或者overflow:auto属性。
5.父元素高度不能低于sticky高度。
6.必须指定top、bottom、left、right4个值之一。
7.安卓4.4和ios7之前的低端手机不兼容,可用js使导航栏在固定定位与相对定位间切换。
定位属性
定位属性包含位置属性及层级属性。位置属性包括top、bottom、left、right,这些属性指的是目标元素相对于参照物的距离。
而层级属性,表示哪一个显示得更前面一点。我们可以看一下这个例子,当我给第3个盒子添加z-index后,他是不是盖在最上面了啦,而我再给第4个盒子添加更大的z-index后,它就盖在第3个盒子上面了。
css弹性布局
掌握好css弹性布局,做UI开发时会更得心应手、事半功倍。(重点,敲黑板!!!)
要实现弹性布局也很简单,只需要对容器添加display:flex;就可以了。
接下来看一下弹性布局包含的内容。下图是一个弹性布局的示意图,在一个大的container容器里,横放着三个item项目。main axis意思是主轴,就是item按哪条轴来排列的,cross axis是侧轴或者交叉轴,就是和主轴垂直的那条轴。start 和 end 分别表示轴的开头和结尾。接下来我一个一个属性介绍一下。
flex-direction
先说容器属性,flex-direction表示主轴的方向,即项目是要横着排还是竖着排。一般我们只用到row和column,分别是横着排和竖着排。加上了reverse表示反方向排列。接下来我们先假设项目都是默认的横着排的。
justify-content
justify-content定义项目在主轴上是怎么对齐的,分别有下图五点。要注意的是,如果使用了space-around的话,两侧项目到边缘的距离是项目与项目之间间距的一半。这个也比较好理解,每个项目都有间距,那两边的项目只有一个间距就到边缘,而中间那些项目有左一个间距和右一个间距,自然就是边缘的间距的两倍了。
align-items
既然有主轴的对齐就肯定有交叉轴的对齐了,属性值也和上一个有点相似。这儿就不多说了。用得最多的就是center属性,拿来做垂直居中对齐。一般弹性布局用得最多的容器属性就是这两个属性了。
flex-wrap
flex-wrap定义如果一行放不下,应该怎么办,默认是不换行,也有换行及反着换行的选择。使用换行的话,就可以实现出九宫格,瀑布流之类的效果了。
flex-grow
接下来要介绍的是项目的属性了,就是在一个个item里设置的属性。用得最多的是flex-grow,一般我们直接只写flex,表示item占据空间的比例,如果每个item都是1那就是平均分,如果其中一个item设为2,那么他占的空间是别的item的两倍。
很多时候我会用这个属性来做图文横排的样式,给文字设个flex=1,就可以把除了图片以外的空间都占满了。
align-self
align-self定义单个项目的交叉轴对齐方式,比如某个项目不想按正常套路排列,就可以用这个属性来设置了,可选值和前面说的align-item是一样的。
order
order定义项目的排列顺序,数值越小,排列越靠前,默认为0。有时候如果想做一个九宫格抽奖的效果,就可以做一个按钮再做八个奖品项,然后用order来调整他们的顺序了,而不用像以前那样,先做四个奖品项,再做一个按钮,再做四个奖品项了。
可视化工具
弹性布局的介绍到此就完了,这里再介绍一个直观的可视化工具flexbox playground,给容器和项目设置不同的值,看看他们的表现。
这是另一个可视化工具flexbox.help,和之前的相比,可以生成css代码,但不能给单个项目设置属性看效果。
css盒子模型
刚刚说完元素之间的布局后,接下来我要说的是更小层面的东西了,就是单个元素的组成结构,我们表示为盒子模型。
大家先看看下图这个画框,框的中间是一副画,在css里表示content,画与画框之间的间距,我们叫padding,画框相当于border,而画框外面的间距就是margin了。css的盒子模型就是长这样的了。
模型的宽与高,在默认标准模式下,就是指content的宽与高。
但当我们设置box-sizing: border-box时,模型的宽与高就是content+padding+border的宽高了。
说这个有什么用呢?用处可大了。以下面这个例子为例,假设容器宽高是固定的,这时我们需要调小padding间距,如果不用border-box,那模型的宽就是content的宽,我们调小多少padding,就要把content调大相应的尺寸,这样最终容器的宽高才能保持一致。
而如果用了border-box,此时模型的宽就是content+padding+border的宽,我们调小padding就行了,content会自动撑满整个容器,就是自动调大了尺寸了,一步到位了。所以很多时候我挺喜欢用这个属性的。
css BFC
说完border-box,我再说一个有趣的现象,叫外边距重叠现象。比如你写了两个列表项,分别设置了这样的间距,然后你用浏览器打开一看,发现他们的间距合并在一起了。这个现象是合理的,因为你本来按着设计稿量的尺寸设置了每个列表项的外边距,结果浏览器却显示了2倍的间距,这样就很奇怪了吧。不过为了减少这个现象的影响,我一般是只设置一边的间距,比如只设置列表项的下边距之类的。
有的时候可能你还是不想外边距重叠,那解决办法就是创建BFC。创建了BFC后,元素自成了一个环境,环境里面与外面的的样式和表现互相独立,互不影响。所以就两个外间距都出现了。
那怎么创建BFC呢?这里有4个办法。
- overflow不为visible;
- float的值不为none;
- position的值为absolute、fixed;
- display属性为inline-blocks,table, table-cell,table-caption,flex,inline-flex;
示例演示的是第一个办法,设置overflow属性。可以看到,一开始元素之间的外边距是重叠了的,这时候让我来创建一个bfc。前面说了要创建一个环境,让环境里面的与外面的互不影响,所以这时我要在p标签外面添加一个div,然后设置div的overflow属性,让div成为一个bfc,使得里面的p样式不受外面影响。设置完后,可以看到两者的外间距就分开了。
结语
关于布局、结构方面的知识点我就整理完了,不知本文能否帮得到大家呢?欢迎大家分享收藏,说不定哪个时候突然需要复习和参考一下呢。(。ӧ◡ӧ。)