CSS布局实战 | 青训营

137 阅读9分钟

知识点可以参考我的其他文章

CSS布局之Flex | 青训营 - 掘金 (juejin.cn)

CSS布局基础 | 青训营 - 掘金 (juejin.cn)

主要是这两篇

居中方式

  1. 利用margin:0 autotext-align:center样式实现水平居中;
  2. 利用”高==行高“实现垂直居中;
  3. 利用绝对定位实现垂直居中。
  4. 利用table实现垂直居中;
div.table{
  display: table;
}
div.td{
  display: table-cell;
  vertical-align: middle;
}

放这怕我就自己忘


本次实战以小米商城为例,中间重复出现的商品栏不会重复编写,所以分为以下这几部分,同时因为主要练习布局技巧,所以不就添加伪类了。

首页

www.mi.com_shop.png

商品栏

Snipaste_2023-08-28_11-40-28.JPG

尾页

image.png

注意侧边栏是个绝对定位

目路结构

image.png

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- <link rel="stylesheet" href="./css/normalize.css"> -->
    <link rel="stylesheet" href="index.css">
    <link rel="stylesheet" href="head.css">
    <link rel="stylesheet" href="banner.css">
    <link rel="stylesheet" href="add.css">
    <link rel="stylesheet" href="footer.css">
    <title>m</title>
</head>
<body>
    <!-- 黑色顶栏 -->
    <div class="head">
    </div>   
    <!-- 中心部分 -->
    <div class="banner w">
    </div>
    <!-- 商品部分 -->
    <div class="add ">
    </div>
    <!-- 结尾 -->
    <div class="footer"></div>
</body>
</html>

index.css

*{
    margin: 0;
    padding: 0;
}
li {
    list-style: none;
}
a {
    text-decoration: none;
}

最后页面上的图右键可以保存(应该都知道吧)

image.png

1、首页

我们可以看到首页与下方的商品栏背景颜色是不同的,取色后发现是默认的白色,页面整体通览下来后可以发现页面两边留白,即存在版心。

因此我们在index.css中加入

/* 版心 */
.w{
    width: 1240px;
    margin: auto;
}

需要将主体装在一定高度的盒子里

所以在banner.css里写

.banner {
    height: 770px;
}

1.1 head——黑色顶栏

image.png

图片可知,先有一个大盒子宽度占满,高度、颜色需测量;

其次可以分为左右两个小盒子(使用浮动);

最后,文字不顶格,从版心处开始按文字长短占位,,使用行级元素不方便(需要设定宽高),最好直接是文字的宽度,因为本身带有链接,所以用a标签装文字和span盒子(装小竖线)。

居中方式:利用”高==行高“实现垂直居中

    <!-- 黑色顶栏 -->
    <div class="head">
        <div class="w">
                <div class="left">
                    <a href="">小米官网</a>
                    <span>|</span>
                    <a href="">小米商城</a>
                    <span>|</span>
                    <a href="">MIUI</a>
                    <span>|</span>
                    <a href="">IoT</a>
                    <span>|</span>
                    <a href="">云服务</a>
                    <span>|</span>
                    <a href="">天星数科</a>
                    <span>|</span>
                    <a href="">有品</a>
                    <span>|</span>
                    <a href="">小爱开放平台</a>
                </div>
            <div class="right">
                    <a href="">登录</a>
                    <span>|</span>
                    <a href="">注册</a>
                    <span>|</span>
                    <a href="">消息通知</a>
                    <span>|</span>
                    <div class="buy"><a href="">购物车(0)</a></div>
            </div>
        </div>
    </div> 
.head {
    background-color: #333333;
    width: 100%;
    height: 40px;
}
.left,.right {
    display: flex;
}
/*浮动分开盒子*/
.left {
    float: left;
}
.right {
    float: right;
}
.head  a {
    font-size: 12px;
    color: #b0b0b0;
}
.head a,span {
    height: 40px;
    line-height: 40px;/*文字垂直居中*/
}
.head span {
    color:#3f423d;
    margin-right: 5px;
    margin-left: 5px; /*文字之间的间隔*/
}
.buy {/*最后的购物车与其他的间隔不一样,单独设置一下*/
    width: 80px;
    padding-left: 30px;
    background: #424242;
}

