Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

对“粘连”footer布局的思考和总结_20161227 #33

Open
zhiqiang21 opened this issue Dec 27, 2016 · 1 comment
Open

对“粘连”footer布局的思考和总结_20161227 #33

zhiqiang21 opened this issue Dec 27, 2016 · 1 comment

Comments

@zhiqiang21
Copy link
Owner

zhiqiang21 commented Dec 27, 2016

经典的"粘连"footer布局

参考文章链接在文章末尾,简单的语言总结如下:

经典的“粘连”footer布局就是。我们有一块内容<main>。当<main>的高度足够长的时候,紧跟在<main>后面的元素<footer>会跟在<main>元素的后面。当<main>元素比较短的时候(比如小于屏幕的高度),我们期望这个<footer>元素能够“粘连”在屏幕的底部。如下图所示:

main足够长时

main比较短时

上面布局的实现方法在参考文章中已经有提到。下面主要探讨我们项目中遇到的情况:

我们需要实现的布局就是 按钮“提交”所在的区域能够自由伸缩。当屏幕较低时,最就是“提交”按钮和表单所在的区域接触或者有一定的间隙。 示例图就是下面的:

当屏幕足够高的时候

屏幕足够高的时候

当屏幕比较低的时候

屏幕比较低的时候

上面的布局在移动端需要考虑以下因素对布局的影响:

  1. 安卓上键盘弹起会对absolutefixed产生影响;
  2. 我们的绝对定位的元素是使用的bottom相对于屏幕的底部定位;

为了解决以上的两个问题的解决方案:

  1. 使用正常文档流的元素包裹绝对定位的元素;
  2. 绝对定位元素的父级元素应该有一个min-height防止,父级元素太低时,绝对定位元素“溢出”父级元素;(min-height >= 绝对定位元素 + bottom);

根据“粘连”footer布局的思想,结合弹性盒布局。我们需要的这种布局可以有两种方式,分别介绍如下:

1.使用vh单位

先来了解下vhvw这两个单位。

  1. vh相对于视口的高度。视口被均分为100单位的vh。
  2. vw相对于视口的宽度。视口被均分为100单位的vw。

上面两个单位通俗的意义就是在css中获取当前屏幕的高度和宽度(不通过js计算)。

示例代码如下:

<body>
    <div class="item1"></div>
    <div class="item2"></div>
    <div class="item3">
        <div class="btn-item">你好</div>
    </div>
</body>

css代码如下:

* {
    margin: 0;
    padding: 0;
}

body {
    /*主要就是这里获取视窗口的高度*/
    min-height: 100vh;
    display: -webkit-box;
    display: -webkit-flex;
    display: -moz-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-flex-flow: column;
    -ms-flex-flow: column;
    flex-flow: column;
}

.item1 {
    height: 100px;
    background-color: #ddd
}

.item2 {
    height: 300px;
    background-color: #fea0a0
}

.item3 {
    /*防止绝对定位的元素溢出父级元素*/
    min-height: 30px !important;
    border: 1px solid #481eff;
    position: relative;
    height: 0;
    -webkit-box-flex: 1;
    -webkit-flex: 1;
    -moz-box-flex: 1;
    -ms-flex: 1;
    flex: 1;
    -webkit-flex-basis: 0;
    -ms-flex-preferred-size: 0;
    flex-basis: 0;
    max-height: 100%;
}

.btn-item {
    position: absolute;
    bottom: 10px;
    border: 1px solid #000;
}

以上就是完全使用css来实现我们项目中布局的方法,但是这个方法有一个很明显的缺点就是vh单位的兼容性问题。兼容列表如下:

因为兼容性问题,纯css的方法在我们的项目中使用还是不现实。但是我们想下问题的本质:在使用弹性盒的基础上,我们唯一需要做的就是知道弹性盒元素的高度(就是我们项目中屏幕的高度)。

2.js简单计算满足兼容问题。

就是在dom树渲染完成以后给body设置高度未屏幕的高度。为了避免不必要的“重绘”或者是“重排”在head标签中添加如下js。

var callback = function(){
    document.body.style.height=window.screen.height+'px';
};

//是否是页面加载触发绑定了事件
if ( document.readyState === "complete" || (document.readyState !== "loading" && !document.documentElement.doScroll) ) {
    callback();
} else {
    //DOMContentLoaded 仅支持ie9+ 和移动端  <=ie8 使用 onreadystatechange  可以监听dom是否加载完毕
    document.addEventListener("DOMContentLoaded", callback);
}

使用 jQuery 或者是 Zepto 的方法,仍然在head标签中添加如下js。

$(function(){
    $('body').height($(window).height());
})

所以在我们的项目中结合弹性盒布局和添加简单的动态js计算屏幕的高度。就可以完美实现我们项目中需要的布局。

body {
    /*使用js动态计算就可以不使用vh单位*/
    /*min-height: 100vh;*/
    display: flex;
}

参考文章:

因为是一个

cssstickyfooter.com
ryanfait.com/sticky-footer
css-tricks.com/snippets/css/sticky-footer
pixelsvsbytes.com/blog/2011/09/sticky-css-footers-the-flexible-way
mystrd.at/modern-clean-css-sticky-footer

@zhiqiang21
Copy link
Owner Author

啊呀呀,每次读超过1000字的英文都感觉自己是文盲

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant