2011-06-20 3 views
43

固定ヘッダーとスクロール可能なコンテンツ領域を持つWebページを作成しようとしています。ヘッダーが既知の高さを持っている場合はこれは簡単ですが、ヘッダーが流動しているときの解決策を見つけるのには苦労しています。CSSを使用して固定可変高さヘッダーとスクロール可能なコンテンツボックスを配置するにはどうすればよいですか?

私が望むレイアウトは次のとおりです。

「頭」は、それはそれがために、コンテンツのニーズ何でも高さであり、「コンテンツ」とは何の最小の高さを持っていませんが、ビューポートの一番下の最大の高さに到達します
-------------- 
head 
-------------- 
content 
-------------- 

スクロール可能になる前に

これは最近の純粋なCSSで可能でしょうか?私はIE8 +をターゲットにしています。私が欲しいものを明確にするために

here is what I would do if I knew the height of the headerposition:fixedは、文書フローのうちの要素を取るとして、あなたがposition:fixedを意味する「固定」で仮定し

<!DOCTYPE html> 
<html> 
    <head> 
     <style type="text/css"> 

body { 
    margin: 0; 
} 

#head { 
    background: yellow; 
    height: 20px; /* I can't rely on knowing this. */ 
} 

#content { 
    background: red; 
    position: absolute; 
    top: 20px; /* here also */ 
    bottom: 0; 
    width: 100%; 
    overflow: auto; 
} 

     </style> 
    </head> 
    <body> 
     <div id="head">some variable height content</div> 
     <div id="content"> 
      scrollable content<br/> 
      scrollable content<br/> 
      scrollable content<br/> 
      scrollable content<br/> 
      scrollable content<br/> 
      scrollable content<br/> 
      scrollable content<br/> 
      scrollable content<br/> 
      scrollable content<br/> 
      scrollable content<br/> 
      scrollable content<br/> 
      scrollable content<br/> 
      scrollable content<br/> 
      scrollable content<br/> 
      scrollable content<br/> 
     </div> 
    </body> 
</html> 
+1

スクロールバーをコンテンツの横に、またはページ全体の高さに沿ってしますか? – Eric

+1

ヘッダーが「固定」の場合、どのように高さが液体ですか? – Eric

+1

スクロールバーは、コンテンツの横にあるのが理想的です。私が固定したと言ったとき、私は定位置にいた。メインコンテンツでスクロールしません。 –

答えて

23

、私は、それは純粋なCSSで可能だとは思いません。

ただし、必要なものを取得するには、JavaScriptを1行または2行にするだけです。このような何か(実際に動作テストされていないが、例のみの目的のために、構文はに微調整が必​​要になります):そのような

var height = document.getElementById("head").offsetHeight; 
document.getElementById("content").style.marginTop = height + 'px'; 

何かがあなたに固定<div>の描画時の高さを取得し、それに応じてコンテンツ<div>のマージンを設定する必要があります。また、固定の背景色を明示的に設定する必要があります。そうしないと、スクロール時にコンテンツが固定されたように見えることがあります。

+5

をターゲットにしていますページがサイズ変更された後に再計算することを忘れないでください – Eric

+0

ヘッダーを設計して、幅が変更されたときに再フローしないようにして、サイズ変更について心配する必要はありません。 –

+0

javascriptを使用することができれば、フリーゼパンの初期高さや後続の容器の余白を指定する必要がなくなるので、これは素晴らしい答えです。私はちょうどpageLoad()でそれを押し込み、ページリサイズのイベントリスナーを追加します。 – Ravendarksky

20

Here's解決策ですが、それはカンニングです。基本的には、固定位置1の下で、コンテンツを押し下げ、重複したヘッダ要素を持っている:

<div class="outer"> 
    <div class="header">Header content goes here</div> 
    <div class="header-push">Header content goes here</div> 
    <div class="content"> 
     ... 
    </div> 
</div> 
+0

メインコードの@Ericのおかげで、コンテンツのヘッダーを動的にするためにちょっと微調整しました。私はjQueryを使って、どれほど大きくなってもヘッダーの高さにコンテンツをスティックするようにしました。 http://jsfiddle.net/K7h9k/5/ –

+1