1.2 banner——白色导航栏

image.png

对比后可发现logo的位置从版心处开始,导航栏的起始位置与下方侧边栏对齐,由此我们依然可以将这一栏拆成两个盒子。

而右边的盒子还有搜索框,因此又可以拆成左右两个盒子。 这里我们采用定位来对logo进行居中

口诀:子绝父相

因此将logo图片套上一个盒子以后,将盒子设置为相对定位,将图片设置为绝对定位,下移一半再往回移动图像的一般即可居中,代码如下

.logo { 
    position: relative;
}
.logo img {
    position: absolute;
    top: 50%;
    margin-top: -29px;
    /* 都是为了居中 */
}
   <div class="box-nav">
            <div class="nav-index w">
                <div class="sub logo">
                    <img src="im\logo.png" alt="no" width="57px">
                </div>
                <ul class="nav">
                    <li>Xiaomi手机</li>
                    <li>Redmi手机</li>
                    <li>电视</li>
                    <li>笔记本</li>
                    <li>平板</li>
                    <li>家电</li>
                    <li>路由器</li>
                    <li>服务中心</li>
                    <li>社区 </li>         
                </ul>
                <div class="search">
                    <div class="content"> 电视</div>
                    <div class="button">搜索</div>
                </div>
            </div>
        </div>

.logo img {
    position: absolute;
    top: 50%;
    margin-top: -29px;
    /* 都是为了居中 */
}
.box-nav {
    height: 100px;
    /* border-bottom: solid 1px #e0e0e0; */
}
.nav-index {
    height: 100px;
}
.logo {
    float: left;
    height: 100px;   
    position: relative;
}
.nav {
    float: left;
    width: 630px;
    height: 100px;
    display: flex;
    flex-direction: row;
    justify-content: space-around;
    align-items: center;
    font-size: 16px;
}
.search {
    float: right;
    position: relative;
    width: 300px;
    height: 50px;
    border: solid 1px #e0e0e0;
    top: 50%;
    margin-top: -25px;
}
.button,.content {
    height: 50px;
    line-height: 50px;
}
.content {
    float: left;
    color: #757575;
    width: 239px;
    padding-left: 10px;
}
.button {
    float: right;
    width: 50px;
    border-left:solid 1px #e0e0e0;
    color: #616161;
    text-align: center;
}

1.3 banner——封面主体

image.png

这里侧边栏使用列表+弹性盒布局,li内还有一个右浮动的小盒子存放箭头。居中方式如下

    display: flex;
    flex-direction: column;
    /* 垂直加水平居中 */
    justify-content: center;
    align-items: center;

图片通过背景的方式导入。

左右两个小箭头以及右下角的原点,通过绝对定位来完成

其中小圆点使用弹性盒完成的,以下代码可实现匀称的分布

weight=height=border-radius可将盒子变成圆形

    justify-content: space-around;
    align-items: center;
 <div class="w main">
            <ul class="sub sub-nav">
                <li>手机<span>></span></li>
                <li>手机<span>></span></li>
                <li>手机<span>></span></li>
                <li>手机<span>></span></li>
                <li>路由器<span>></span></li>
                <li>路由器<span>></span></li>
                <li>路由器<span>></span></li>
                <li>路由器<span>></span></li>
                <li>路由器<span>></span></li>
                <li>路由器<span>></span></li>
            </ul>
            <div class="main-right">
                <span class="left"> < </span>
                <span class="right"> > </span>
                <ul class="right-bottom">
                    <li></li>
                    <li></li>
                    <li></li>
                    <li style="background-color: #ffffff;"></li>
                    <li></li>
                </ul>
            </div>
        </div>
       
