css 布局技巧汇总--使用flex,grid响应式布局| 青训营

355 阅读4分钟

居中对齐

居中对齐是老生常谈的话题了,也是实战中最常用的布局方式,绝大多图标,按钮之类的都采用的居中对齐方式,毕竟有种美叫对称美.

文字居中(行盒)

<div style="background-color: rgb(29,125,250);width: 100px;height: 40px;line-height: 40px;text-align: center;color: white;">
        按钮
    </div>

仅需两行轻松实现

line-height: 40px; 设置行高等于容器高度实现垂直居中

text-align: center; 设置水平居中

  • 条件: 需要知道容器高度

image.png

块盒居中

常规流实现

定宽,设置左右margin为auto,基于其父盒子实现水平居中

.button{
    width: 100px;
    margin: 0 auto;
}

image.png

绝对定位实现

父元素设置position: relative;,子元素设置position: absolute,上下左右为0

 .background{
            position: relative;
        }
        .button{
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            margin: auto;
        }

image.png

其中top: 0;bottom: 0; 设置的是垂直居中

left: 0;right: 0; 设置的是水平居中

flex 布局实现

.background{
            /* position: relative; */
            display: flex;
            justify-content: center;
            align-items: center;
        }

其中justify-content: center 设置水平居中

align-items: center 设置垂直居中

使用flex 布局轻松完成各种场景

头部导航栏

image.png

/* 父元素 */
.learning_sections{
    display: flex;
    justify-content: center;
}
/* 子元素 */
.learning_section{
    padding:0px 9px;
}

image.png

justify-content为主轴元素居中紧密排列,再设置padding间隔开,仅需三行便完成了导航栏布局

三栏布局

即左右固定,中间自适应的布局

image.png

html

<div class="container">
        <aside class="left"></aside>
        <div class="main"></div>
        <aside class="right"></aside>
    </div>

css

.container{
            display: flex;
            height: 900px;
        }
        .left{
            width: 300px;
            
            background-color: rgb(135,192,202);
        }
        .right{
            width: 200px;
            background-color: rgb(240,207,227);
        }
        .main{
            flex:1;
            background-color:rgb(229,223,213) ;
        }

页面缩放之后左右也不会改变

image.png

  • flex:1flex-grow:1, flex-shrink:1flex-basis:1 的简写

  • flex-grow属性 定义了放大比例,默认值为0,如果值为0则即使父盒子有剩余空间也不放大。

如果所有元素的flex-grow属性都为1则元素平均分配。如果有一个元素为2其他为1,则为2的元素占据空间比其他为1的元素占据空间多一倍。

  • flex-shrink属性 定义了元素缩小比例,默认值为1,1代表着如果空间不足,会将该元素缩小。

如果说一个元素为0,其他都为1,则空间不足时,其他flex-shrink为1的元素会缩小,为0的元素则不缩小。

负数无效。

  • flex-basis属性 定义了在分配多余空间之前,元素占据的主轴空间。

默认值为auto,意思为元素本来的大小

他可以和宽高一样设置固定的。则元素会占据固定的空间。

两栏布局

同理只要将不改变的一边设置为定值,另一边设置flex:1即可

左右选项布局

image.png

这种左边筛选右边排序的布局非常常见

我们只需用一个父盒子包裹两个子元素,并设置父盒子的属性为justify-content: space-between即可

.father{
            display: flex;
            width: 90%;
            margin: auto;
            justify-content: space-between;
            align-items: center;
        }
  • justify-content: space-between属性的意思是两侧顶格其余空间平均分配

  • 因此设置父盒子为固定宽并居中便可轻松实现这种两侧选项式布局,align-items: center则是为了垂直方向居中对齐

表单对齐

image.png

<div class="main">
            <form class="form" action="">
                <input type="text">
                <input type="text">
                <input type="text">
                <input type="text">
                <input type="text">
            </form>
        </div>
.form{
            width: 80%;
            height: 40%;
            display: flex;
            flex-direction: column;
            justify-content: space-evenly;
        }
.main{
            flex:1;
            background-color:rgb(229,223,213) ;
            display: flex;
            justify-content: center;    
        }

其父盒子设置justify-content: center;使表单水平居中,表单本身设置flex-direction: column; 使主轴变为垂直,而justify-content: space-evenly;则使每个子元素之间的间隔都均等

更强大的布局 Grid

Grid 也是响应式布局,因此很多人都认为学了flex布局就不需要再学Grid布局了,从上面的演示来看,flex布局对于对称型的布局有很好的帮助,而对于非对称的布局就没有那么强的能力了,需要对其子元素的布局单独进行调整,而Grid布局可以很好的解决这个问题.

  • 使用Grid布局实现图片瀑布流

image.png

html结构

<div class="container">
        <img class="item" src="http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg" alt="">
        <img class="item" src="http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg" alt="">
        <img class="item" src="http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg" alt="">
        <img class="item" src="http://g.hiphotos.baidu.com/image/pic/item/55e736d12f2eb938d5277fd5d0628535e5dd6f4a.jpg" alt="">
        ...
    </div>

css

.container{
            width: 60%;
            margin: auto;
            display: grid;
            grid-template-columns: repeat(3,1fr);
            grid-auto-rows: 10px;
            grid-column-gap: 10px;
        }
        .container .item{
            width: 100%;
        }

js

(function () {
		var container = document.querySelector('.container');
        var items = container.querySelectorAll('.item');
        var rowHeight = parseInt(getComputedStyle(container).getPropertyValue('grid-auto-rows'));
        var rowGap = parseInt(getComputedStyle(container).getPropertyValue('grid-row-gap'));

        items.forEach(function(item) {
        // 根据图片高度动态计算每张图片所占的网格数
            var rowSpan = Math.ceil((item.offsetHeight + rowGap) / (rowHeight + rowGap));
            item.style.gridRow=`auto / span ${rowSpan}`
        });
	})()

代码分析

  1. grid-template-columns: repeat(3,1fr); 设置三列,每列均分三分之一的空间
  2. grid-auto-rows: 10px; 设置每行网格的高度为10px
  3. grid-column-gap: 10px; 设置列间距
  4. grid-row:auto / span ${rowSpan}: 设置子元素所占的网格线范围,"/"之前的auto为起始网格线, span x表示结束网格线距离起始网格行间隔x条网格线

网格线可视化

image.png