CSS系列篇:布局

前言

这是一篇对常见的CSS布局进行汇总整理。还有flex布局待我补充。

一、单列布局

Paste_Image.png
1、width和max-width的区别

注意点:设置width,当屏幕宽度缩放缩小到比设置值还小时,就会产生滚动条。而如果是设置max-width的话,当屏幕宽度缩放缩小到比设置值还小时,元素的大小就会缩小到当时实际的大小(100%),而不会产生滚动条。

没有设置最大宽度.png
设置最大宽度.png
2、单列布局实现:

思路:使用一个外部div包裹住头部、内容、尾部,然后头部、内容、尾部设置高度,对外部div设置宽度和margin为auto,实现单列布局的居中。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <div class="wrapper">
    <div class="header"></div>
    <div class="container"></div>
    <div class="footer"></div>
  </div>
</body>
</html>

/*样式设置*/
.wrapper{
  border:1px solid black;
  max-width:500px;
  /*或者设置为width:500px;*/
  margin:20px auto;
}
.header{
  height:100px;
  background-color:red;
}
.container{
  height:300px;
  background-color:yellow;
}
.footer{
  height:100px;
  background-color:blue;
}
3、改进

在此基础上,做改善,去除外部标签,将wrapper的样式设置,直接放到头部、内容和尾部的样式上即可。这样可以减少标签,也可以对每个局部做控制。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <div class="header mid"></div>
  <div class="container mid"></div>
  <div class="footer mid"></div>
</body>
</html>
/*样式设置*/
.mid{
  max-width:500px;
  margin:0px auto;
}
.header{
  height:100px;
  background-color:red;
}
.container{
  height:300px;
  background-color:yellow;
}
.footer{
  height:100px;
  background-color:blue;
}
4、单栏布局——通栏的实现

因为上下部分是实现通栏,背景色充满整个屏幕,而内容部分还要保证居中。所以将上下部分外面包裹一层,对外面一层只设置颜色,而对上下部分的div则实际设置宽度和居中的设置,来实现目的。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <div class="header">
    <div class="mid">haha头部</div>
  </div>
  <div class="container mid">内容</div>
  <div class="footer">
    <div class="mid">haha尾部</div>
  </div>
</body>
</html>
/*样式设置*/
.mid{
  max-width:500px;
  margin:0px auto;
}
.header{
  height:50px;
  background-color:red;
}
.container{
  height:300px;
  background-color:yellow;
}
.footer{
  height:50px;
  background-color:blue;
}

效果:

Paste_Image.png

注意:这里对居中的设置,.mid的宽度是设置了一个最大宽度的。
这样可以避免如下情况:当页面缩小到一定程度时,出现滚动条,上下部分出现白色空隙:

Paste_Image.png

如果不在例子中.mid中设置最大宽度,就需要分别在上下两部分设置最小宽度,这样页面宽度缩小到比最小宽度最小时,也还是最小宽度的大小,而不会产生空白缝隙,虽然此时就有滚动条了。.mid的宽度是设置了一个最大宽度的设置,就不会出现滚动条。

.mid{
  width:500px;
  margin:0px auto;
}
.header{
  height:50px;
  background-color:red;
  min-width:500px;
}
.container{
  height:300px;
  background-color:yellow;
}
.footer{
  height:50px;
  background-color:blue;
  min-width:500px;
}
上下两部分设置最小宽度.png
.mid中设置最大宽度-没有滚动条.png

二、内部元素水平居中

这个很明了了,不推荐使用浮动然后margin:auto的方式。直接使用行内元素居中的text-align:center设置。父元素设置文本居中,子元素设置为inline-block:

.parent{text-align:center;}
.child{display: inline-block;}

对于IE67,不支持inline-block,就使用hack的写法:

.child{*display:inline;*zoom:1}

*号是只有IE67才能识别,zoom:1让其产生BFC,触发了块级的特性。

实际例子:实现如下常见效果:

Paste_Image.png
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <div class="container">
    <a href="">HTML</a>
    <a href="">CSS</a>
    <a href="">JavaScript</a>
    <a href="">Output</a>
  </div>