.main {
    height: 460px;
    background: url(im/main.png) no-repeat top center;
    background-size: 1226px auto;
}
.sub-nav {
    height: 460px;
    background-color: rgba(105, 101, 101, 0.6);
    float: left;
    display: flex;
    flex-direction: column;
    /* 垂直加水平居中 */
    justify-content: center;
    align-items: center;
    font-size: 14px;
    color: #ffffff;

}
.sub-nav li{
    line-height: 42px;
    width: 170px;
    height: 42px;
}
.sub-nav li span {
    float: right;
    font-weight: bold;
}
.main-right {
    float: right;
    position: relative;
    width: 992px;
    height: 460px;
}
.main-right span {
    position: absolute;
    top: 50%;
    margin-top: -35px;
    width: 41px;
    height: 69px;
    color: #d8d8d8;
    font-size: 50px;
    line-height: 69px;

}
.main-right .right {
    left: 955px;
}
.right-bottom {
    position: absolute;
    right: 30px;
    bottom: 20px;
    height: 21px;
    width: 90px;
    display: flex;
    justify-content: space-around;
    align-items: center;
}
.right-bottom li {
    height: 7px;
    width: 7px;
    border-radius: 7px;
    background-color: #8f8f8f;
    border: solid 2px #b1b1b1;

}

1.4 baneer——封面下部

image.png

分为左右两部分,都用了弹性盒布局

右边的内部设定换行,控制好li的长和宽即可。

左边同理,注意其内部元素的居中不能使用line-height

.box1 ul li { 
    /* 注意居中不能用line-height */
    height: 82px;
    width: 76px;
    color: #ffffff;
}

居中使用的代码

    .box1 ul li a{
    display: block;
    height: 60px;
    font-size: 12px;
    text-align: center;
    margin-top: 18px;
}

整体代码

 <div class="box">
            <div class="box1 w">
                <ul class="sub">
                    <li><a><img src="im\mini1.png" alt="no">企业团购</a></li> 
                    <li><a><img src="im\mini1.png" alt="no">企业团购</a></li> 
                    <li><a><img src="im\mini1.png" alt="no">企业团购</a></li> 
                    <li><a><img src="im\mini1.png" alt="no">企业团购</a></li> 
                    <li><a><img src="im\mini1.png" alt="no">企业团购</a></li> 
                    <li><a><img src="im\mini1.png" alt="no">企业团购</a></li>   
                </ul>
            </div>
            <div class="box2 w">
                <ul>
                    <li><img src="im\goods.png" alt=""></li>
                    <li><img src="im\goods.png" alt=""></li>
                    <li><img src="im\goods.png" alt=""></li>
                </ul>
            </div>
        </div>
    </div>
.box {
    margin-top: 15px;
}
.box1 ul {
    display: flex;
    float: left;
    /* align-items: center; */
    justify-content: center;
    background-color: #5f5750;
    flex-wrap: wrap;
    height: 170px;
}
.box1 ul li { 
    /* 注意不能用line-height */
    height: 82px;
    width: 76px;
    color: #ffffff;
}
.box1 ul li a{
    display: block;
    height: 60px;
    font-size: 12px;
    text-align: center;
    margin-top: 18px;
}
.box1 ul li a img {
    margin: 0 23px;
    width: 24px;
}
/* .box2 ul li {
    width: 316px;
} */
.box2 ul {
    float: right;
    display: flex;
    justify-content: space-between;
    width: 978px;
}
.box2 ul img {
    width: 316px;
}

1.5 banner——右侧固定栏

固定定位+弹性盒

image.png

 <ul class="fix">
        <li><img src="im\my.png" alt="no">个人中心</li>
        <li><img src="im\my.png" alt="no">个人中心</li>
        <li><img src="im\my.png" alt="no">个人中心</li>
        <li><img src="im\my.png" alt="no">个人中心</li>
        <li class="last"><img src="im\my.png" alt="no">个人中心</li>
    </ul>

.fix {
    position: fixed;
    right: 0px;
    bottom: 70px;
    height: 450px;
    display: flex;
    flex-direction: column;
    width: 83.6px;
    background-color: #ffffff;

}
.fix li {
    height: 90px;
    text-align: center;
    font-size: 14px;
    border: solid 1px #f5f5f5;
    border-bottom: 0px;
    color: #757575;
} 
.fix .last {
    border-bottom: solid 1px #f5f5f5;
}
.fix img {
    width: 30px;
    margin: 20px 20px 5px 20px;   
}

2、商品栏——add

文件起始内容

.add {
    height: 1000px;
    background-color: #f5f5f5;
}

2.1 横栏广告

这个设定长、宽就行了

