HTML布局的一点点套路

1,275 阅读8分钟

前言

首先明确是否需要兼容IE8,如果需要就用Float布局定宽,如果不需要兼容IE8,就用Flex布局弹性定宽

  • 不到万不得已,一般不写死widthheight
  • 如果是IE,就全部写死
  • 尽量用高级语法,比如calcflex等 以下面的一个布局来说说一些布局的套路

左边是PC布局,右边是手机布局

Float布局

Float布局是最古老的,也是兼容性最好的,可以兼容IE5

Float布局主要有两点:

  • 给父元素的class加上clearfix
  • 给子元素的CSS加上float: left/right
  • 在CSS中写一个.clearfix::after的类

以上述图片的top栏为例

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>布局套路</title>
</head>

<body>
  <div class="top clearfix">
    <div class="logo">logo</div>
    <div class="navBar">
      <div class="nav clearfix">
        <div class="navItem">导航1</div>
        <div class="navItem">导航2</div>
        <div class="navItem">导航3</div>
        <div class="navItem">导航4</div>
        <div class="navItem">导航5</div>
      </div>
    </div>
  </div>
  <style>
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    .clearfix::after {
      content: '';
      display: block;
      clear: both;
    }/*IE8支持*/

    .clearfix {
      zoom: 1
    }/*当clearfix::after出现IE兼容性问题时,加上这一段。支持到IE6*/

    .top {
      background-color: #ddd;
    }

    .logo {
      float: left;
      height: 36px;
      background-color: pink;
      width: 100px;
      text-align: center;
      line-height: 36px;
    }

    .navBar {
      float: right;
    }

    .nav {
      line-height: 24px;
      padding: 6px 0;
    }

    .navItem {
      float: left;
      margin-left: 20px;
    }
  </style>
</body>

</html>

效果如下:

Flex布局

Flex布局套路要点:

<body>
  <div class="pictures">
    <div class="picture"></div>
    <div class="picture"></div>
    <div class="picture"></div>
    <div class="picture"></div>
    <div class="picture"></div>
    <div class="picture"></div>
    <div class="picture"></div>
    <div class="picture"></div>
  </div>
  <style>
    .pictures {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
      background-color: orange;
      width: 800px;
      margin: 0 auto;
    }

    .picture {
      width: 194px;
      height: 194px;
      background-color: grey;
      margin-top: 4px;
      margin-bottom: 4px;
    }
  </style>
</body>

效果如下:

如果是采用Float布局,由于没有justify-content属性,那么想要得到间距效果,就必须加上margin

<body>
  <div class="pictures clearfix">
    <div class="picture"></div>
    <div class="picture"></div>
    <div class="picture"></div>
    <div class="picture"></div>
    <div class="picture"></div>
    <div class="picture"></div>
    <div class="picture"></div>
    <div class="picture"></div>
  </div>
  <style>
    .pictures {
      background-color: orange;
      width: 800px;
      margin: 0 auto;
    }

    .picture {
      width: 194px;
      height: 194px;
      float: left;
      background-color: grey;
      margin: 4px;
    }
  </style>
</body>

效果如下:

这里出现了一个问题,由于最左边的div的margin-left和最右边的div的margin-right的存在,导致4个div加上它们的margin的总宽度超过了800px,导致换行了,怎么解决呢?

  • 第一种方法 既然它们有多余的margin,消除多余的margin不就是了
.picture:nth-child(4n+1) {
  margin-left: 0
}

.picture:nth-child(4n) {
  margin-right: 0
}

效果如下:

但这种语法不是每个浏览器都支持的,特别时IE浏览器,那么还有什么办法呢?

  • 第二种方法 在外面加一层wrapper的div,在这个div上加负margin
<body>
  <div class="pictures">
    <div class="pictureWrapper clearfix">
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
    </div>
  </div>
  <style>
    .pictures {
      background-color: orange;
      width: 800px;
      margin: 0 auto;
    }

    .pictureWrapper {
      margin-left: -4px;
      margin-right: -4px;
    }

    .picture {
      width: 194px;
      height: 194px;
      float: left;
      background-color: grey;
      margin: 4px;
    }
  </style>
</body>

效果如下:

用Flex布局有个bug,如果div的个数不满足4的倍数,比如只有7个时,问题就来了

怎么解决呢?

那就是不用justify-content属性,用margin加上wrapper负margin来实现

<body>
  <div class="pictures">
    <div class="pictureWrapper">
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
    </div>
  </div>
  <style>
    .pictures {
      background-color: orange;
      width: 800px;
      margin: 0 auto;
    }

    .pictureWrapper {
      display: flex;
      flex-wrap: wrap;
      margin-left: -4px;
      margin-right: -4px;
    }

    .picture {
      width: 194px;
      height: 194px;
      background-color: grey;
      margin: 4px;
    }
  </style>
</body>

效果如下:

clac

在写宽度高度时,尽量使用高级语法clac,这样当父级元素宽高没有固定时,子元素就可以随页面变化而变化

比如:

