任务:
------------恢复内容开始------------
任务:使用rem+scss 淘宝flexible布局 vw/vh布局三种方式实现上下固定,中间自适应可滚动的布局
实现中关键点:
1 上下固定的布局使用position:fixed 来实现
2 中间自适应的部分需要使用 position: absolute 来实现,并且添加 overflow: auto
3 中间部分要想撑开,需要添加div标签并设置高度
4 scss使用的时候,需要使用如下形式。然后scss中可以使用$生命变量,进行嵌套等操作
<style lang="scss"> @import "style.css"; //注意是.css不是.scss </style>
5 淘宝的flexible布局不是常见的flex布局,它的操作是需要引入一个flexible.js文件,然后再直接使用rem单位来进行适配操作,这里rem是clientwidth的1/10
6 移动端元素的大小设置一般基于宽度,不是高度的原因:是因为同样宽度的手机,可能有不同的高度,虽然cilentHeight获取到的还是设备的实际高度,但是
我们的目的是在同样宽度的同时更多的加载内容,而不是内容等比的缩放占满,所以以宽度为准
7 dpr是设备像素比,等于物理像素/设备独立像素,即1px对应多少物理像素
三种方法比较总结:
具体代码源码如下:
rem+scss:
HTML代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title>rem</title> <script> function init(){ var viewWidth = document.documentElement.getBoundingClientRect().width || window.innerWidth; document.documentElement.style.fontSize = viewWidth / 750 * 10 + 'px'; } window.addEventListener('resize', init); </script> <style lang="scss"> @import "style.css"; </style> </head> <body> <div class="wrap"> <div class="header">header</div> <div class="main">main <div class="content"></div> </div> <div class="footer">footer</div> </div> </body> </html>
scss代码:
$bgColor:#000;
$fontSize:3rem;
$barHeight:5rem;
$contentHeight:200rem;
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.wrap{
font-size:$fontSize;
.header {
background-color: $bgColor;
width: 100%;
height: $barHeight;
line-height: $barHeight;
text-align: center;
color:#fff;
position: fixed;
left: 0;
top: 0;
}
.footer {
width: 100%;
height: $barHeight;
line-height: $barHeight;
position: fixed;
text-align: center;
color:#fff;
left: 0;
bottom: 0;
background-color: $bgColor;
}
.main {
width: 100%;
position: absolute;
left: 0;
top:$barHeight;
bottom:$barHeight;
overflow: auto;
}
.content{
height:$contentHeight;
}
}
flexible布局:
HTML代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> <title>flexible</title> <script src="flexible.js"></script> <style> * { margin: 0; padding: 0; box-sizing: border-box; } .wrap { font-size: .5rem; } .wrap .header { background-color: #000; width: 100%; height: 1rem; line-height: 1rem; text-align: center; color: #fff; position: fixed; left: 0; top: 0; } .wrap .footer { width: 100%; height: 1rem; line-height: 1rem; position: fixed; text-align: center; color: #fff; left: 0; bottom: 0; background-color: #000; } .wrap .main { width: 100%; position: absolute; left: 0; top: 1rem; bottom: 1rem; overflow: auto; } .wrap .content { height: 50rem; } </style> </head> <body> <div class="wrap"> <div class="header">header</div> <div class="main">main <div class="content"></div> </div> <div class="footer">footer</div> </div> </body> </html>
flexbile.js代码:这部分知网上拉去的,最开始拉取的版本是简洁版,这个应该是原版。核心就是针对设备像素比dpr进行IOS上的设置,iOS下,对于2和3的屏,分别用2倍和3倍的方案,其余的用1倍方案
没有针对安卓做配置,根元素字体大小为clienWdith的十分之一
(function(win, lib) { var doc = win.document; var docEl = doc.documentElement; var metaEl = doc.querySelector('meta[name="viewport"]'); var flexibleEl = doc.querySelector('meta[name="flexible"]'); var dpr = 0; var scale = 0; var tid; var flexible = lib.flexible || (lib.flexible = {}); if (metaEl) { console.warn('将根据已有的meta标签来设置缩放比例'); var match = metaEl.getAttribute('content').match(/initial\-scale=([\d\.]+)/); if (match) { scale = parseFloat(match[1]); dpr = parseInt(1 / scale); } } else if (flexibleEl) { var content = flexibleEl.getAttribute('content'); if (content) { var initialDpr = content.match(/initial\-dpr=([\d\.]+)/); var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/); if (initialDpr) { dpr = parseFloat(initialDpr[1]); scale = parseFloat((1 / dpr).toFixed(2)); } if (maximumDpr) { dpr = parseFloat(maximumDpr[1]); scale = parseFloat((1 / dpr).toFixed(2)); } } } if (!dpr && !scale) { var isAndroid = win.navigator.appVersion.match(/android/gi); var isIPhone = win.navigator.appVersion.match(/iphone/gi); var devicePixelRatio = win.devicePixelRatio; if (isIPhone) { // iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案 if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) { dpr = 3; } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){ dpr = 2; } else { dpr = 1; } } else { // 其他设备下,仍旧使用1倍的方案 dpr = 1; } scale = 1 / dpr; } docEl.setAttribute('data-dpr', dpr); if (!metaEl) { metaEl = doc.createElement('meta'); metaEl.setAttribute('name', 'viewport'); metaEl.setAttribute('content', 'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no'); if (docEl.firstElementChild) { docEl.firstElementChild.appendChild(metaEl); } else { var wrap = doc.createElement('div'); wrap.appendChild(metaEl); doc.write(wrap.innerHTML); } } function refreshRem(){ var width = docEl.getBoundingClientRect().width; if (width / dpr > 540) { width = 540 * dpr; } var rem = width / 10; docEl.style.fontSize = rem + 'px'; flexible.rem = win.rem = rem; } win.addEventListener('resize', function() { clearTimeout(tid); tid = setTimeout(refreshRem, 300); }, false); win.addEventListener('pageshow', function(e) { if (e.persisted) { clearTimeout(tid); tid = setTimeout(refreshRem, 300); } }, false); if (doc.readyState === 'complete') { doc.body.style.fontSize = 12 * dpr + 'px'; } else { doc.addEventListener('DOMContentLoaded', function(e) { doc.body.style.fontSize = 12 * dpr + 'px'; }, false); } refreshRem(); flexible.dpr = win.dpr = dpr; flexible.refreshRem = refreshRem; flexible.rem2px = function(d) { var val = parseFloat(d) * this.rem; if (typeof d === 'string' && d.match(/rem$/)) { val += 'px'; } return val; } flexible.px2rem = function(d) { var val = parseFloat(d) / this.rem; if (typeof d === 'string' && d.match(/px$/)) { val += 'rem'; } return val; } })(window, window['lib'] || (window['lib'] = {}));
vw/vh布局:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title>vwvh</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } .header { background-color: #000000; width: 100vw; height: 6vh; text-align: center; line-height:6vh; color:#fff; position: fixed; left: 0; top: 0; } .footer { width:100vw; height: 6vh; position: fixed; text-align: center; line-height:6vh; color:#fff; left: 0; bottom: 0; background-color: #000000; } .main { position: absolute; top: 6vh; width:100vw; left: 0; bottom:6vh; overflow: auto; } .content{ height:200vh; } </style> </head> <body> <div class="wrap"> <div class="header">header</div> <div class="main">main <div class="content"></div> </div> <div class="footer">footer</div> </div> </body> </html>
------------恢复内容结束------------