image.png

    <div class="add ">
        <!-- 顶部广告 -->
        <div class="top w">
            <img src="im\long.png" alt="">
        </div>
    </div>
.top img{
    margin-top: 25px;
    width: 1226px;
}

2.2 指示栏

注意标签语义化

使用定位进行右侧的制作

圆形盒子制作方法同上

image.png

     <div class="add ">
        <div class="w box_1">
            <h2 class="l">手机</h2>
            <div class="r">
                <span class="">查看更多</span><span class="round">></span>
            </div>
        </div>
      </div>
.box_1 {
    position: relative;
    margin-top: 20px;
    height: 58px;
    width: 1226px;
    line-height: 58px;
    /* background-color: #ffffff; */
}
.box_1 .l {
    font-size: 22px;
    font-weight: 200;
    line-height: 58px;
    color: #333;

}
.box_1 .r {
    position: absolute;
    top: 0;
    right: 0;
}
.round {
    display: inline-block;
    border-radius: 20px;
    height: 20px;
    text-align: center;
    line-height: 20px;
    color: #ffffff;
    width: 20px;
    background-color: #b0b0b0;
    margin: 10px;
}

2.3商品

左侧一张竖图,右侧使用弹性布局

image.png

    <div class="add ">
        <!-- 一个商品栏 -->
        <div class="goods w">
            <img src="im\long2.png" alt="no" class="sub">
            <div class="rgs">
                <div class="rg">
                    <img src="im\good.png" alt="no">
                    <h3>Xiaomi MIX Fold 3</h3>
                    <p>轻薄折叠屏丨徕卡光学丨全焦段四摄</p>
                    <div>8999元起</div>
                </div>
                <div class="rg">
                    <img src="im\good.png" alt="no">
                    <h3>Xiaomi MIX Fold 3</h3>
                    <p>轻薄折叠屏丨徕卡光学丨全焦段四摄</p>
                    <div>8999元起</div>
                </div>
                <div class="rg">
                    <img src="im\good.png" alt="no">
                    <h3>Xiaomi MIX Fold 3</h3>
                    <p>轻薄折叠屏丨徕卡光学丨全焦段四摄</p>
                    <div>8999元起</div>
                </div>
                <div class="rg">
                    <img src="im\good.png" alt="no">
                    <h3>Xiaomi MIX Fold 3</h3>
                    <p>轻薄折叠屏丨徕卡光学丨全焦段四摄</p>
                    <div>8999元起</div>
                </div>
                <div class="rg">
                    <img src="im\good.png" alt="no">
                    <h3>Xiaomi MIX Fold 3</h3>
                    <p>轻薄折叠屏丨徕卡光学丨全焦段四摄</p>
                    <div>8999元起</div>
                </div>
                <div class="rg">
                    <img src="im\good.png" alt="no">
                    <h3>Xiaomi MIX Fold 3</h3>
                    <p>轻薄折叠屏丨徕卡光学丨全焦段四摄</p>
                    <div>8999元起</div>
                </div>
                <div class="rg">
                    <img src="im\good.png" alt="no">
                    <h3>Xiaomi MIX Fold 3</h3>
                    <p>轻薄折叠屏丨徕卡光学丨全焦段四摄</p>
                    <div>8999元起</div>
                </div>
                <div class="rg">
                    <img src="im\good.png" alt="no">
                    <h3>Xiaomi MIX Fold 3</h3>
                    <p>轻薄折叠屏丨徕卡光学丨全焦段四摄</p>
                    <div>8999元起</div>
                </div>
            </div>
        </div>
    </div>
.goods {
    height: 614px;
}
.goods img {
    height: 614;
}
.rgs {
    float: right;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-content: space-between;
    width: 978px;
    height: 614px;
}
.rg{
    background-color: #fff;
    height: 300px;
    width: 234px;
    font-size: 14px;
    text-align: center;
}
.rg img {
    margin-top: 30px;
    height: 160px;
}
.rg h3 {
    font-weight: 400;
    font-size: 14px;
}
.rg p {
    font-size: 12px;
    color: #b0b0b0;
    margin: 5px 0 10px;
}
.rg div{
   color: #ff8410;
}

3、结尾——footer

起始

.footer {
    height: 472px;
    background-color: #fff;
}

