web前端学习笔记(CSS变化宽度布局)
一、“1-2-1”单列变宽布局:
对于变宽度的布局,首先要使内容的整体宽度随浏览器窗口宽度的变化而变化。因此中间的 container 容器中的左右两列的总宽度也会变化,这样就会产生不同的情况。这两列是按照一定的比例同时变化,还是一列固定,另一列变化。这两种都是很常用的布局方式。然而对于等比方式而言,相对比较简单,和我上一篇博客中 1-2-1 的布局方式非常类似,因此这里只是介绍一列固定另一列变宽的 case。
在实际的应用中,只有单列宽度变化,而其它保持固定的布局可能会更加实用。一般在存在多个列的页面中,通常比较宽的一个列是用来放置内容的,而窄列放置链接、导航等内容,这些内容一般宽度是固定的,不需要扩大。因此如果能把内容列设置为可以变化,而其他列固定,会是一个很好的方式。
考虑到综合原因,该篇博客将只是给出示意图和 CSS 关键概要。
示意图:
原理分析:
核心的问题就是浮动列的宽度应该等于“100% - 300px”,而 CSS 显然不支持这种带有减法运算的宽度表达方法。但是通过 margin 可以变通的实现这个宽度。实现的原理为,在 content 外面再套一个 div,即图中的 contentWrap,使它的宽度为 100%,也就是等于 container 的宽度。然后通过将其margin-left设置为-300px,就使它向左平移了 300px。再将 content 的margin-left设置为正的300px,就实现了“100% - 300px”这个本来无法表达的宽度。此时,content 在 contentWrap 的里面,以标准流的方式存在,将将其左侧 margin 设置为 300px 之后,就可以保证里面的内容不会溢出到布局的外面。这种方法的最大好处就是不用考虑各列的高度,通过设置 footer 的 clear: both 属性,就可以保证不会发生重叠现象。
CSS 简要代码:
#header, #footer, #container {
margin: 0 auto;
width: 85%;
}
#contentWrap {
margin-left: -300px;
float: left;
width: 100%;
}
#content {margin-left: 300px;}
#side {
float: right;
width: 300px;
}
#footer {clear: both;}
二、“1-3-1”单侧列宽度固定的变宽布局:
对于一列固定、其它两列按比例适应宽度的情况,如果这个固定的列在左边或右边,那么只需要在两个变宽列的外面套一个 div,并且这个 div 宽度是变宽的。它与旁边的固定宽度列构成一个单列固定的“1-2-1”布局,然后再将变宽列中的两个变宽列按比例并排,就很容易实现了。对于上例中的 contentWrap 容器,如果内部只有一个 div 活动列,就像上面的“1-2-1”布局那样,这个活动列以标准流方式放置,它的宽度是自然形成的,这样显示效果是没有问题的,而当 contentWrap 容器中有两个浮动的活动列时,就需要分别设置宽度,比如分别为 40% 和 60%(为了避免四舍五入误差,这里设置 59.9%)。需要特别注意的是,contentWrap 列的宽度等于 container 的宽度,因此这里的 40% 并不是总宽度减去 side 的宽度以后的 40%,而是总宽度的 40%,这显然不是我们想要的。解决的方法就是在容器里面再套一个 div,即由原来的一个 contentWrap 变为两层,分别叫做 outerWrap 和 innerWrap。
示意图:
原理分析:
新增加的 innerWrap 是以标准流方式存在的,宽度会自然伸展,由于设置了 200px 的左侧 margin,因此它的宽度就是总宽度减去 200px 了,这样,innerWrap 里面的 navi 和 content 就会以这个新宽度为宽度基准。
CSS 简要代码:
#header, #footer, #container {
margin: 0 auto;
width: 85%;
}
#outerWrap {
float: left;
width: 100%;
margin-left: -200px;
}
#innerWrap {margin-left: 200px;}
#navi {
float: left;
width: 40%;
}
#content {
float: right;
width: 59.5%;
}
#side {
float: right;
width: 200px;
}
#footer {clear: both;}
三、“1-3-1”中间列宽度固定的变宽布局:
这里介绍的布局形式是,固定列被放在中间,它的左右各有一列,并按比例适应总宽度。这是一种很少见的布局方式,之所以给出只是为了 CSS 的研究和练习。
示意图:
原理分析:
这里以固定的“1-3-1”布局为基础。现在需要在 navi 和 side 两个 div 外面分别套一层 div,把它们包裹起来。将左侧的 naviWrap 设置为 50% 宽度,向左浮动,并通过将margin-left设置为-150px,向左平移了 150px。然后在里面的 navi 中,左侧margin-left设置为150px,补偿回来这 150px。接着,将 content 设置为固定宽度,先做浮动,这就就紧贴着 navi 的右边界。最后将 sideWrap 做与 navi 部分相似的处理,设置为 50% 宽度,向右浮动。这时本来宽度已经超过 100%,会被挤到下一行,但是将右侧margin-right设置为-150px后,就不会超过总宽度了。
CSS 简要代码:
#header, #footer, #container {
margin: 0 auto;
width: 85%;
}
#naviWrap {
width: 50%;
float: left;
margin-left: -150px;
}
#navi {margin-left: 150px;}
#content {
float: left;
width: 300px;
}
#sideWrap {
width: 49.9%;
float: right;
margin-right:-150px;
}
#side {margin-right: 150px;}
#footer {clear: both;}
四、“1-3-1”双侧列宽度固定的变宽布局:
对于三列布局,一种很实用的布局是 3 列中的左右两列宽度固定,中间列宽度自适应。
示意图:
原理分析:
先把左边和中间两列看做一组,作为一个活动列,而右边的一列作为固定列。然后再把两列各自当做独立的列,左侧为固定列,最后保留 content 为变宽列。在使用该方法时,每实现一个活动列都需要增加额外的辅助 div。这里的思路是,在内层,为了使 navi 固定,content 变宽,在二者外面套了一个“innerWrap”的 div;为了在 innerWrap 中使 content 能够变宽,在 content 外面又套了“contentWrap”div;同理,为了使 innerWrap 能够变宽,又为它套了一个 outerWrap,从而是结构变得复杂。但实际上原理还是相同的。
CSS 简要代码:
#header, #footer, #container {
margin: 0 auto;
width: 85%;
}
#side {
width: 200px;
float: right;
}
#outerWrap {
width: 100%;
float: left;
margin-left: -200px;
}
#innerWrap {margin-left: 200px;}
#navi {
width: 150px;
float: left;
}
#contentWrap {
width: 100%;
float: right;
margin-right: -150px;
}
#content {margin-right: 150px;}
#footer {clear: both;}
五、“1-3-1”中列和侧列宽度固定的变宽布局:
这里介绍的布局方式为中间列和它一侧的列是固定宽度,另一侧列宽度自适应。
示意图:
原理分析:
假设仍然希望左侧的 navi 和 content 列的宽度分别固定为 150px 和 250px,右侧的 side 列宽度变化。那么 side 列的宽度就等于“100% - 150px - 250px”。该方法将在 side 列的外面再套一个 sideWrap 列,使 sideWrap 的宽度为 100%,并通过设置margin-right为-400px,使其向右平移 400px。然后再对 side 列设置正的margin-right,限制右边界,这样就可以实现希望的效果了。
CSS 简要代码:
#header, #footer, #container {
margin: 0 auto;
width: 85%;
}
#navi {
flaot: left;
width: 150px;
}
#content {
float: left;
width: 250px;
}
#sideWrap {
float: right;
width: 100%;
margin-right: -400px;
}
#side {margin-right: 400px;}
#footer {clear: both;}
注:该篇博客源自《CSS 设计彻底研究》中的第十四章,书中的例子简明扼要、通俗易懂,因此选取部分主要内容与大家分享,同时也便于今后自己的在线查阅。