CSS你必须知道的移动布局方案

本篇主要研究移动端布局方案和一些布局经验
写前端之前,必须引入一个reset.scss来重置浏览器默认样式,不然会因为脏样式,影响最终效果
下面我整理了几大必要项目

一、样式篇

1.清除默认样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
html,body{height:100%;}
html,body,h1,h2,h3,h4,h5,h6,div,dl,dt,dd,ul,ol,li,p,blockquote,pre,hr,figure,table,caption,th,td,form,fieldset,legend,input,button,textarea,menu{margin:0;padding:0;}
header,footer,section,article,aside,nav,hgroup,address,figure,figcaption,menu,details{display:block;}
table{border-collapse:collapse;border-spacing:0;}
caption,th{text-align:left;font-weight:normal;}
html,body,fieldset,img,iframe,abbr{border:0;}
i,cite,em,var,address,dfn{font-style:normal;}
[hidefocus],summary{outline:0;}
li{list-style:none;}
h1,h2,h3,h4,h5,h6,small{font-size:100%;}
sup,sub{font-size:83%;}
pre,code,kbd,samp{font-family:inherit;}
q:before,q:after{content:none;}
textarea{overflow:auto;resize:none;}
label,summary{cursor:default;}
a,button{cursor:pointer;}
h1,h2,h3,h4,h5,h6,em,strong,b{font-weight:bold;}
del,ins,u,s,a,a:hover{text-decoration:none;}
body,textarea,input,button,select,keygen,legend{font:12px/1.14 Microsoft YaHei,arial,\5b8b\4f53;color:#333;outline:0;}
body{background:#fff;}
a,a:hover{color:#333;}
*{box-sizing: border-box;}

2.去除input默认填充的背景颜色

1
2
3
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0px 1000px white inset;
}

3.清除input[type=number]的默认样式

1
2
3
4
5
6
7
8
input[type=number] {
-moz-appearance:textfield;
}
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}

4.清除移动端 a 标签等点击区域变色

1
2
3
*{
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}

5.清除移动端 input 样式

1
2
3
4
5
6
7
8
input{
border: none;
-moz-appearance:none;
-webkit-appearance : none ; /*解决ios上按钮的圆角问题*/
border-radius: 0; /*解决ios上输入框圆角问题*/
outline:medium; /*去掉鼠标点击的默认黄色边框*/
background-color: transparent;
}

6.避免ios滑动滚动条卡顿

1
2
3
*{
-webkit-overflow-scrolling : touch
}

二、midea媒体查询

orientation 方向
resolution 分辨率
dpr === dppx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/* 横屏 */
@media screen and (orientation:landscape){

}
/* 竖屏 */
@media screen and (orientation:portrait){

}
/* 窗口宽度<960,设计宽度=768 */
@media screen and (max-width:959px){

}
/* 窗口宽度<768,设计宽度=640 */
@media screen and (max-width:767px){

}
/* 窗口宽度<640,设计宽度=480 */
@media screen and (max-width:639px){

}
/* 窗口宽度<480,设计宽度=320 */
@media screen and (max-width:479px){

}
/* 设备像素比为2 */
/* 常用于1px边框,还应规定 3dppx 的情况 */
@media (min-resolution: 2dppx) {

}
/* windows UI 贴靠 */
@media screen and (-ms-view-state:snapped){

}
/* 打印 */
@media print{

}

三、强制横(竖)屏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.landscape-container {
position: absolute;
overflow: hidden;
}

// 竖屏
@media screen and (orientation: portrait) {
.landscape-container {
width: 100vh;
height: 100vw;
top: calc((100vh - 100vw) / 2);
left: calc((100vw - 100vh) / 2);
transform: rotate(90deg);
transform-origin: 50% 50%;
}
}

// 横屏
@media screen and (orientation: landscape) {
.landscape-container {
width: 100vw;
height: 100vh;
top: 0;
left: 0;
transform: none;
transform-origin: 50% 50%;
}
}

四、rem单位设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(function (doc, win) {
var docEl = doc.documentElement
var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'

function recalc() {
var designWidth = 750
var clientWidth = docEl.clientWidth
if (!clientWidth || clientWidth > designWidth) return
docEl.style.fontSize = (100 * clientWidth / designWidth) + 'px'
}

if (!doc.addEventListener) return
win.addEventListener(resizeEvt, recalc, false)
doc.addEventListener('DOMContentLoaded', recalc, false)
})(document, window)

五、垂直居中

未知父元素高度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.parentElement {
position: relative;
// 方法1 transform: translateY(-50%);
.childElement {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
// 方法2
.childElement {
position: absolute;
top: 0;
bottom: 0;
margin: auto;
}
}

已知父元素高度,仅有一个子元素

1
2
3
4
5
6
7
8
.parentElement {
height: xxx;
.childElement {
position: relative;
top: 50%;
transform: translateY(-50%);
}
}

六、图文居中

1
2
3
4
<div class="container">
<img src="../../public/images/bg1.jpg">
<span>安能摧眉折腰事权贵,使我不得开心颜</span>
</div>
1
2
3
4
5
6
.container{
padding:15px 0;
img{
vertical-align: middle;
}
}

七、文本行超出显示省略号

单行文字:

1
2
3
4
5
6
7
// 注意宽度是必须的
.article-container {
width: 500px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

多行文字:

1
2
3
4
5
6
7
8
.article-container {
display: -webkit-box;
word-break: break-all;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4; //需要显示的行数
overflow: hidden;
text-overflow: ellipsis;
}

JSArray-打印出所有数组方法

在实际应用中
JS数组方法使用很多
对他的熟悉否,都直接关系到代码质量

对数组的这些方法的使用是此篇文章的重点

在浏览器调试工具中新建一个数组对象,并打印它的隐形原型,即可得到关于Array对象底下的所有方法

console.log(new Array().proto)

一、万恶之源

创建一个长度为100,值都为1的数组

1
new Array(100).fill(1)

请创建一个长度为100,值为对应下标的数组

1
2
3
4
5
[...Array(100).keys()]

//其他方法:
Array(100).join(",").split(",").map(function(key,index){return index;})
Array(100).fill().map((v, i) => i)

为了能写出这样简洁的代码,我把Array对象地下的所有方法都打印了出来,用来学习。

二、数组方法

includes

查找数组中是否包含指定的值,此方法比较简单,只能用来匹配字符串或数组

1
2
3
4
5
var arrs = [1,2,3,4,5,6];
arrs.includes(10);
// false
arrs.includes(2);
// true

concat

创建并返回一个由多个数组拼接而成的数组,该方法不会改变原有数组

1
2
console.log([1,2].concat([3,4,5]))
// [1,2,3,4,5]

copyWithin

从数组的指定位置拷贝元素到数组的另一个指定位置中

1
array.copyWithin(target, start, end)

实例:

1
2
3
4
5
//复制数组的前面两个元素到第三和第四个位置上:
var fruits = ["Banana", "Orange", "Apple", "Mango", "Kiwi", "Papaya"];
fruits.copyWithin(2, 0, 2);

// Banana,Orange,Banana,Orange,Kiwi,Papaya

entries

返回一个数组的迭代对象,该对象包含数组的键值对 (key/value)。

1
2
3
4
5
6
7
8
9
10
var fruits = ["Banana", "Orange", "Apple", "Mango"];
for (let a of fruits.entries()) {
console.log(a)
}

//输出:
[0, "Banana"]
[1, "Orange"]
[2, "Apple"]
[3, "Mango"]

keys

从数组创建一个包含数组键的可迭代对象。

1
2
3
4
5
6
7
8
9
10
var fruits = ["Banana", "Orange", "Apple", "Mango"];
for (let a of fruits.keys()) {
console.log(a)
}

//输出:
0
1
2
3

values

从数组创建一个包含数组值的可迭代对象。

1
2
3
4
5
6
7
8
9
10
var fruits = ["Banana", "Orange", "Apple", "Mango"];
for (let a of fruits.values()) {
console.log(a)
}

//输出:
Banana
Orange
Apple
Mango

every

用于检测数组所有元素是否都符合指定条件,且不会改变原数组

every() 方法使用指定函数检测数组中的所有元素:
如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
如果所有元素都满足条件,则返回 true。

1
array.every(function(currentValue,index,arr), thisValue)

实例:

1
2
3
4
5
6
7
var ages = [32, 33, 16, 40];
function checkAdult(age) {
return age >= 18;
}
ages.every(checkAdult)

// false

fill

用于将一个固定值替换数组的元素

1
array.fill(value, start, end)

实例:

1
2
3
4
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.fill("Runoob", 2, 4);

// ["Banana", "Orange", "Runoob", "Runoob"]

filter

创建并返回一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素,该方法不会改变原数组。

1
array.filter(function(currentValue,index,arr), thisValue)

实例:

1
2
3
4
5
6
7
var ages = [32, 33, 12, 40];
function checkAdult(age) {
return age >= 18;
}
ages.filter(checkAdult);

// [32,33,40]

find

返回通过测试(函数内判断)的数组的第一个元素的值,且在找到符合条件的值后立刻停止执行。

1
2
3
4
5
6
7
var ages = [3, 10, 18, 20];
function checkAdult(age) {
return age >= 18;
}
console.log(ages.find(checkAdult))

// 18

flat

按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。即:扁平化嵌套数组,返回一个包含将数组与子数组中所有元素的新数组。

1
2
var newArray = arr.flat(depth)
//depth 可选 指定要提取嵌套数组的结构深度,默认值为 1。

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]

var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]

var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]