.picture {
  width: clac(25% - 8px);
  height: 194px;
  background-color: grey;
  margin: 4px;
}

两个广告栏

广告栏的class不要取名为ad,会被广告屏蔽软件屏蔽

<body>
  <div class="art clearfix">
    <div class="sider"></div>
    <div class="main"></div>
  </div>

  <style>
    .art {
      width: 800px;
      margin: 0 auto;
    }

    .sider {
      float: left;
      height: 300px;
      width: 33.333333%;
      background-color: #666;
    }

    .main {
      float: left;
      height: 300px;
      width: 66.666666%;
      background-color: #999;
    }
  </style>
</body>

效果如下:

广告内容另外写div放进去

两个div中间加道间隙

  • 减少div宽度,并加margin
.sider{
  height: 300px;
  width:calc(33.333333% - 20px);
  margin-right:20px;
  background-color: #666;
}

效果如下:

如果不支持calc语法,那就在外面加个div来实现

  • Flex布局实现 在Flex布局中,可使用justify-content属性
<body>
  <div class="art">
    <div class="sider"></div>
    <div class="main"></div>
  </div>

  <style>
    .art {
      width: 800px;
      margin: 0 auto;
      display: flex;
      justify-content: space-between;
    }

    .sider {
      height: 300px;
      width: calc(33.333333% - 20px);
      background-color: #666;
    }

    .main {
      height: 300px;
      width: 66.666666%;
      background-color: #999;
    }
  </style>
</body>

手机端

首先加上viewport标签,然后用@media,在里面写上手机端的属性来实现

比如导航栏,写两个导航栏,手机端的导航栏默认不显示,用@media来控制其条件显示

  .nav {
    line-height: 24px;
    padding: 6px 0;
  }

  .nav2 {
    display: none;
  }

  @media (max-width:420px) {
    .nav2 {
      display: block;
    }
    .nav {
      display: none;
    }
  }

手机端效果图:

其他效果也是类似的写法

图片不变形

当想让插入的图片不产生变形时,最好不要用img标签

用div通过CSS来插入

.div{
  background: transparent url(图片的链接) no-repeat center;
}

有时候图片会显示不完全,加上

.div{
  background-size: cover;
}

最后,文章一开始图片所展示的页面代码如下:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>布局套路</title>
  <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
</head>

<body>
  <div class="top clearfix">
    <div class="logo">logo</div>
    <div class="navBar">
      <div class="nav clearfix">
        <div class="navItem">导航1</div>
        <div class="navItem">导航2</div>
        <div class="navItem">导航3</div>
        <div class="navItem">导航4</div>
        <div class="navItem">导航5</div>
      </div>
      <div class="nav2">手机端</div>
    </div>
  </div>

  <div class="banner"></div>

  <div class="pictures">
    <div class="pictureWrapper">
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>
      <div class="picture"></div>

    </div>
  </div>

  <div class="art">
    <div class="sider">广告1</div>
    <div class="main">广告2</div>
  </div>
  <style>
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    .clearfix::after {
      content: '';
      display: block;
      clear: both;
    }

    .clearfix {
      zoom: 1
    }

    .top {
      background-color: #ddd;

    }

    .logo {
      float: left;
      height: 36px;
      background-color: pink;
      width: 100px;
      text-align: center;
      line-height: 36px;
    }

    .navBar {
      float: right;
    }

    .nav {
      line-height: 24px;
      padding: 6px 0;
    }

    .nav2 {
      display: none;
    }

    @media (max-width:420px) {
      .nav2 {
        display: block;
      }
      .nav {
        display: none;
      }
    }

    .navItem {
      float: left;
      margin-left: 20px;
    }

    .banner {
      width: 800px;
      height: 300px;
      background-color: #777;
      margin: 10px auto 10px auto;
    }

    @media (max-width:420px) {
      .banner {
        width: auto;
      }
    }

    .pictures {
      background-color: orange;
      width: 800px;
      margin: 10px auto;
      overflow: hidden;
    }

    .pictureWrapper {
      display: flex;
      flex-wrap: wrap;
      margin-left: -4px;
      margin-right: -4px;
    }

    .picture {
      width: 194px;
      height: 194px;
      background-color: grey;
      margin: 4px;
    }

    @media (max-width:420px) {
      .pictures {
        width: auto;
      }
      .picture {
        width: calc(50% - 8px);
      }
    }

    .art {
      width: 800px;
      margin: 0 auto;
      display: flex;
      justify-content: space-between;
    }

    .sider {
      height: 300px;
      width: calc(33.333333% - 20px);
      background-color: #666;
    }

    .main {
      height: 300px;
      width: 66.666666%;
      background-color: #999;
    }

    @media (max-width:420px) {
      .art {
        width: auto;
        flex-direction: column;
      }
      .sider {
        width: auto;
        height: auto;
      }
      .main {
        width: auto;
        height: auto;
      }
    }
  </style>
</body>

</html>

一些值得注意的地方

在进行HTML的布局时,布局和内容应该利用嵌套多层div来实现,一个div尽量只完成一件事情,使页面结构清晰化