</body>
</html>
/*css设置*/
.container{
  text-align:center;
  background-color:#ccc;
  font-size:0;
  padding:5px;
}
.container a{
  display:inline-block;
  text-decoration:none;
  border:1px solid #eee;
  border-right:0;
  font-size:14px;
  padding:5px 6px;
  color:#fff;
}
.container a:last-child{
  border-right:1px solid #eee;
  border-radius:0px 5px 5px 0px;
}
.container a:first-child{
  border-radius:5px 0px 0px 5px;
}

三、双列布局

Paste_Image.png

对这种一边固定宽度,另一边宽度最大化的布局的实现,就需要借助浮动和margin来设置。
固定宽度的那一列,设置为浮动,向左或向右浮动。然后父元素清除浮动,这样footer部分才能正常文档流位置。自适应宽度的那一列,则设置margin-left或margin-right,留出缝隙出来。

具体代码:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <div class="container">
    <div class="left"></div>
    <div class="right">随意扩展宽度</div>
  </div>
  <div class="footer">这是底部</div>
</body>
</html>
/*样式设置*/
.container:after{
  content:" ";
  display:block;
  clear:both;
}
.left{
  width:200px;
  height:400px;
  background-color:blue;
  float:left;
}
.right{
  height:400px;
  background-color:red;
  margin-left:210px;
}
.footer{
  height:50px;
  background-color:#ccc;
}
Paste_Image.png

如果要实现侧边栏在右,则只需要改下浮动的方向以及margin-right即可。
注意,这里浮动的设置需要关注浏览器的渲染顺序,所以div的顺序还是不变。

<div class="container">
    <div class="left"></div>
    <div class="right">随意扩展宽度</div>
 </div>

而非

<div class="container">
    <div class="right">随意扩展宽度</div>
    <div class="left"></div>
</div>

如果是这样,按照浏览器渲染顺序,则会变成:

Paste_Image.png

对于浏览器的渲染顺序,在三栏布局中就更为明显:

四、三栏布局

注意html的书写顺序:

<body>
  <div class="container">
    <div class="aside"></div>
    <div class="aside2"></div>
    <div class="content">随意扩展宽度</div>
  </div>
  <div class="footer">这是底部</div>
</body>

而不是

<body>
 <div class="container">
   <div class="aside"></div>
   <div class="content">随意扩展宽度</div>
   <div class="aside2"></div>
 </div>
 <div class="footer">这是底部</div>
</body>

因为对于第一种写法,左右两栏都是浮动,中间content部分会当它们不存在,直接同行,而设置左右margin之后,就能留出空隙

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <div class="container">
    <div class="aside"></div>
    <div class="aside2"></div>
    <div class="content">随意扩展宽度</div>
  </div>
  <div class="footer">这是底部</div>
</body>
</html>
/*样式设置*/
.container:after{
  content:" ";
  display:block;
  clear:both;
}
.aside{
  width:100px;
  height:300px;
  background-color:blue;
  float:left;
}
.aside2{
  width:100px;
  height:300px;
  background-color:blue;
  float:right;
}

.content{
  height:200px;
  background-color:red;
  margin-right:110px;
  margin-left:110px;
}
.footer{
  height:50px;
  background-color:#ccc;
}

效果:

Paste_Image.png

五、圣杯布局

圣杯布局其实也是三栏布局,但不同之处就在于,它是将主体dom部分写在前面,仍能实现三栏布局:

<body>
 <div class="container">
   <div class="aside"></div>
   <div class="content">随意扩展宽度</div>
   <div class="aside2"></div>
 </div>
 <div class="footer">这是底部</div>
</body>

具体实现:
将三个div都左浮动,然后将main这个div的宽度等同于100%,等于父元素宽度。然后对左右div设置margin-left的负值,让它们三个同处一行。

Paste_Image.png