//使用 Infinity 作为深度,展开任意深度的嵌套数组
arr3.flat(Infinity);
// [1, 2, 3, 4, 5, 6]

flat() 方法会移除数组中的空项:

1
2
3
var arr4 = [1, 2, , 4, 5];
arr4.flat();
// [1, 2, 4, 5]

flatMap

暂时不知道

foreach

调用数组的每个元素,并将元素传递给回调函数。

1
array.forEach(function(currentValue, index, arr), thisValue)

实例:

1
2
3
4
5
6
7
8
9
let sum = 0;
var numbers = [65, 44, 12, 4];
function myFunction(item) {
sum += item;
}
numbers.forEach(myFunction)
console.log(sum)

// 125

indexOf

返回某个指定的字符串值在字符串中首次出现的位置。indexOf() 方法对大小写敏感!如果要检索的字符串值没有出现,则该方法返回 -1。

join

把数组中的所有元素放入一个字符串,且元素是通过指定的分隔符进行分隔的。

1
arrayObject.join(separator)

实例:

1
2
[1,2,3].join('-')
// "1-2-3"

lastIndexOf

返回一个指定的字符串值最后出现的位置

map
返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值,且不会改变原数组。

pop
删除并返回数组的最后一个元素。

push
向数组的末尾添加一个或多个元素,并返回新的长度。

