Как использовать CSS для размещения фиксированного заголовка переменной высоты и прокручиваемого содержимого?

Я пытаюсь создать веб-страницу с фиксированным заголовком и прокручиваемой областью содержимого. Это тривиально, когда заголовок имеет известную высоту, но я изо всех сил пытаюсь найти решение, когда заголовок жидкости.

Макет, который я хочу:

--------------
head
--------------
content
--------------

где "голова" - это какая-то высота, в которой ее содержимое нуждается, и "контент" не имеет минимальной высоты, но достигнет максимальной высоты дна окна просмотра, прежде чем станет прокручиваемым.

Возможно ли это в наши дни в чистом CSS? Я нацеливаюсь на IE8+.

Чтобы уточнить, что я хочу, вот что я сделал бы, если бы знал высоту заголовка:

<!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

Предполагая, что "фиксированный" означает "t20 > , я не думаю, что это возможно в чистом CSS, поскольку position:fixed выводит элемент из потока документов.

Однако для получения того, что вы хотите, нужно просто взять строку или два JavaScript. Что-то вроде этого (непроверенный, только для целей, потребуется синтаксис, который можно настроить, чтобы на самом деле работать):

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

Что-то вроде этого должно получить выведенную высоту фиксированного <div> и соответственно установить поле содержимого <div>. Вам также нужно будет явно задать цвет фона на фиксированном <div>, иначе при прокрутке содержимое будет заливаться в фиксированное.

Ответ 2

Вот решение, но это чит. В принципе, у вас есть дублированный элемент заголовка, чтобы нажимать содержимое, в фиксированном положении:

<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>

Ответ 3

Я сделал комбинацию как принятого, так и Эрика. Пустой div используется для подталкивания содержимого ниже "head". Ширина этого div устанавливается jQuery при запуске window.onresize:

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

Подробнее см. этот jsFiddle.

Ответ 4

Этот javascript будет принимать переменную высоту фиксированного заголовка и устанавливать верхний край содержимого для потока под ним. Просто загрузите страницу.

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

Ответ 5

Вот полный пример решения 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>