然后就考虑怎么留左右缝隙的事了。因为main的宽度是父元素宽度的100%,所有如果还是使用margin-left和margin-right的方式来留左右空白是无效的,只会加长宽度。
所以设置三个div的父元素的左右padding,让整行留空白出来,然后对左右两个div设置相对定位,进行移动即可

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <div class="ct">
    <div class="main">haha</div>
    <div class="left"></div>
    <div class="right"></div>
  </div>
</body>
</html>

/*样式设置*/
.ct:after{
  content:"";
  display:block;
  clear:both;
  width:500px;
}
.ct{
  padding-left:100px;
  padding-right:100px;
}
.main{
  height:300px;
  background:blue;
  float:left;
  width:100%;
}
.left{
  width:100px;
  height:300px;
  background:yellow;
  float:left;
  margin-left:-100%;
  position:relative;
  left:-110px;
}
.right{
  width:100px;
  height:300px;
  background:red;
  float:left;
  margin-left:-100px;
  position:relative;
  left:110px;
}

最终效果:

Paste_Image.png

六、双飞翼布局

圣杯布局的实现,然后页面缩小到一定程度,就会错乱:

Paste_Image.png

这是就需要进一步优化,就是双飞翼布局啦。

<!DOCTYPE html>
<html>
<head>
<meta name="description" content="双飞翼布局" />
  <meta charset="utf-8">
  <title>JS Bin</title>
  <style>
    .main
    {
     /* height:350px;
      background:blue;*/
      width:100%;
    }
    .leftside
    {
      width:100px;
      height:300px;
      background:red;
      margin-left:-100%;
    }
    .rightside
    {
      width:100px;
      height:300px;
      background:yellow;
      margin-left:-100px;
    }
    .main,.leftside,.rightside
    {
      float:left;
    }
    .wrap
    {
      margin-left:100px;
      margin-right:100px;
      height:350px;
      background:blue;
    }
    .container
    {
      content:'';
      display:block;
      clear:both;
    }
  </style>
</head>
<body>
    <div class=container>
      <div class="main">
       <div class="wrap">main</div> 
      </div>
      <div class="leftside">leftside</div>
      <div class="rightside">rightside</div>
    </div>
</body>
</html>

实现效果

Paste_Image.png

七、浮动和负margin的区别以及应用

负margin是会改变到元素的实际所占坑位的大小的,所以当多个元素并行浮动放不下时,可以设置最后一个元素的负margin值,放到同一行。
负margin和position:relative的区别,CSS系列篇:零碎、细节点整理(二 )的这篇文章中已经梳理了。

1、应用:水平等距排列

子元素li设置浮动,父元素ul设置负margin

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <div class="ct">
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
      <li>6</li>
      <li>7</li>
      <li>8</li>
      <li>9</li>
    </ul>
  </div>
</body>
</html>
/*样式设置*/
*{
  margin:0;
  padding:0;
  list-style:none;
}
.ct{
  border:1px solid black;
  width:640px;
  margin:0 auto;
  overflow:hidden; /*形成BFC,清除浮动*/
}

li{
  width:200px;
  height:200px;
  background-color:red;
  float:left;
  margin:20px 0px 20px 20px;
}
ul{
  margin-left:-20px;
}

效果:

Paste_Image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,868评论 1 92
  • CSS布局 布局是CSS中一个重要部分,本文总结了CSS布局中的常用技巧,包括常用的水平居中、垂直居中方法,以及单...
    web前端学习阅读 1,648评论 1 38
  • 收听音频,戳链接,旧号itclan已暂停使用,欢迎关注微信itclanCoder公众号可收听更多音频 前言 关于网...
    itclanCoder阅读 8,254评论 3 30
  • 前言 温馨提示:本文较长,图片较多,本来是想写一篇 CSS 布局方式的,但是奈何 CSS 布局方式种类太多并且实现...
    sunshine小小倩阅读 3,205评论 0 59
  • 最近想和小伙伴们一起去上海自然博物馆逛逛。作为一枚学习自然科学的烟酒僧,只有科技馆和博物馆这样的地方才能合理地体现...
    LostAbaddon阅读 6,211评论 10 6