首页
web设计
Web2.0
案例分析
正文
牢不可破的九宫格布局
发布日期:
2009.06.23
浏览:
1005次 关键字:
牢不可破 九宫 布局
在我的前一篇教程《九宫格基本布局》中,我介绍了用相对定位加绝对定位的方法来制作九宫格的基本布局。这是一种比较符合人们惯性思维的方法,好像制作过程中一切都是顺理成章的事情,然而因为IE6让人恶心的奇偶性BUG,使得这种布局方法要想通用变得有点遥不可及,因为国内大多数用户还是用着IE6,我们不能因此而丢掉这部分用户。
这个BUG目前是无药可治,也没有什么Hack技巧能运用,唯一能用的方式就是绕开它。也就是说我要定位这九宫格的四个角容器的位置,绝对定位的方法是不能采用的了,这不吝是一个重大的打击,这将完全推翻我前一篇文章中用到的方法,我们只好另起炉灶了。
那么还有那些技术能够拯救这个BUG于水深火热之中呢?我们知道如果用左右浮动的方法能够准确地将元素对象发生偏移,并且这种方法也能避免IE6的奇偶性BUG。OK,我们就用它了。
布局的重点和难点
我们还是按照表格的结构来构建我们新模型的结构体,然而这次会相对于前一篇文章的结构有所改变。在这个模型中我们要关注的重点和难点是以下这两点:
1、 t_m和b_m这两个中间容器的宽度值必须是一个百分比的值,否则不能保证整个九宫格的左右动态伸展,它决不能为某个固定的像素值。其宽度等于总容器宽度减去两侧角容器宽度之和的百分比值。其计算公式为:
t_m(或b_m)的宽度=(总容器宽度-(左上角容器宽+右上角容器宽度))/总容器宽度
也就是说t_m或b_m的宽度不是100%,然而t_l和t_r这两个容器的宽度在实际案例中一般是一张图片的宽度,所以它一般都是一个固定宽度值,这样在一个同行的三个容器中,左右两侧宽度是固定值,而中间又要求是百分比,并且这三个容器的总宽度加起来应该是100%,这该怎么办呢?
这里我们采用一种比较稳妥的办法来让中间容器能达到理想的宽度百分比:
我们可以用一个DIV容器,设置它的padding:0 10px;不设置它的宽度,默认状况下,它的宽度就是100%的。因为设置了左右的padding值,则其内部的宽度就是我们要的t_m的理想宽度值,因此我们再给它内部定义一个容器,这个子容器宽度设置为100%。这个子容器的背景色就可以设置为左右水平平铺的背景图片。这个子容器就是我们要用到的上顶边容器。它满足了我们对宽度值的特殊要求。
因此这个t_m的结构就可以做成如下的结构:
<div class="top"><span class="t_m"></span></div>
然而这样定义会导致另外一个问题,这个问题在IE7以下的浏览器的都存在,因为我们定义了padding,会在下面的中间的主体层中也同时产生左右侧的内补丁,这里有点不明白的是:为什么会对IE7产生影响?
因此其补救方法是在这儿针对IE6和IE7应用一个HACK技巧:
.b_l{margin-left:0px;+margin-left:-10px;_margin-left:-10px;}
.b_r{margin-right:0px;+margin-right:-10px;_margin-right:-10px;}
这句话是针对三种浏览器设置不同的偏移值,将b_l和b_r向左右偏移到指定的位置。
2、 b_l和b_r这两个容器的高度值必须相同,以使它们可以一直垂直向下平铺背景色。这样,当中间主体内容区(context)中内容的高度发生改变时,其两侧的背景色能一直和主体内容区(context)保持同一高度。也就是说它们能根据内容主体的高度而自由地拉伸自己的高度值。
我们可以采用在平时工作中经常用到的多列同高的方法来处理这个问题。这个方法就是采用内补丁和负外补丁相结合的方式来达到多列同高:
.m_l,.m_r{padding-bottom:30000px;margin-bottom:-30000px;}
我们将m_l和m_r的下内补丁padding-bottom的值设置为一个相对比较大的值,比如我将它们设置为30000px(你可以将它设置为你想要的值),相信一般的情况下,是不会超过这个高度值了。然后将下外补丁(margin-bottom)设置为和下内补丁(padding-bottom)值相同的负值,将它拉回到原来的位置上,并将总容器(box)设置overflow:hidden;,截除多余的高度,就可以保证两列同高。
将上面两个难点问题解决后,余下的事情就是简单而愉快的事情了!
结构层
现在我们将结构层在前一个案例的基础上作了一下调整,因此就成了下面这样一种结构了:
<div class="box">
<!--第一行—顶部*/-->
<div class="top"><span class="t_m"></span></div>
<span class="t_l"></span>
<span class="t_r"></span>
<!--第二行—中间内容区*/-->
<span class="m_l"></span>
<span class="m_r"></span>
<div class="context">内容主体区域</div>
<!--第三行—底部*/-->
<div class="b_m"><span></span></div>
<span class="b_l"></span>
<span class="b_r"></span>
</div>
样式层
下面是主要的样式设置:
/*总容器*/
.box{overflow:hidden;width:50%;margin:50px auto 0;background:#fff;}
.box span{display:block;}
/*顶部样式*/
.top{height:10px;padding:0 10px;}
.t_l,.t_r{width:10px;height:10px;font-size:0%;margin-top:-10px;}
.t_l{float:left;background:#ff0000;}/*左上角*/
.t_r{float:right;background:#ff0000;}/*右上角*/
.t_m{height:10px;font-size:0%;width:100%;background:#7F0000;}/*这是可左右伸展的区域,两例留出空白便于放置左右角容器*/
/*中间样式*/
.m_l,.m_r{width:10px;padding-bottom:30000px;margin-bottom:-30000px;}/*两列等高*/
.m_l{float:left;margin-left:0px;+margin-left:-10px;_margin-left:-10px;background:#7F0000;} /*左边框*/
.m_r{float:right;margin-right:0px;+margin-right:-10px;_margin-right:-10px;background:#7F0000;} /*右边框*/
/*底部样式*/
.b_m{padding:0 10px;height:10px;}/*这是可左右伸展的区域,两例留出空白便于放置左右列同高容器*/
.b_m span{width:100%;height:10px;font-size:0%;background:#7F0000;}
.b_l,.b_r{height:10px;font-size:0%;width:10px;margin-top:-10px;}
.b_l{float:left;background:#ff0000;}/*左下角*/
.b_r{float:right;background:#ff0000;}/*右下角*/
经过上述设置后,我们的九宫格就算完成了,它是“牢不可破”的,会随着内容主体的宽高动态地向各个方向自由伸展。在此模型中,为了演示的效果,我将总容器的宽度设置了一个百分比50%,你可以根据你的实际需要调整它的大小,其内部会随着它的宽度值自动填充整个区域,不会撑破父容器。如下图所示:

你可以用八张图片来制作一个漂亮的九宫格盒子。看看它的完美表现。
本模型在以下浏览器中测试通过:
IE5.5、IE6、IE7、IE8、FF3、TT、Maxthon2.1.5、Opera9.6、Safari4.0、Chrome2.0。
运行代码框
[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]
SELECT [t0].[a_id], [t0].[a_site], [t0].[a_model], [t0].[a_type], [t0].[a_special], [t0].[a_name], [t0].[a_from], [t0].[a_from_url], [t0].[a_author], [t0].[a_editor], [t0].[a_describe], [t0].[a_content], [t0].[a_create_date], [t0].[a_tag], [t0].[a_hits], [t0].[a_commend], [t0].[a_istop], [t0].[a_isimg], [t0].[a_cacheimg], [t0].[a_imgurls], [t0].[a_imgurl], [t0].[a_ismedia], [t0].[a_mediaurl], [t0].[a_iscomment], [t0].[a_isRecycle], [t0].[a_weight], [t0].[a_weights], [t0].[a_status], [t0].[a_url], [t0].[a_file_path], [t0].[a_contentfile], [t0].[a_comment], [t0].[a_ispass], [t0].[a_bury], [t0].[a_dig], [t0].[a_score], [t0].[a_rank], [t0].[a_diguser], [t0].[a_buryuser], [t0].[a_viewip], [t0].[a_lastviewdate], [t0].[a_neworimageorvideo], [t0].[class_id], [t0].[class_type], [t0].[class_name], [t0].[class_show_name], [t0].[class_parent_id], [t0].[class_id_path], [t0].[class_name_path], [t0].[class_show_name_path], [t0].[class_depth], [t0].[class_order], [t0].[class_content], [t0].[class_img], [t0].[a_model_name]
FROM [dbo].[mvc_content_view] AS [t0]
WHERE ([t0].[a_id] = @p0) AND ([t0].[a_type] = @p1) AND (NOT ([t0].[a_isRecycle] = 1))
-- @p0: Input BigInt (Size = 0; Prec = 0; Scale = 0) [6354]
-- @p1: Input BigInt (Size = 0; Prec = 0; Scale = 0) [240]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1
SELECT TOP (1) [t0].[a_id], [t0].[a_name]
FROM [dbo].[mvc_content_view] AS [t0]
WHERE ([t0].[a_type] = @p0) AND ([t0].[a_id] < @p1) AND (NOT ([t0].[a_isRecycle] = 1))
ORDER BY [t0].[a_id] DESC
-- @p0: Input BigInt (Size = 0; Prec = 0; Scale = 0) [240]
-- @p1: Input BigInt (Size = 0; Prec = 0; Scale = 0) [6354]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1
SELECT TOP (1) [t0].[a_id], [t0].[a_name]
FROM [dbo].[mvc_content_view] AS [t0]
WHERE ([t0].[a_type] = @p0) AND ([t0].[a_id] > @p1) AND (NOT ([t0].[a_isRecycle] = 1))
ORDER BY [t0].[a_id]
-- @p0: Input BigInt (Size = 0; Prec = 0; Scale = 0) [240]
-- @p1: Input BigInt (Size = 0; Prec = 0; Scale = 0) [6354]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1
SELECT TOP (10) [t0].[a_id], [t0].[a_site], [t0].[a_model], [t0].[a_type], [t0].[a_special], [t0].[a_name], [t0].[a_from], [t0].[a_from_url], [t0].[a_author], [t0].[a_editor], [t0].[a_describe], [t0].[a_content], [t0].[a_create_date], [t0].[a_tag], [t0].[a_hits], [t0].[a_commend], [t0].[a_istop], [t0].[a_isimg], [t0].[a_cacheimg], [t0].[a_imgurls], [t0].[a_imgurl], [t0].[a_ismedia], [t0].[a_mediaurl], [t0].[a_iscomment], [t0].[a_isRecycle], [t0].[a_weight], [t0].[a_weights], [t0].[a_status], [t0].[a_url], [t0].[a_file_path], [t0].[a_contentfile], [t0].[a_comment], [t0].[a_ispass], [t0].[a_bury], [t0].[a_dig], [t0].[a_score], [t0].[a_rank], [t0].[a_diguser], [t0].[a_buryuser], [t0].[a_viewip], [t0].[a_lastviewdate], [t0].[a_neworimageorvideo], [t0].[class_id], [t0].[class_type], [t0].[class_name], [t0].[class_show_name], [t0].[class_parent_id], [t0].[class_id_path], [t0].[class_name_path], [t0].[class_show_name_path], [t0].[class_depth], [t0].[class_order], [t0].[class_content], [t0].[class_img], [t0].[a_model_name]
FROM [dbo].[mvc_content_view] AS [t0]
WHERE ([t0].[a_type] IN (@p0)) AND (NOT ([t0].[a_isRecycle] = 1))
ORDER BY [t0].[a_id] DESC
-- @p0: Input BigInt (Size = 0; Prec = 0; Scale = 0) [240]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1
SELECT TOP (10) [t0].[a_id], [t0].[a_site], [t0].[a_model], [t0].[a_type], [t0].[a_special], [t0].[a_name], [t0].[a_from], [t0].[a_from_url], [t0].[a_author], [t0].[a_editor], [t0].[a_describe], [t0].[a_content], [t0].[a_create_date], [t0].[a_tag], [t0].[a_hits], [t0].[a_commend], [t0].[a_istop], [t0].[a_isimg], [t0].[a_cacheimg], [t0].[a_imgurls], [t0].[a_imgurl], [t0].[a_ismedia], [t0].[a_mediaurl], [t0].[a_iscomment], [t0].[a_isRecycle], [t0].[a_weight], [t0].[a_weights], [t0].[a_status], [t0].[a_url], [t0].[a_file_path], [t0].[a_contentfile], [t0].[a_comment], [t0].[a_ispass], [t0].[a_bury], [t0].[a_dig], [t0].[a_score], [t0].[a_rank], [t0].[a_diguser], [t0].[a_buryuser], [t0].[a_viewip], [t0].[a_lastviewdate], [t0].[a_neworimageorvideo], [t0].[class_id], [t0].[class_type], [t0].[class_name], [t0].[class_show_name], [t0].[class_parent_id], [t0].[class_id_path], [t0].[class_name_path], [t0].[class_show_name_path], [t0].[class_depth], [t0].[class_order], [t0].[class_content], [t0].[class_img], [t0].[a_model_name]
FROM [dbo].[mvc_content_view] AS [t0]
WHERE ([t0].[a_type] IN (@p0)) AND (NOT ([t0].[a_isRecycle] = 1))
ORDER BY [t0].[a_id] DESC
-- @p0: Input BigInt (Size = 0; Prec = 0; Scale = 0) [240]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1
SELECT TOP (10) [t0].[a_id], [t0].[a_site], [t0].[a_model], [t0].[a_type], [t0].[a_special], [t0].[a_name], [t0].[a_from], [t0].[a_from_url], [t0].[a_author], [t0].[a_editor], [t0].[a_describe], [t0].[a_content], [t0].[a_create_date], [t0].[a_tag], [t0].[a_hits], [t0].[a_commend], [t0].[a_istop], [t0].[a_isimg], [t0].[a_cacheimg], [t0].[a_imgurls], [t0].[a_imgurl], [t0].[a_ismedia], [t0].[a_mediaurl], [t0].[a_iscomment], [t0].[a_isRecycle], [t0].[a_weight], [t0].[a_weights], [t0].[a_status], [t0].[a_url], [t0].[a_file_path], [t0].[a_contentfile], [t0].[a_comment], [t0].[a_ispass], [t0].[a_bury], [t0].[a_dig], [t0].[a_score], [t0].[a_rank], [t0].[a_diguser], [t0].[a_buryuser], [t0].[a_viewip], [t0].[a_lastviewdate], [t0].[a_neworimageorvideo], [t0].[class_id], [t0].[class_type], [t0].[class_name], [t0].[class_show_name], [t0].[class_parent_id], [t0].[class_id_path], [t0].[class_name_path], [t0].[class_show_name_path], [t0].[class_depth], [t0].[class_order], [t0].[class_content], [t0].[class_img], [t0].[a_model_name]
FROM [dbo].[mvc_content_view] AS [t0]
WHERE ([t0].[a_type] IN (@p0)) AND (NOT ([t0].[a_isRecycle] = 1))
ORDER BY [t0].[a_hits] DESC, [t0].[a_id] DESC
-- @p0: Input BigInt (Size = 0; Prec = 0; Scale = 0) [240]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1