知乎页面布局
知乎页面布局简洁明了,整体居中显示,采用上下结构,上面为顶部,提供导航、搜索、用户功能,下面为页面内容,内容左右分布,左边为主内容,主要是知乎上一些文章的摘要,右边为侧边栏,为用户提供一些服务选项和版权信息;卡片化是知乎页面上的一个特色,几乎所有的内容都是通过放在卡片中呈现给用户。
看看知乎首页布局:
知乎采用了flex布局,flex布局的特点是写更少的代码,让布局更简单(less code, simple layout)。
- html
<div id="app">
<div>
<header class="app-header">
<div class="app-header-inner">header</div>
</header>
<div class="sticky-holder"></div>
</div>
<main class="app-main">
<div class="app-content">
<div class="app-main-column">
<div class="story-container">
<div class="card story-item">知乎知乎知乎知乎</div>
<div class="card story-item">知乎知乎知乎知乎</div>
</div>
</div>
<div class="side-bar"></div>
</div>
</main>
</div>
知乎首页刚开始并没有让<header>
的position设置为fixed,而是让它正常占据文档流,当页面滚动的时候,通过js设置<header>
为固定定位,为了防止下面内容因为<header>
变为固定定位而上移,就通过一个class为sticky-holder
的<div>
标签占据着原来<header>
的位置,class为sticky-holder
的<div>
刚开始是不存在的,只有当滚动条滚动的时候才渲染。
- css
body{
margin: 0;
background: #f6f6f6;
}
.app-header{
width: 100%;
background: #fff;
}
.app-header-inner{
width: 1000px;
height: 52px;
padding: 0 16px;
background: #8bc34a;
margin: 0 auto;
}
.sticky-holder{
display: none;
}
.app-content{
display: flex;
align-items: flex-start; /*--让app-main-column和side-bar在副轴上上对齐--*/
width: 1000px;
padding: 0 16px;
margin: 10px auto;
background: #00bcd4;
}
.story-container{
width: 694px;
height: 1000px;
padding-bottom: 20px;
background: #ff9800;
}
.app-main-column{
margin-right: 10px;
}
.side-bar{
flex: 1; /*--没有为side-bar设置宽度,而是通过设置flex属性,让side-bar自适应剩余宽度--*/
height: 500px;
background: #f44336;
}
.card{ /*--卡片样式--*/
box-sizing: border-box;
overflow: hidden;
margin-bottom: 10px;
border-radius: 2px;
background: #fff;
box-shadow: 0 1px 3px rgba(26,26,26,.1);
}
.story-item{
padding: 16px 20px;
}
app-header-inner和app-content都是定宽1000px,居中。story-container宽度为694px,side-bar自适应剩余宽度。卡片的样式设置非常通用。
- js
(function(){
const appHeaderEle = document.querySelector('.app-header'),
stickyHolderEle = document.querySelector('.sticky-holder');
window.addEventListener('scroll', function(){
if(document.documentElement.scrollTop || document.body.scrollTop !== 0) {
appHeaderEle.style.position = 'fixed';
stickyHolderEle.style.display = 'block';
stickyHolderEle.style.position = 'relative';
stickyHolderEle.style.height = 52 + 'px';
}else{
appHeaderEle.style.position = 'relative';
stickyHolderEle.style.display = 'none';
}
})
})()
获取class为app-header和sticky-holder的DOM元素,监听浏览器的滚动事件,当滚动条距离文档顶部的距离不为0时设置class为app-header的标签为固定定位,同时设置class为sticky-holder的标签为相对定位,且高度与class为app-header的相同;当滚动条距离文档顶部的距离为0时,隐藏class为sticky-holder的标签,并设置class为app-header的标签为相对定位。
效果:
小结:
1、知乎当然不是用原生js去实现这种滚动的时候让页面顶部固定定位,其页面结构和样式也比上面demo中的复杂,在这只是简单分析并山寨了一下其页面布局,里面还是有许多值得借鉴的地方;
2、知乎首页通过动态渲染class为sticky-holder
的<div>
来解决顶部固定定位后会造成的内容上移问题;
3、卡片样式设置的非常通用,可以全局使用;