您的位置:首页 > Web前端 > CSS

浮动情况下的负外边距的研究以及经典布局

2016-07-26 23:33 447 查看

引子

最近看了一眼最新的面试题,准备秋招,发现了一个比较老的题,就是div+css经典布局的二列式布局和三列式布局,比如:两列布局,左边定宽,右边自适应。或者三列布局,两边定宽,中间自适应。这不很好写么,比如我以前这么写

/*css代码*/
body{
margin:0;
padding:0;
}
.left{
float:left;
width:300px;
height:600px;
background-color: #ac2925;
}
.container{
height:600px;
background-color: #1b6d85;
margin-left:310px;
}

----------

<!--html结构代码-->
<div id="test">
<div class="left">左侧固定宽度</div>
<div class="container">右侧自适应宽度</div>
</div>


很好,这并没有什么错误而且也实现了功能,而且一不会影响接下来div的正常排列,但接下来,一篇博客引起了我的注意,博主提出了一个强硬的条件,div的顺序如果倒过来(也就是上面代码的左侧和右侧的div代码块换下顺序),那么就会出现一个问题,排列走样了。


这个问题也很好理解,由于右侧div是没有浮动的,也就是他没有脱离文档流,正常来讲,他应该被盖在红的下面,所以我们在上面设置了margin来偏移div(浮动理解为沿着z轴漂浮,但飘起来的元素不一定在一个面内)。但是顺序的改变带来了一点微妙的变化,没有浮动的div是一个block元素,他在文档流中单独占一行,并且有marign-left的css,所以才会出现第一行有空白,这样,图片上显示的就很清楚了。

那么怎么办呢,那篇文章的博主是这么写的(我会在底下给出链接)

html

<div id="wrap">
<div id="content" style="height:140px;">
<div id="contentb">
content自适应区,在前面
</div>
</div>
<div id="sidebar" style="height:240px;">sidebar固定宽度区</div>
</div>


css

#sidebar {
width: 300px; float: right;background-color: #ac2925;
}
#content {
margin-left: -310px; float: left; width: 100%;background-color: #1b6d85;
}
#contentb {
margin-left: 310px;background-color: #245269;
}


这里为了看的更清楚,我加上了颜色



解释一下这篇博主的思想(他是左边自适应,右边固定宽):把左边的也浮动起来,这样他就没有了默认宽度,再把宽度设置为100%,这样左边的宽度就等于浏览器宽度,然后把他margin-left一个负红块的宽度,这样红块就可以浮动上来了,然后由于margin-left了,相当于左移了距离,那么在把里面的内容div(contentb)进行margin-left一个正值宽度,就可以正常显示了。

出于好奇,想做一个左边宽度固定,右边宽度自适应的,那大家想了还不简单,把这里面的左浮动换右浮动,margin-left换成margin-right不就完了么。

注意,并不是这样,这个地方有一个问题,当你这么还完了之后,是有这种效果,但是出现了下边的横向滚动条和右边拉过去的一片空白(就是margin-right:-310px 的这个310px)。

那么到底是怎么回事呢,于是我小小研究了一下margin在浮动情况下负值到底代表这什么。

分情况讨论

这里我们结合浮动来讨论,例如:左浮动+margin-left:负值,简称为左左。

左左:这种情况,相当于你的div向左偏移了一个margin-left的值(负值),不会出现滚动条,于是就有了一部分被浏览器左边隐藏了得效果。

右右:这种情况,相当于你的div向右偏移了一个margin-right的值(负值),但是会出现滚动条,而且右边滚动条拉过去会出现白边,白边的值就是你设置的margin-right的值。

左右:这个和接下来的都是要重点研究一下的,推荐各位可以自己试一下啊,然后感受一下变化和差距。正常情况下来想,一个div设置了左浮动,那还要他的右外边距干什么?他的右外边距应该由挨着他的下一个元素的左外边距来控制,但是这里margin-right变成了一个负值,接下来的现象就很神奇了,他的宽度相当于在减少,但是实际上展现在页面上的还是那个宽度,这就意味着,当这个负值等于他本身的宽度的时候,他的宽度对挨着他的浮动元素来说就是0!!!这样,就可以实现100%宽度的上浮,并可以实现经典的二列布局,见代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>二列布局,左宽固定,右自适应</title>
<style>
/*css代码*/

.left{
float:left;
height:600px;
width:300px;
margin-right:-300px;
background-color: #ac2925;
font-size: 29px;
}
.container{
float:right;
width:100%;
background-color: #1b6d85;
}
.container_a{
margin-left:310px;
height:600px;
background-color: #afd9ee;
font-size: 29px;
}
</style>
</head>
<body>
<div id="wrap">
<div class="container">
<div class="container_a">自适应宽度</div>
</div>
<div class="left">固定宽度</div>
</div>
</body>
</html>


这里面,div的顺序只是影响了他们在z轴的高度,在前面的div比z轴坐标值小(表现出来的就是被后面的div盖上了,用类似z-index那种属性来理解),这样就算换了顺序,还是原来的样子,不会出现上面的问题(注意可能自适应有两层div,外层div推荐设成无色,这样就不会有覆盖问题,具体可以调调div顺序来观察一下。)



然后右左就和这个一样了,现在想要换成左边适应,右边固定,你只要把left换成right,right换成left就ok了。

最后,写一个三列的,左右固定,中间自适应

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>三列布局,左右宽固定,中间自适应</title>
<style>
/*css代码*/

.left{
float:left;
height:600px;
width:300px;
margin-right:-300px;
background-color: #ac2925;
font-size: 29px;
}
.container{
float:left;
width:100%;
}
.container_a{
margin:0 310px 0 310px;
height:600px;
background-color: #afd9ee;
font-size: 29px;
}
.right{
float:right;
height:600px;
width:300px;
margin-left:-300px;
background-color: #ac2925;
font-size: 29px;
}
</style>
</head>
<body>
<div id="wrap">
<div class="left">固定宽度</div>
<div class="container">
<div class="container_a">自适应宽度</div>
</div>
<div class="right">固定宽度</div>
</div>
</body>
</html>




最后感谢这篇博客的博主,这是他的博客博客链接

还有这些天大概看了一下bootstrap,感觉不是很习惯,有没有感觉现在网页全是bootstrap风格的,看久了也不爱看了。

这种对css布局和语法最基本的研究虽然可能用处不是很大,但是明白了当年一代而过的知识之后,还是很开心的。这几天把我学的bootstrap更新一下,然后就可以放假回家,等待秋招啦!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  css 布局