如何最好地实现这个特定的布局?

4
我希望我的网站能够有类似StumbleUpon的功能,可以查看外部文章。侧边栏用于评论等。这是它的jsfiddle

我已经做了什么:

HTML

<div id="header">Head</div>
<div id="sidebar">Sidebar</div>
<iframe id="article" src="http://cnn.com"></iframe>

CSS

html,body{width:100%;height:100%;overflow:hidden;}
#header{width:100%;height:49px;border-bottom:1px solid #000;}
#sidebar{height:100%;width:249px;border-right:1px solid #000;float:left;}
#article{border:0;overflow:visible;float:right;}

JS

$('#article').height($('html').height()-50).width($('html').width()-$('#sidebar').outerWidth()-1);

我发现实现这种布局的方法很多,包括浮动、绝对定位、内边距、表格(绝对不是)等等。在兼容性和速度方面,什么是最佳实现方式?


6
关于改善已经工作的代码的问题,应该去http://codereview.stackexchange.com/询问。 - James Montagne
我发现每种方法都有其缺陷,所以我在这里发布它。在速度较慢的 CPU 上,浮点数会出现延迟,position:absolute 在触摸屏设备上效果不佳,而 padding 在 IE 中的行为也不同。 - Leo Jiang
如果你设置了正确的文档类型(doctype),IE 将具有与其他浏览器相同的盒子模型。 - tybro0103
3
“最好的方式”在这里是一个相当主观的术语。 - darryn.ten
我正在寻找各种可能性,而我(或社区)可以确定“最佳”方式。我主要关注(按重要性大致顺序)兼容性、易用性、速度和清晰的代码。 - Leo Jiang
显示剩余4条评论
7个回答

1

HTML5,适用于IE7及以上版本(感谢html5shiv)。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">  
    <!--[if lt IE 9]>
    <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->

    <style>    
        body,html{
          padding: 0;
          margin: 0;      
        }

        header{    
          height: 49px;
          border-bottom: 1px solid black;
          background-color: #fdd;
        }

        nav {
          position: absolute;     
          width: 249px;
          top: 50px;
          bottom: 0;
          left: 0;
          background-color: #dfd;
          border-right: 1px solid black;
          overflow: hidden;
        }

        body > section {
          position: absolute;
          top: 50px;
          right: 0; 
          bottom: 0;
          left: 250px;
          overflow: auto;
          background-color: #ddf;
        }
    </style>
</head>    
<body>

    <header>
        Header
    </header>  

    <nav>
        Sidebar
    </nav>

    <section>
        <article>
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
        </article>      
    </section>

</body>
</html>

如果您希望更通用,可以使用aside。但是侧边栏大多数情况下用于网站导航。 - tomtastico

0
<style>
  #side_bar {
    width:200px;
    float:left;
  } #body_con {
    overflow:hidden; /*expands to fit in sidebar*/
  } #main_content {
    margin-left:200px;
  }
</style>

<div id="header"></div>
<div id="body_con">
  <div id="side_bar"></div>
  <div id="main_content"></div>
</div>

就是这么简单。


1
你建议的样式中没有浮点数吗? - darryn.ten
看起来你在 body_con 中有一个额外的闭合 div,而且我没有看到标题的任何样式? - ScottS
@ScottS 又有一个错别字,已经修复。标题不需要任何样式即可适应位置。 - tybro0103
我猜头部缺乏样式是@Linksku自己决定的。从他的布局要求中,我的印象是body高度为100%,header高度固定,剩下的空间用于sidebararticle。你的解决方案会在页面(而不仅仅是文章)很长时出现滚动条(根据他最初的fiddle,他似乎想避免这种情况)。这只是我对他布局要求的理解。对他来说,100%的body高度可能并不是关键。 - ScottS

0
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>

  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

  <title></title>

  <style>

  body,html{
    padding: 0;
    margin: 0;
    height: 100%;
    cursor: default;
    overflow: hidden;
  }
  #divContainer{
    position: relative;
    height: 100%; 
  }
  #divHead{
    position: relative;
    height: 100px;
    border-bottom: 1px solid #ccc;
    background-color: #eee;
  }
  #divMain{

  }
  #divSidebar{
    position: absolute;
    background-color: #eee;
    border-right: 1px solid #ccc;
    width: 250px;
    left: 0;
    top: 101px;
    bottom: 0;
    overflow: hidden;
  }
  #divContent{
    position: absolute;
    left: 251px;
    top: 101px;
    bottom: 0;
    right: 0;
    overflow-y: scroll;
  }


  </style>  

</head>                                                              

<body>

  <div id='divContainer'>

    <div id='divHead'>
      Header
    </div>

    <div id='divMain'>
      <div id='divSidebar' >
        Sidebar
      </div>
      <div id='divContent' >
        Content    
      </div>
    </div>

  </div>

</body>
</html>

0

我从未在触摸设备上遇到position:absolute的兼容性问题,您确定您没有将其与fixed混淆吗?另外,padding在所有浏览器中都表现出色,除非您将IE设置为怪异模式,您绝对不希望出现这种情况,因为有很多原因。

在您的布局中,我会使用position:absolute,因为您正在将所有东西挤在body内,而没有自然的滚动流。