3.1 顶栏

列表+弹性盒

image.png

<div class="footer w">
        <ul class="header">
            <li class="first">预约维修服务</li>
            <li>预约维修服务</li>
            <li>预约维修服务</li>
            <li>预约维修服务</li>
            <li>预约维修服务</li>
        </ul>
</div>      
.footer .header {
    display: flex;
    justify-content: space-between;
    height: 80px;
    align-items: center;
    border-bottom: solid 1px #e0e0e0;
}
.header li {
    text-align: center;
    /* line-height: 80px; */
    height: 25px;
    border-left: solid 1px #e0e0e0;
    color: #616161;
    font-size: 16px;
    width: 243px;
}
.footer .first {
    border-left: 0;
}

3.2 大量指南

dl列表+浮动

注意:这里用检查看过代码后,发现有一个空的列表放在前面使其布局更好看,思考后发现这样也更方便以后对其添加部件,也是个值得学习的布局方法。

image.png

<div class="footer w">
     <div class="list">
            <dl>
                <dt></dt>
            </dl>
            <dl>
                <dt>线下门店</dt>
                <dd>授权体验店</dd>
                <dd>专区</dd>
                <dd>服务网点</dd>    
                <dd>授权体验店</dd>
                <dd>专区</dd>
                <dd>服务网点</dd>
                <dd>授权体验店</dd>
                <dd>专区</dd>
                <dd>服务网点</dd>
            </dl>   
            <dl>
                <dt>线下门店</dt>
                <dd>授权体验店</dd>
                <dd>专区</dd>
                <dd>服务网点</dd>    
            </dl>  
            <dl>
                <dt>线下门店</dt>
                <dd>授权体验店</dd>
                <dd>专区</dd>
                <dd>服务网点</dd>  
                <dd>授权体验店</dd>
                <dd>专区</dd>
                <dd>服务网点</dd> 
            </dl>  
            <dl>
                <dt>线下门店</dt>
                <dd>授权体验店</dd>
                <dd>专区</dd>
                <dd>服务网点</dd>    
            </dl>  
            <dl>
                <dt>线下门店</dt>
                <dd>授权体验店</dd>
                <dd>专区</dd>
                <dd>服务网点</dd>  
                <dd>授权体验店</dd>
                <dd>专区</dd>
                <dd>服务网点</dd>
                <dd>授权体验店</dd>
            </dl> 
        </div> 
</div>  
    padding: 40px 0;
    height: 312px;
}
.footer dl{
    float: left;
    width: 160px;
}
.footer dt {
    margin-bottom: 20px;
    font-size: 14px;
}
.footer dd {
    margin-top: 10px;
    height: 18px;
    color: #757575;
    font-size: 12px;
}

3.3 电话

image.png

内部三个盒子,使用弹性盒布局控制好其间距。

<div class="list">
    <div class="tele">
                <p class="b">400-100-5678</p>
                <p class="l">8:00-18:00(仅收市话费)</p>
                <a>人工客服</a>
            </div> 
</div> 
.tele .b {
    font-size: 22px;
    color: #ff6700;
    /* margin-bottom: 2px; */
}
.tele .l {
    font-size: 12px;
    color: #616161;
}
.tele a {
    text-align: center;
    display: block;
    color: #ff6700;
    height: 28px;
    line-height: 30px;
    width: 119px;
    border: solid 1px #ff6700;
    font-size: 12px;
}

最终成果

C__Users_h_Desktop%E5%AE%9E%E6%88%98_%E6%96%B0%E5%BB%BA%E6%96%87%E4%BB%B6%E5%A4%B9_index.html.png

总结:

  1. 本次实践大量运用了弹性盒布局,可以看到其布局的便利性。
  2. 本次实战的难点感觉在于居中方式
  3. line-height=height实现的是文字对于盛装它的容器的水平居中。对盒子的居中不起作用。
  4. 当多个盒子大小一致时用弹性盒布局会很方便。
  5. justify-content: center align-items:center 是对子元素的居中,而不是子元素内容物的居中。
  6. 利用margin:0 auto是盒子的水平局中,text-align:center是文字的水平居中。
  7. 用绝对定位居中盒子不会错,但盒子数值但需要知道,比较不方便。