布局实现技巧之margin的使用——多列布局,自适应布局应用float和margin负值
2016-02-16 18:31

    写前端的小伙伴们对于margin和float这两个css样式都不陌生,但是你们真的了解他们吗,你们的用法真的对吗?

   我们看看margin,margin是声明一个元素的外边距的值,但是我们要注意margin的外边距的值可正可负,正值用于我们正常的美观间距,负值则可用于特殊布局的实现。

    margin使用

    1,margin值得塌陷现象。2,margin增加block元素的宽度。3,margin负值改变元素文档流的定位位置。

    坍陷现象就不介绍了,这个属于一个基础的知识点,我们来看看后两个功效,这两个功效主要用于布局实现上面。

    

像上面这种布局实现多列,并且中间有间隙。我们平时实现的话可能前面4个元素添加一个margin-right:15px;最后一个元素去除margin-right,来实现。当然这样也可以实现,但是我们需要给最后一个元素再加一个class或者内部style样式。这样无疑影响美观和大气。


        既然margin复制对于block元素有增加宽度的效果,那么我们猜想可以这样实现,通过添加margin-right:-15px;来增加容器15像素的宽度,然后每个子元素照样拥有margin-right:15px;但是在容器的外层通过:overflow:hidden;让多出的15px不显示。那么我们就可以这样实现。

    

<div class='container'>
	<div class='out clearfix'>
	    <ul>
		<li><div></div></li>
		<li><div></div></li>
		<li><div></div></li>
		<li><div></div></li>
		<li><div></div></li>
	     </ul>
	</div>
</div>
<style>
  body{margin:0;padding:0;list-style:none;}
 .clearfix{*zoom:1;}
 .clearfix:before,.clearfix:after{content:"";display:table;line-height:0;visibility:hidden;font-size:0;}
 .clearfix:after{clear:both;}
 .container{margin:20px;border:1px solid #13B9E2;}
 .out{width:100%;padding:10px 0;overflow:hidden;}
 .out ul{margin:0;padding:0;list-style:none;margin-right:-15px;}
 .out ul li{float:left;width:20%;}
 .out ul li div{margin-right:15px;height:200px;background:#E2B52B;}
</style>

你可以点击这里查看demo

如上代码,我们通过给ul添加margin-right:-15px;增加了ul的15px的宽度,他外层的out通过overflow:hidden;让其不显示,然后li每个为20%的宽度,就形成5个子元素并列了,内部的div再加上margin-right:15px,这样每个li中的div之间的间隔都就有了15px的间距,最后一个div的15px间距依然存在,只是在out元素之外而已。

我们把overflow:hidden;去掉之后再看

这样我们就可以很明显的看到ul比out超出了15像素的宽度,但在我们加上overflow:hidden;的时候他就会被截断,就能符合我们正常需要的展示了。


下面我们在看一下margin负值的定位,margin负值在inline元素和float元素中不会增加元素的宽度,而是会改变元素的位置,这个改变会导致他后面的元素跟着一起改变。也就是在inline,float,margin负值会改变后续文档流的位置,比如我们margin-left:-200px;那么在他之后的元素会基于此像做移动200px的距离,这会造成跟前面元素的部分重叠。而这个特性就正好有助于我们实现某些特定的布局。

像上面这个散列布局,我们设定左边元素宽度为240px;右边元素的宽度为210px;中间的容器宽度随浏览器自适应。

在实现这种布局的时候,我之前使用过absolute定位,相信现在也还有好多人在通过使用absolute定位来实现这种布局的定位。

absolute定位的原理比较简单,就是中间元素加一个margin:0 220px 0 250px;这样基于div的block属性默认宽度为100%;而在不加宽度属性的时候,此div会根据其margin值进行其宽度的自适应缩小。然后就是对左右两块内容运用absolute属性进行定位,将左边的定位到左边,右边的定位到右边。用此absolute定位可以很好的实现这种布局的展示,但是此布局有一个局限性,就是如果两边元素的内容高度高出了中间主体容器内容的高度后,就会导致左右两块地内容覆盖下面文档流中的元素内容,很好理解左右两块使用的都是absolute定位进行实现的,那么他们就已经脱离了文档流,自然不会撑开总容器,也就不能把他们下面的内容往下推。这种情况下除非使用js进行resize时计算设定总容器的高度,才能保证布局的良好展示。这算这个布局的一个缺点,但是在一些特定情况下还是可以使用的。

    比如在手机端多块中块的高度是固定的,而absolute元素的高度也是固定不大于总容器高度的时候。这种布局也具有自适应性。

    

    而相对于absolute定位实现此布局,利用margin负值进行实现,就显得更加优雅,和更加具有灵活性,通过margin负值实现,他们整体实在一个文档流中,只要我们没有忘记清楚浮动,那么下面的元素会根据三块内容中最高元素的高度往下面移动。

    这这个margin负值结合float实现的原理就是因为margin负值改变了元素的位置。

    

<div class='container clearfix'>
  <div class='main'>
	<div class='main-inner'></div>	
  </div>
  <div class='fleft'></div>
  <div class='fright'></div>
</div>
<style>
body{margin:0;padding:0;list-style:none;}
.clearfix{*zoom:1;}
.clearfix:before,.clearfix:after{content:"";display:table;line-height:0;visibility:hidden;font-size:0;}
.clearfix:after{clear:both;}
.container{margin:20px;}
.main{float:left;width:100%;}
.main-inner{margin-left:250px;margin-right:220px;background:#2EB4E6;height:400px;}
.fleft{width:240px;float:left;margin-left:-100%;background:#92E62E;height:400px;}
.fright{width:210px;float:left;margin-left:-210px;background:#ECA61F;height:400px;}	
</style>

从上面的代码看到,fleft通过margin-left:-100%;使得他本身相对于外层容器ul移动了一个ul的宽度。在此移动后,fright元素在文档流中也会跟随像前移动,也就是紧贴在main元素的最后面了。float和inline元素的margin负值对改变后续文档流的影响有些许区别,float不会让fright也向左移动100%的距离,而只是移动了fleft腾出的距离。

你可以点击这里查看demo

我们不妨让左右的元素高度变矮点,再给main元素加个背景看看效果如何。

我们可以看到,左右两块元素确实在margin元素之上,也就是说由于margin负值的作用,左右两块元素跟main元素发生了重叠。而适当的给main-inner加一个margin属性就可以实现此性能良好的散列适应性布局了。

原创文章,转载请注明来自:妹纸前端-www.webfront-js.com.
阅读(2734)
辛苦了,打赏喝个咖啡
微信
支付宝
妹纸前端
妹纸前端工作室 | 文章不断更新中
京ICP备16005385号-1