如何使用 CSS 来定位固定的可变高度标题和可滚动的内容框?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6414384/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 00:49:00  来源:igfitidea点击:

How do I use CSS to position a fixed variable height header and a scrollable content box?

css

提问by David Roe

I'm trying to make a web page with a fixed header and a scrollable content area. This is trivial when the header has a known height but I'm struggling to find a solution for when the header is fluid.

我正在尝试制作一个带有固定标题和可滚动内容区域的网页。当标题具有已知高度时,这是微不足道的,但我正在努力寻找标题流动时的解决方案。

The layout I want is:

我想要的布局是:

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

where "head" is whatever height its content needs it to be and "content" has no minimum height but will reach a maximum height of the bottom of the viewport before becoming scrollable.

其中“head”是其内容需要的任何高度,而“content”没有最小高度,但会在可滚动之前达到视口底部的最大高度。

Is this possible these days in pure CSS? I'm targeting IE8+.

这些天在纯 CSS 中这可能吗?我的目标是 IE8+。

To clarify what I want, here is what I would do if I knew the height of the header:

为了澄清我想要什么,如果我知道标题的高度,我会这样做

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

采纳答案by Shauna

Assuming by "fixed" you mean position:fixed, I don't think it's possible in pure CSS, as position:fixedtakes the element out of the document flow.

假设您的意思是“固定” position:fixed,我认为在纯 CSS 中是不可能的,因为position:fixed将元素从文档流中取出。

However, it should just take a line or two of JavaScript to get what you want. Something like this (untested, only for example purposes, will need syntax tweaked to actually work):

然而,它应该只需要一两行 JavaScript 就可以得到你想要的东西。像这样的东西(未经测试,仅用于示例目的,需要调整语法才能实际工作):

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

Something like that should get you the rendered height of the fixed <div>and set the content <div>'s margin accordingly. You'll also need to explicitly set a background color on the fixed <div>, otherwise the content will appear to bleed into the fixed one when scrolling.

像这样的东西应该让你得到固定的渲染高度<div>并相应地设置内容<div>的边距。您还需要在 fixed 上显式设置背景颜色<div>,否则滚动时内容会渗入到 fixed 中。

回答by Eric

Here'sa solution, but it's a cheat. Basically, you have a duplicate header element, to push down the content, under the fixed position one:

这是一个解决方案,但这是一个骗局。基本上,您有一个重复的标题元素,用于将内容下推,位于固定位置之一:

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

回答by geca

I did a combination of both the accepted and Eric's answer. An empty div is used to push the content bellow "head". The width of this div is set by jQuery when window.onresize is fired:

我结合了公认的答案和埃里克的答案。一个空的 div 用于将内容推送到“头部”下方。当 window.onresize 被触发时,这个 div 的宽度由 jQuery 设置:

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

See this jsFiddlefor more info.

有关更多信息,请参阅此 jsFiddle

回答by Keith

This javascript will take the variable height of a fixed header and set the top margin of the content to flow underneath. Just call page load.

此 javascript 将采用固定标题的可变高度,并将内容的上边距设置为在下方流动。只需调用页面加载。

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

回答by Ravendarksky

Here is a full code example of Shauna's solution above for the lazy/confused/people who can't get this working.

这是上面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>