それは素晴らしい(ちょっとハッキーな)解決策ですが、質問を簡単に答えるための要件を簡素化しました。私は実際には下に2つの独立した列が欲しいので、全ページをスクロールしてそれを行うことはできません。たぶんJavascriptが唯一の方法です。私は新しいテーブルレイアウトのもののいくつかがトリックを行うことを望んでいたが、私はそれを動作させることができなかった。 –

+2

私は数時間、純粋なCSSソリューションを思いついてきましたが、実際には不可能だと結論づけました。 96年に発明された標準の驚異。 –

2

このJavaScriptは、下に流れるように固定ヘッダの可変の高さを取り、コンテンツの上マージンを設定します。ちょうどページロードを呼び出す。

<script type="text/javascript"> 
    function AdjustHeight() { 
     var height = document.getElementById("fixedheader").offsetHeight; 
     document.getElementById("content").style.marginTop = height + 'px'; 
    }  
</script> 
2

これは、この作業を行うことができない怠惰な/混乱した/人々のための上記Shaunaのソリューションの完全なコード例です。

<html> 
<head> 

<style> 
#FreezePaneHeader { 
    position: fixed; top:0; left: 0; width: 100%;background-color: gray; 
} 

#FreezePaneBody { 
    margin-top: 30px; 
} 
</style> 

<script type="text/javascript">   
     function resizeFreezePane() 
     { 
      var height = document.getElementById("FreezePaneHeader").offsetHeight; 
      document.getElementById("FreezePaneBody").style.marginTop = height + 'px'; 
     } 

     //Resizes content to allow static header with dynamic height on postbacks 
     function pageLoad() { 
      resizeFreezePane(); 
     } 

     var addEvent = function (elem, type, eventHandle) { 
      if (elem == null || typeof (elem) == 'undefined') return; 
      if (elem.addEventListener) { 
       elem.addEventListener(type, eventHandle, false); 
      } else if (elem.attachEvent) { 
       elem.attachEvent("on" + type, eventHandle); 
      } else { 
       elem["on" + type] = eventHandle; 
      } 
     }; 

     //also when page is resized. 
     addEvent(window, "resize", resizeFreezePane); 

    function GenerateLorem(ele){ 
     var x = document.getElementById(ele); 
     x.innerHTML = x.innerHTML + "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur pretium euismod leoquis convallis. In ornare suscipit massa eu commodo. Pellentesque vel nibh volutpat, commodo libero et, 

porta tellus. Duis eu fringilla arcu. Etiam imperdiet lectus diam, dignissim viverra dui hendrerit id. Fusce condimentum bibendum tincidunt. Aenean fringilla felis elit, et dapibus ante tempus at. Phasellus quis dolor odio.</p>"; 
     resizeFreezePane(); 
     } 
    </script> 
</head> 

<body> 
<div id="FreezePaneHeader">Frozen Page Header</div> 
<div id="FreezePaneBody"> 
<button id="ButtonAddText" onclick="GenerateLorem('FreezePaneHeader'); return false;">Add more header text</button> 
<button id="ButtonAddText" onclick="GenerateLorem('FreezePaneBody'); return false;">Add more body text</button> 
<p id="PageContents"></p> 
</div> 
</body> 

</html> 
6

私は受け入れられた答えとエリックの答えの両方を行いました。空のdivを使用して、コンテンツ「head」をプッシュします。 window.onresizeが発射されるときに、このdiv要素の幅は、jQueryのによって設定されます。

function resizeHeader() { 
    $(".header-push").height($(".header").height()); 
} 
$(document).ready(resizeHeader); 
$(window).resize(resizeHeader); 

は、詳細はthis jsFiddleを参照してください。

+2

奇妙なことに、私はこのアプローチが一番好きです。重複したヘッダーは必要ありませんが(どちらも私には当てはまらない空のdivが必要です)、ヘッダーについて何かを知る必要はありません。それはずっと短くなっています。 – Boom

+1

トリガが多すぎるのを避けるために、ウィンドウのサイズ変更中に少し遅延を追加すると便利です - 私は250ミリ秒を使い、十分に良いと思われます:http://stackoverflow.com/questions/2854407/javascript-jquery-window-resize-how-to -fire-after-the-resize-is-completed – billynoah

+0

純粋なCSSソリューションが見つからないことが多くの時間にわかりました。これは間違いなくトリックですが、JSを無効にしている人はどうでしょうか(私はおそらくおそらくかなり悪いブラウジング体験をしていると思いますが)。 – edwardmp

関連する問題