<meta name="viewport" content="width=width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0">
viewport是严格的等于浏览器的窗口。viewport与跟viewport有关的meta标签的关系,详细建议读一读这篇文章:移动前端开发之viewport的深刻理解,viewport与布局的关系,能够看下这篇文章:在移动浏览器中使用viewport元标签控制布局css
之因此把flex布局放在第一位,是由于它在某些场景下确实很方便,好比垂直居中,再或者某些栅格化的适配,一旦用习惯以后,不天然就很依赖这种布局了。html
传统布局,是基于盒子模型,严重依赖于display属性,float属性,position属性。
而flex布局能够更加简洁的实现各类布局场景,且已经被全部浏览器兼容,在移动端上应用起来更加驾轻就熟。前端
flex属性内容比较少,只要理解应用起来很随意,学习详见阮一峰flexandroid
flex-direction / flex-wrap / flex-flow / justify-content / align-items / align-content
水平(主轴上)对齐方式:web
justify-content:flex-start | flex-end | center | space-between | space-around; flex-start(默认值):左对齐 flex-end:右对齐 center: 居中 space-between:两端对齐,子元素间隔相等 space-around:子元素两侧的间隔相等
十字交叉轴上对齐方式浏览器
align-items:flex-start | flex-end | center | baseline | stretch flex-start:上对齐 flex-end:下对齐 center:交叉轴对齐 baseline: 第一行文字的基线对齐 stretch(默认值):若是子元素未设置高度或设为auto,将占满整个容器
项目排列方向app
flex-direction:row | row-reverse | column | column-reverse; row(默认值):从左1/2/3/... row-reverse:从左../3/2/1 column:从上1/2/3/... column-reverse:从上../3/2/1
换行方式iphone
flex-wrap:nowrap(不换行) | wrap(向下换) | wrap-reverse(向上换)
flex-flowsvg
flex-direction和flex-wrap的简写 flex-flow:row nowrap
多根轴线的对齐方式布局
align-content:flex-start | flex-end | center | space-between | space-around | stretch; flex-start:上对齐。 flex-end:下对齐。 center:居中对齐。 space-between:两端对齐,间隔平均。 space-around:间隔相等。 stretch(默认值):占满。
order/flex-grow/flex-shrink/flex-basis/flex/align-self
1.order/ (num) order定义自身排列顺序。数值越小,越靠前,默认为0。-1/0/1/2/3/... 2.flex-grow/ (num) flex-grow 定义自身放大比例,默认为0不放大。例如:1/2/1=25%:50%:25% 3.flex-shrink/ 定义了空间不足时自身缩小比例,默认为1自动缩小,0不缩小。 4.flex-basis/ flex-basis定义最小空间,默认值为auto,即自身的原本大小。 5.flex属性/ flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。 6.align-self属性/ align-self定义自身对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,若是没有父元素,则等同于stretch。
//Webkit内核的浏览器,必须加上-webkit前缀。 .box{ display: -webkit-flex; /* Safari */ display: flex; }
rem是根据html的font-size大小来变化,正是基于这个出发,咱们能够在每个设备下根据设备的宽度设置对应的html字号,从而实现了自适应布局。
rem布局的本质是等比缩放,通常是基于宽度。
假设咱们将屏幕宽度平均分红100份,每一份的宽度用x表示,x = 屏幕宽度 / 100,若是将x做为单位,x前面的数值就表明屏幕宽度的百分比.
若是想要页面元素随着屏幕宽度等比变化,咱们须要上面的x单位,不幸的是css中并无这样的单位,幸运的是在css中有rem,经过rem这个桥梁,能够实现神奇的x
经过上面对rem的介绍,能够发现,若是子元素设置rem单位的属性,经过更改html元素的字体大小,就可让子元素实际大小发生变化,若是让html元素字体的大小,恒等于屏幕宽度的1/100,那1rem和1x就等价了
//designWidth:设计稿的实际宽度值,须要根据实际设置 //maxWidth:制做稿的最大宽度值,须要根据实际设置 //这段js的最后面有两个参数记得要设置,一个为设计稿实际宽度,一个为制做稿最大宽度,例如设计稿为750,最大宽度为750,则为(750,750) ;(function(designWidth, maxWidth) { var doc = document, win = window, docEl = doc.documentElement, remStyle = document.createElement("style"), tid; function refreshRem() { var width = docEl.getBoundingClientRect().width; maxWidth = maxWidth || 540; width>maxWidth && (width=maxWidth); var rem = width * 100 / designWidth; remStyle.innerHTML = 'html{font-size:' + rem + 'px;}'; } if (docEl.firstElementChild) { docEl.firstElementChild.appendChild(remStyle); } else { var wrap = doc.createElement("div"); wrap.appendChild(remStyle); doc.write(wrap.innerHTML); wrap = null; } //要等 wiewport 设置好后才能执行 refreshRem,否则 refreshRem 会执行2次; refreshRem(); 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 = "16px"; } else { doc.addEventListener("DOMContentLoaded", function(e) { doc.body.style.fontSize = "16px"; }, false); } })(750, 750);
html { font-size : 20px; } @media only screen and (min-width: 401px){ html { font-size: 25px !important; } } @media only screen and (min-width: 428px){ html { font-size: 26.75px !important; } } @media only screen and (min-width: 481px){ html { font-size: 30px !important; } } @media only screen and (min-width: 569px){ html { font-size: 35px !important; } } @media only screen and (min-width: 641px){ html { font-size: 40px !important; } }
上面的作的设置固然是不能全部设备全适配,可是用JS是能够实现全适配。具体用哪一个就要根据本身的实际工做场景去定了。
;(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'] = {}));
从上面的代码,主要是改变了dpx和document的font-size大小。大小为docEl.getBoundingClientRect().width / 10 + ‘px’;
移动端适配方案比较多,还有改变viewport暴力适配,和新出的属性vw,vh等等,我我的开发中经常使用的就是flex布局和js动态设置的rem布局,偶然也会加入vw,vh,百分比等等,灵活适配。 但愿对各位有些许的帮助。。。