页面高度自适应布局方案(含IE下兼容方案)

happy young...大约 4 分钟技术前端开发

页面高度自适应布局方案(含IE下兼容方案)

自适应布局中,几个常用的技巧: flex布局,calc计算属性,以及jQuery动态调整布局。本文将通过一个常见的Sticky footer 布局为例提供示例和说明。

页面自适应目标:

页面整体布局为上中下,上为header,下为footer,高度固定;中间为main-container,高度填充整个页面,并能随着页面内容及浏览器的大小缩放。

页面整体布局如下:(页面效果: layout.htmlopen in new window )

<!DOCTYPE html>
<html>  
<head>  
<title>DEMO</title>  
<style>
    body {
        height: 100%;
        margin: 0px;
    }
    #app {
        width: 100%;
    }
    .header {
        background-color: aqua;
        height: 88px;
    }
    .main {
        background-color: bisque;
    }
    #content {
        height: 500px; 
        background-color: brown;  
    }
    .footer {
        background-color: blueviolet;
        height: 80px;
    }
</style>
<script>
    function changeContentHeight() {
        const slider = document.getElementById('slider');
        console.log(slider.value);
        document.getElementById("content").setAttribute("style", "height: " + slider.value + "px");
    }
</script>
</head>  
<body>  
    <div id="app">
        <div class="header"> header</div>
        <div class="main">
            <div id="content" >
                content height: 
                100
                <input id="slider" type="range" min="100" max="2000" step="1" onchange="changeContentHeight()"/> 
                2000
            </div>
        </div>
        <div class="footer"> footer</div>
    </div>
</body>  
</html>  

方案一: flex布局

实现示例:(页面效果: flex-layout.htmlopen in new window )

<style>
    body {
        height: 100%;
        margin: 0px;
    }
    #app {
        width: 100%;
        min-height: 100vh;
        /* height: 100vh;
        height: auto !important; */
        display: flex;
        flex-direction: column;
    }
    .header {
        background-color: aqua;
        height: 88px;
    }
    .main {
        background-color: bisque;
        min-height: 300px;
        flex: 1;
    }
    #content {
        height: 500px; 
        background-color: brown;  
    }
    .footer {
        background-color: blueviolet;
        height: 80px;
    }
</style>

实现说明: 首先对app设置min-height: 100vh 保证页面填充了整个页面。这里不能设置height:100vh。在页面内容大小超过一屏时会被溢出。 对外层元素设置display:flex,并制定子元素的排布方向 flex-direction: column, 然后对子元素中的main div设置flex:1,。这样可以通过main div的缩放来撑开整个页面。

方案二:calc计算属性

实现示例:(页面效果: calc-layout.htmlopen in new window )

<style>
    body {
        height: 100%;
        margin: 0px;
    }
    #app {
        width: 100%;
        min-height: 100vh;
        /* height: 100%; */
    }
    .header {
        background-color: aqua;
        height: 88px;
    }
    .main {
        background-color: bisque;
        min-height: calc(100vh - 168px);
    }
    #content {
        height: 500px; 
        background-color: brown;  
    }
    .footer {
        background-color: blueviolet;
        height: 80px;
    }
</style>

实现说明: 首先对app设置min-height: 100vh 保证页面填充了整个页面。 然后对main元素最小高度min-height通过calc计算属性赋值,以自适应页面高度。 该方案兼容性较强,但calc里的计算里,高度数值和其他组件有关联,开发存在耦合。在能使用flex布局的情况下,还是优先使用flex。

方案三:jQuery动态调整布局

对于部分通过css难以自适应或兼容的布局,可尝试通过js的方式监听窗口变化,动态设置页面样式。

<script>
    function changeContentHeight() {
        const slider = document.getElementById('slider');
        console.log(slider.value);
        document.getElementById("content").setAttribute("style", "height: " + slider.value + "px");
    }
    function selfAdapt() {
        let height = window.innerHeight - 168 + "px";
        document.getElementsByClassName("main")[0].setAttribute("style", "min-height: " + height);
    }
    window.addEventListener("resize", this.selfAdapt);
</script>

附:IE浏览器上min-height 和 flex:1 属性失效的问题分析及处理

背景说明:在IE浏览器上,对于flex布局下,无法做到父元素和子元素的同时缩放。要么父元素设定固定高度,子元素设置了flex:1做自动缩放; 要么子元素不做自动缩放,父元素随子元素布局缩放。当在父元素设置min-height时,在子元素设置flex:1时,效果和设置height保持一致。 尝试并验证了网上的各个方案,参考该方法可解决(https://www.cnblogs.com/SamWeb/p/9836497.html)。open in new window 实现示例:(页面效果: flex-compatible-layout.htmlopen in new window )

<!DOCTYPE html>
<html>  
<head>  
<title>flex-compatible-layout</title>  
<style>
    body {
        height: 100%;
        margin: 0px;
    }
    #wrapper {
        display: flex;
    }
    #app {
        min-height: 100vh;
        width: 100%;
        display: flex;
        flex-direction: column;
    }
    .header {
        background-color: aqua;
        height: 88px;
    }
    .main {
        background-color: bisque;
        min-height: 300px;
        flex-grow: 1;
    }
    #content {
        height: 500px; 
        background-color: brown;  
    }
    .footer {
        background-color: blueviolet;
        height: 80px;

    }
</style>
<script>
    function changeContentHeight() {
        const slider = document.getElementById('slider');
        console.log(slider.value);
        document.getElementById("content").setAttribute("style", "height: " + slider.value + "px");
    }
</script>
</head>  
<body>  
<div id="wrapper">
    <div id="app">
        <div class="header"> header</div>
        <div class="main">
            <div id="content" >
                content height: 
                100
                <input id="slider" type="range" min="100" max=2000" step="1" onchange="changeContentHeight()"/> 
                2000
            </div>
        </div>
        <div class="footer"> footer</div>
    </div>
</div>  
</body>  
</html>  

实现说明: 最外层添加wrapper div元素,嵌套一层flex布局。

app div元素的min-height需要设置为100vh,不能设置为100%。 设置为100%情况下,因为外层元素没有固定高度,是无法达到撑满整个视图的效果。

main div元素的缩放设置应使用flex-grow指定,如果使用flex:1, IE模式下会默认解析为flex: 1 1 0, 即flex-basis:0px。IE在该情况下会flex子元素main div将不会被其内容content div撑开;flex-basis: auto的情况下会正常撑开。

上次编辑于:
贡献者: Yangxi
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.14.6