绝对定位还具有一个巨大的优点;您可以进行以下操作:left:250px;right:0,它将用250px的左边距扩展可用区域。我认为,这是在容器内编程流体布局的更合理方式,而不是使用浮动来进行负边距和其他hack技术。

另一个重要方面:使用绝对定位,您还可以将文章DIV移动到内容顺序中侧边栏之上。这是许多人忘记的事情,在大多数情况下,使屏幕阅读器和搜索引擎尽快到达内容是更有意义的。

它的缺点是IE6及以下版本不支持,但在this article中有简单的解决方法(如您所见)。
使用浮动仍然是一种选择,但正如我所提到的,它可能会造成更多的麻烦,因为它们被设计为自然布局流的一部分。
我还会将iframe放在一个#article div内,这样与布局网格分开更有意义。
类似于this
<div id="header">Head</div>
<div id="article">
    <iframe src="http://cnn.com"></iframe>
</div>​
<div id="sidebar">Sidebar</div>

还有CSS:

html,body {
    width:100%;
    overflow:hidden;
}
#header {
    position:absolute;
    left:0;
    right:0;
    height:49px;
    border-bottom:1px solid #000;
}
#sidebar {
    position:absolute;
    top:50px;
    bottom:0;
    width:249px;
    border-right:1px solid #000;
}
#article {
    position:absolute;
    top:50px;
    left:250px;
    right:0;
    bottom:0;
}
#article iframe {
    border:none;
    width:100%;
    height:100%;
}

最终,针对IE5和IE6的一些神奇技巧(如果您想走那么远):

<!--[if lt IE 7]>
<style>    
body, #header { width:100% }
#sidebar, #article{ height: expression(document.body.clientHeight-50) }
#article{ width: expression(document.body.clientWidth-250) }
</style>
<![endif]-->

兼容性而言,这应该是最兼容的。它可以在没有JavaScript的情况下工作,并且是流式的(或者现在称为“响应式”),因此应该适用于许多不同的屏幕尺寸。但是,根据您如何设置缩放默认值,您可能需要添加一些媒体查询来在最小屏幕上重新排列布局。

速度而言,有一个关于渲染速度的大瓶颈,那就是使用JavaScript进行DOM操作。只需将其留出即可,然后您可以使用任何CSS技术。 (同意,IE5/6表达式不是可用的最快速度渲染方法,但它可以正常工作,我们正在谈论严重的遗留支持...)

有人可能会认为使用HTML5元素,例如HEADERASIDEARTICLE是合适的,但您需要一个HTML5 shim脚本才能使其在某些IE版本中工作,然后您会失去一些没有安装JavaScript的兼容性。


您可能还需要调整IE7-的iframe设置,以保持100%的高框架高度,但我不确定您是否真的想使用iframe,或者它只是其他东西的占位符。 - David Hellsing

0
针对您的评论:“我主要寻找(按重要性大致顺序)兼容性、易用性、速度和清晰代码。” 兼容性:这似乎是您最关心的问题。您的另一个评论说:“在慢速CPU上,浮动会很卡顿,position:absolute在触摸设备上效果不佳,而且IE中的填充行为不同。”正如tybro0103在他的评论中指出的那样,使用正确的文档类型应该不会导致IE中的填充问题。关于float渲染速度的问题,请参见下面的“速度”部分。您对position: absolute的担忧似乎是合理的,最好避免使用它--但除此之外,任何其他方法都不太可能有任何真正的兼容性问题。 易用性:我不确定您的意思是什么,因为您已经通过“这个特定的布局”限制了布局,并且易用性实际上更多是布局问题(而不是布局背后的结构)。

速度:我认为速度更多地受到headersidebararticle中所包含的内容(特别是如果文章链接到外部网站)的影响,而不是用于创建基本布局的结构和最小化的CSS。即使在慢速CPU上,浮动渲染稍微慢一些(我以前从未听说过这个问题,但是在慢速CPU上不是所有东西都会渲染得更慢吗?),大型图像、大量JavaScript等都会比CSS float声明更加拖慢页面的显示速度。

清晰的代码:您原始的fiddle非常干净。三个HTML项和四个最小的CSS位是您可以获得的最紧凑的。


为什么“position:absolute”是一个有效的兼容性问题?它在除了IE5/6的一些边缘情况之外,到处都得到了完全支持。 - David Hellsing
@David--根据原帖作者的评论,“position:absolute在触摸屏设备上效果不佳。”我不知道这是否属实,但如果是这样,并且他想要适应这些设备,那么他的担忧是合理的。 - ScottS

0
一个更好的解决方案是将内容加载到容器div中,而不是使用iframe和所有相关的问题(窗口/iframe有2个滚动条)。
为什么不使用JavaScript通过AJAX拉取页面内容。您还可以在当前页面加载后预加载下一个站点,以节省时间。
您的布局看起来不错,但也许可以将侧边栏/标题设置为滑出式,以便在页面上最大化目标站点 - stumble upon标题相当不显眼,这就是您应该模仿的。

-1

我会将页眉定位为绝对位置,将侧边栏和内容框向左浮动;

如果您使用lionbars.js或js.scrollpane来节省空间和美观度,侧边栏会更加锐利。


为什么要使用绝对定位?除非你想让标题栏覆盖在其他 div 上,否则你必须添加 padding。我认为这并没有回答 OP 的问题。 - Alexander Holsgrove

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接