reduce
接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。

1
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

实例:

1
2
3
4
5
var numbers = [15.5, 2.3, 1.1, 4.7];
function getSum(total, num) {
return total + Math.round(num);
}
numbers.reduce(getSum, 0)

实例:

1
2
3
// 24
reduceRight
和 reduce() 功能是一样的,不同的是 reduceRight() 从数组的末尾向前将数组中的数组项做累加。

reverse

用于颠倒数组中元素的顺序。

1
2
[1,2,3].reverse()
// [3,2,1]

shift

把数组的第一个元素从其中删除,并返回第一个元素的值。

slice

从已有的数组中返回选定的元素。

1
2
3
arrayObject.slice(start,end)
[1,2,3,4].slice(0,2)
// [1,2]

some

用于检测数组中的元素是否满足指定条件(函数提供)。如果有符合条件的元素,则数组剩下的不再执行。

1
array.some(function(currentValue,index,arr),thisValue)

实例:

1
2
3
4
5
6
7
var ages = [4, 12, 16, 20];
function checkAdult(age) {
return age >= 18
}
ages.some(checkAdult);

// true

sort

对数组的元素进行排序。

1
2
3
4
5
6
7
8
9
10
11
arrayObject.sort(sortby)
//sortby 可选 规定排序顺序。必须是函数。

[2,1,4,3,5].sort()
// [1,2,3,4,5]

function sortNumber(a,b) {
return a - b
}
[2,1,4,3,5].sort(sortNumber)
// [1,2,3,4,5]

splice

向/从数组中添加/删除项目,然后返回被删除的项目,且会改变原数组。

1
arrayObject.splice(index,howmany,item1,.....,itemX)

实例:

1
2
3
4
5
let arr = [1,2,3,4]
let res = arr.splice(0,1,'add')

// res = [1]
// arr = ["add", 2, 3, 4]

toString

把一个逻辑值转换为字符串,并返回结果。

unshift

向数组的开头添加一个或更多元素,并返回新的长度,且该方法会改变原数组。