vue.config.js

设置@符号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
'use strict'

const path = require('path')
function resolve(dir) {
return path.join(__dirname, dir)
}

module.exports = {
//设置@的作用
configureWebpack: {
resolve: {
alias: {
'@': resolve('src')//在项目中使用@,会指定先src的目录下面
}
}
},
}

设置代理

将任何未知的请求代理到指定服务器

1
2
3
4
5
6
module.exports = {
devServer: {
// 将所有未知的请求代理到下面指定的服务器上
proxy: 'http://localhost:4000'
}
}

将不同路径代理到不同服务器中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module.exports = {
devServer: {
proxy: {
// 将api开头的路径的请求代理到url中
'/api': {
target: '<url>',
ws: true,
changeOrigin: true
},
// 将foo开头的路径的请求代理到other_url中
'/foo': {
target: '<other_url>'
}
}
}
}

关闭代码检查

1
2
3
module.exports = {
lintOnSave: false,
}

vue配置文件模板

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
'use strict'

const path = require('path')
function resolve(dir) {
return path.join(__dirname, dir)
}

module.exports = {
//关闭代码检查
lintOnSave: false,

//设置代理
devServer: {
proxy: {
//设置为0.0.0.0之后,同一局域网内可以直接访问项目
host: '0.0.0.0',
//端口号
port: 80,
//是否自动打开浏览器
open: true,
//将路径请求为api开头的请求代理到target指定的服务器中
'/api':{
target:'http://localhost:8080'
}
}
},
//设置@的作用
configureWebpack: {
resolve: {
alias: {
'@': resolve('src')//在项目中使用@,会指定先src的目录下面
}
}
},
}

vuex

vuex原理图

vuex的原理图,在组件调用store的dispatch方法后,执行了actions中的方法(action中可以调用Ajax请求),在actions中commit调用mutations后,在mutation和actions中都可以修改store中的方法

image-20220517145549307

当在actions中不需要进行什么操作(直接将接收的值传入mutations中的时候)可以在组件中不需要调用actions,直接在组件中直接commit调用mutations,可以直接越过actions

image-20220517145909111

vuex的基本使用

创建store

  • 在src下面创建一个文件夹store,创建一个文件index.js,写入以下内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    //引入vue
    import Vue from 'vue'
    //引入vuex
    import Vuex from 'vuex'

    //在vue中使用vuex
    Vue.use(Vuex)

    export default new Vuex.Store({
    //用于响应组件中的动作
    actions: {},
    //用于操作数据(state)
    mutations: {},
    //用于存储数据
    state: {},
    //用于将state中的数据进行加工,比如state中sum+1
    getters: {},
    //用于存放vuex的各个模块,进行模块化管理时使用
    modules: {}
    })
  • 在src下面的main.js中引入上面创建的store文件

    1
    2
    3
    4
    5
    6
    7
    //在main.js文件中引入store
    import store from './store'
    new Vue({
    ........
    //在vue实例中引入store
    store,
    }).$mount('#app')

vuex的基本使用

  • 创建vuex和在main.js中引入(上面创建store中有具体步骤)

    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
    import Vue from 'vue'
    import Vuex from 'vuex'

    Vue.use(Vuex)

    export default new Vuex.Store({
    actions: {
    jia(context, value) {
    context.commit('JIA', value)
    }
    },
    mutations: {
    JIA(state, value) {
    state.sum += value
    }
    },
    state: {
    sum: 0,
    },
    getters: {
    bigSum(state){
    return state.sum + 10
    }
    },
    modules: {}
    })
  • 在组件中操作store。使用this.$store.dispatch(actions中的方法或mutations中的方法,传入的值)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <template>
    <div>
    <div @click="storeJia">操作store</div>
    <!-- 获取state中的数据 -->
    <div style="font-size: 20px;">{{$store.state.sum}}</div>
    <!-- 获取getters中的数据 -->
    <div style="font-size: 20px;">{{$store.getters.bigSum}}</div>
    </div>
    </template>

    <script>
    export default {
    methods: {
    storeJia() {
    this.$store.dispatch('jia', 2)
    }
    },
    }
    </script>

  • 在组件中访问store / getters

    • template中使用插值语法{{}}访问:
      • 访问store:{{$store.state.state中的变量}}
      • 访问getters:{{$store.getters.getters中的变量}}

vuex的进阶使用—mapState

在vue组件中使用store中的数据时,总是要使用$store.state.state中的变量访问变量,所以vuex提供了mapState结合vue提供的computen计算属性一起使用能够快捷的访问state中的属性

  • 创建vuex和在main.js中引入(上面创建store中有具体步骤)。这里只使用state中的数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import Vue from 'vue'
    import Vuex from 'vuex'

    Vue.use(Vuex)

    export default new Vuex.Store({
    actions: {},
    mutations: {},
    state: {
    sum: 0,
    username: '张三'
    },
    getters: {},
    modules: {}
    })
  • 在组件中使用mapState:在计算属性computed中使用

    • 使用对象的方式一个一个引入 / 使用数组的方式直接引入
    • 使用方式一:...mapState({sum:'state中的变量',username:'state中的变量'})
    • 使用方式而:...mapState([state中的变量1 , state中的变量2 , ......])
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <template>
    <div>
    <div style="font-size: 20px;">{{ username1 }}</div>
    <div style="font-size: 20px;">{{ sum1 }}</div>
    <div style="font-size: 20px;">{{ username }}</div>
    <div style="font-size: 20px;">{{ sum }}</div>
    </div>
    </template>

    <script>
    // 引入vuex中的mapState
    import {mapState} from 'vuex'

    export default {
    computed: {
    //使用对象接收store中的数据,可以重新赋变量名,可以和store中的数据一致
    ...mapState({sum1: 'sum', username1: 'username'}),
    //使用数组接收store中的数据,变量名为store中的变量名
    ...mapState(['sum', 'username']),
    },
    }
    </script>

vuex的进阶使用—mapGetters

在vue组件中使用getters中的数据时,总是要使用$store.getters.getters中的变量访问变量,所以vuex提供了mapGerrers结合vue提供的computen计算属性一起使用能够快捷的访问getters中的属性

  • 创建vuex和在main.js中引入(上面创建store中有具体步骤)。这里只使用getters中的数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    import Vue from 'vue'
    import Vuex from 'vuex'

    Vue.use(Vuex)

    export default new Vuex.Store({
    actions: {},
    mutations: {},
    state: {
    sum: 0,
    username: '张三'
    },
    getters: {
    bigSum(state) {
    return state.sum + 10
    },
    newUsername(state){
    return state.username+"是好人"
    }
    },
    modules: {}
    })
  • 在组件中使用mapGetters:在计算属性computed中使用

    • 使用对象的方式一个一个引入 / 使用数组的方式直接引入
    • 使用方式一:...mapGetters({sum:'getters中的变量',username:'getters中的变量'})
    • 使用方式而:...mapGetters([getters中的变量1 , getters中的变量2 , ......])
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <template>
    <div>
    <div style="font-size: 20px;">{{ bigSum1 }}</div>
    <div style="font-size: 20px;">{{ newUsername1 }}</div>
    <div style="font-size: 20px;">{{ bigSum }}</div>
    <div style="font-size: 20px;">{{ newUsername }}</div>
    </div>
    </template>

    <script>
    //从vuex中引入mapGetters
    import {mapGetters} from 'vuex'

    export default {
    computed: {
    ...mapGetters({bigSum1: 'bigSum', newUsername1: 'newUsername'}),
    ...mapGetters(['bigSum', 'newUsername']),
    },
    }
    </script>

vuex的进阶使用—mapActions

在vue组件中使用actions中的方法时,总是要使用this.$store.dispatch('actions中的方法', 需要传入的值)访问actions中的方法,所以vuex提供了mapActions结合vue提供的methods一起使用能够快捷的访问actions中的方法

  • 创建vuex和在main.js中引入(上面创建store中有具体步骤)。这里只使用actions中的方法

    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
    import Vue from 'vue'
    import Vuex from 'vuex'

    Vue.use(Vuex)

    export default new Vuex.Store({
    actions: {
    jia(context, value) {
    context.commit('JIA', value)
    },
    jian(context, value) {
    context.commit('JIAN', value)
    }
    },
    mutations: {
    JIA(state, value) {
    state.sum += value
    },
    JIAN(state, value) {
    state.sum -= value
    }
    },
    state: {
    sum: 0,
    },
    getters: {},
    modules: {}
    })
  • 在组件中使用mapActions:在methods中使用

    • 使用对象的方式一个一个引入 / 使用数组的方式直接引入
    • 使用方式一:...mapActions({jia1:'actios中的方法',jian1:'actions中的方法'})
    • 使用方式而:...mapActions([actions中的方法1 , actions中的方法2 , ......])
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <template>
    <div>
    <div style="font-size: 20px" @click="jia(1)">jia</div>
    <div style="font-size: 20px" @click="jian(1)">jian</div>
    <div style="font-size: 20px" @click="jia1(1)">jia1</div>
    <div style="font-size: 20px" @click="jian1(1)">jian1</div>
    <div style="font-size: 20px;">{{ sum }}</div>
    </div>
    </template>

    <script>
    import {mapState, mapActions} from 'vuex'

    export default {
    computed: {
    ...mapState(['sum']),
    },
    methods: {
    ...mapActions({jia1: 'jia', jian1: 'jian'}),
    ...mapActions(['jia', 'jian']),
    },
    }
    </script>

vuex的进阶使用—mapMutations

在vue组件中使用actions中的方法时,总是要使用this.$store.dispatch('mutations中的方法', 需要传入的值)访问mutations中的方法,所以vuex提供了mapMutations结合vue提供的methods一起使用能够快捷的访问mutations中的方法

  • 创建vuex和在main.js中引入(上面创建store中有具体步骤)。这里只使用mutations中的方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    import Vue from 'vue'
    import Vuex from 'vuex'

    Vue.use(Vuex)

    export default new Vuex.Store({
    actions: {},
    mutations: {
    JIA(state, value) {
    state.sum += value
    },
    JIAN(state, value) {
    state.sum -= value
    }
    },
    state: {
    sum: 0,
    },
    getters: {},
    modules: {}
    })
  • 在组件中使用mapMutations:在methods中使用

    • 使用对象的方式一个一个引入 / 使用数组的方式直接引入
    • 使用方式一:...mapMutations({JIA1:'mutations中的方法',JIAN1:'mutations中的方法'})
    • 使用方式而:...mapMutations([mutations中的方法1 , mutations中的方法2 , ......])
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <template>
    <div>
    <div style="font-size: 20px" @click="JIA1(1)">JIA1</div>
    <div style="font-size: 20px" @click="JIAN1(1)">JIAN1</div>
    <div style="font-size: 20px" @click="JIA(1)">JIA</div>
    <div style="font-size: 20px" @click="JIAN(1)">JIAN</div>
    <div style="font-size: 20px;">{{ sum }}</div>
    </div>
    </template>

    <script>
    import {mapState ,mapMutations} from 'vuex'

    export default {
    computed: {
    ...mapState(['sum']),
    },
    methods: {
    ...mapMutations({JIA1: 'JIA', JIAN1: 'JIAN'}),
    ...mapMutations(['JIA', 'JIAN']),
    },
    }
    </script>

vuex模块化+命名空间

模块化可以将多个store整合到一个store中,需要在每个store中需要将namespaced: true

创建store

  • 创建子模块 person,里面用于放入一些用户的基本信息

    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
    export default {
    namespaced: true,
    //用于响应组件中的动作
    actions: {
    append(context, value) {
    context.commit("APPEND", value)
    }
    },
    //用于操作数据(state)
    mutations: {
    APPEND(state, value) {
    state.username += value
    }
    },
    //用于存储数据
    state: {
    username: "张三"
    },
    //用于将state中的数据进行加工,比如state中sum+1
    getters: {
    newUsername(state){
    return state.username+"是个好人"
    }
    },
    //用于存放vuex的各个模块,进行模块化管理时使用
    modules: {}
    }
  • 创建sum,里面用于放一些运算操作

    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
    export default {
    namespaced: true,
    //用于响应组件中的动作
    actions: {
    sum(context, value) {
    context.commit('SUM', value)
    }
    },
    //用于操作数据(state)
    mutations: {
    SUM(state, value) {
    state.sumValue += value
    }
    },
    //用于存储数据
    state: {
    sumValue: 20
    },
    //用于将state中的数据进行加工,比如state中sum+1
    getters: {
    bigSumValue(state) {
    return state.sumValue + 20
    }
    },
    //用于存放vuex的各个模块,进行模块化管理时使用
    modules: {}
    }
  • 创建index,用于整合所有模块

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import Vue from 'vue'
    import Vuex from 'vuex'

    //引入一个一个的store
    import sum from './sum'
    import person from './person'

    Vue.use(Vuex)

    export default new Vuex.Store({
    modules: {
    sum: sum,
    person: person
    }
    })

在vue中使用模块化中的store数据

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
38
39
40
41
42
43
44
45
<template>
<div>
<div style="font-size: 20px" @click="append('测试')">append</div>
<div style="font-size: 20px" @click="APPEND('测试2')">APPEND</div>
<div style="font-size: 20px" @click="sum(20)">sum</div>
<div style="font-size: 20px" @click="SUM(10)">SUM</div>
<div style="font-size: 20px;">{{ username }}</div>
<div style="font-size: 20px;">{{ newUsername }}</div>
<div style="font-size: 20px;">{{ sumValue }}</div>
<div style="font-size: 20px;">{{ bigSumValue }}</div>
</div>
</template>

<script>
import {mapState, mapGetters, mapActions, mapMutations} from 'vuex'

export default {
computed: {
//使用vuex提供的mapXxx方法
...mapState('person', ['username']),
...mapGetters('person', ['newUsername']),

//从$store方法中获取
bigSumValue() {
return this.$store.getters['sum/bigSumValue']
},
sumValue() {
return this.$store.state.sum.sumValue
}
},
methods: {
//使用mapXxx
...mapActions('person', ['append']),
...mapMutations('person', ['APPEND']),

//使用$store获取
sum() {
this.$store.dispatch('sum/sum', 20)
},
SUM() {
this.$store.commit('sum/SUM', 10)
}
},
}
</script>

vuex持久化

博客2:https://juejin.cn/post/6918684399659646989

vue-router

vue-router参数详解

router-link标签参数详解

一级路由

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
import Vue from 'vue'
import VueRouter from 'vue-router'

//引入组件
import Home from '../components/Home'

Vue.use(VueRouter)

/*
name:可以用于

*/

//创建路由
const routes = [
//创建路由方式一:使用import函数,直接找到组件,不用在开头引入组件,推荐使用
{path: '/', name: 'Index', component: () => import('@/views/index')},
//创建路由方式二:需要在开头先使用import引入组件,再到下面定义路由
{path:'/home', name: 'home', component:Home},

]

const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})

export default router

多级路由

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
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [
//多级路由方式创建一:只需要添加children的值,值为创建一个新的路由,children的值是一个数组
//二级路由访问路径为:一级路由地址/二级路由地址
{
path: '/image4',
name: 'Image4',
component: () => import('@/views/图片展示/图片4'),
children: [
//一个一个嵌套即可
{
path: '/image1',
name: 'Image1',
component: () => import('@/views/图片展示/图片1')
}
]
},

]

const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})

export default router

1
2
3
4
5
6
7
8
9
<template>
<div id="app">
<router-view/>
<!-- 跳转路由并携带query参数,to的字符串写法 -->
<router-link :to="`/home?id=${1}&title=${'测试'}`">测试</router-link>
<!-- 跳转路由并携带query参数,to的对象写法 -->
<router-link :to="{path:'/home',query:{id:1,title:'测试'}}">路由测试</router-link>
</div>
</template>

命名路由

利用路由的name的值访问路由

  • 定义一个路由

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    import Vue from 'vue'
    import VueRouter from 'vue-router'

    Vue.use(VueRouter)

    const routes = [
    {path: '/image4', name: 'Image4', component: () => import('@/views/index')},
    ]

    const router = new VueRouter({
    mode: 'history',
    base: process.env.BASE_URL,
    routes
    })

    export default router
  • 利用路由的path和name属性访问组件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <template>
    <div>
    <!-- 使用name属性访问 -->
    <router-link :to="{name:'Image4'}">测试</router-link><br/>
    <!-- 使用path属性访问 -->
    <router-link :to="{path:'image4'}">测试</router-link><br/>
    <!-- 直接写路径,可以默认为path的值 -->
    <router-link to="/image4">测试</router-link><br/>
    </div>
    </template>

css解决文本溢出

1
2
3
4
5
6
7
8
*{
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
//设置几行开始使用省略号
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}

格式化配置文件

命名为.editorconfig文件

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
38
# 告诉EditorConfig插件,这是根文件,不用继续往上查找
root = true

# 匹配全部文件
[*]
# 结尾换行符,可选"lf"、"cr"、"crlf"
end_of_line = lf
# 在文件结尾插入新行
insert_final_newline = true
# 删除一行中的前后空格
trim_trailing_whitespace = true
# 匹配js和py结尾的文件
[*.{js,py,vue, html, css}]
# 设置字符集
charset = utf-8

# 匹配py结尾的文件
[*.{js, py, vue, html}]
# 缩进风格,可选"space"、"tab"
indent_style = space
# 缩进的空格数
indent_size = 4

# 以下匹配,类同
[Makefile]
indent_style = tab
# tab的宽度
tab_width = 4

# 以下匹配,类同
[lib/**.js]
indent_style = space
indent_size = 2

[{package.json, .travis.yml}]
indent_style = space
indent_size = 2

CSS重置样式表和基础样式

reset.css

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
38
39
40
41
42
43
44
45
46
47
48
/* http://meyerweb.com/eric/tools/css/reset/ 
v2.0 | 20110126
License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}

normalize.css

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */

/* Document
========================================================================== */

/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/

html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}

/* Sections
========================================================================== */

/**
* Remove the margin in all browsers.
*/

body {
margin: 0;
}

/**
* Render the `main` element consistently in IE.
*/

main {
display: block;
}

/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/

h1 {
font-size: 2em;
margin: 0.67em 0;
}

/* Grouping content
========================================================================== */

/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/

hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}

/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/

pre {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}

/* Text-level semantics
========================================================================== */

/**
* Remove the gray background on active links in IE 10.
*/

a {
background-color: transparent;
}

/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/

abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}

/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/

b,
strong {
font-weight: bolder;
}

/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/

code,
kbd,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}

/**
* Add the correct font size in all browsers.
*/

small {
font-size: 80%;
}

/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/

sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}

sub {
bottom: -0.25em;
}

sup {
top: -0.5em;
}

/* Embedded content
========================================================================== */

/**
* Remove the border on images inside links in IE 10.
*/

img {
border-style: none;
}

/* Forms
========================================================================== */

/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/

button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}

/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/

button,
input { /* 1 */
overflow: visible;
}

/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/

button,
select { /* 1 */
text-transform: none;
}

/**
* Correct the inability to style clickable types in iOS and Safari.
*/

button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}

/**
* Remove the inner border and padding in Firefox.
*/

button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}

/**
* Restore the focus styles unset by the previous rule.
*/

button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}

/**
* Correct the padding in Firefox.
*/

fieldset {
padding: 0.35em 0.75em 0.625em;
}

/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/

legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}

/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/

progress {
vertical-align: baseline;
}

/**
* Remove the default vertical scrollbar in IE 10+.
*/

textarea {
overflow: auto;
}

/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/

[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}

/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/

[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}

/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/

[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}

/**
* Remove the inner padding in Chrome and Safari on macOS.
*/

[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}

/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/

::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}

/* Interactive
========================================================================== */

/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/

details {
display: block;
}

/*
* Add the correct display in all browsers.
*/

summary {
display: list-item;
}

/* Misc
========================================================================== */

/**
* Add the correct display in IE 10+.
*/

template {
display: none;
}

/**
* Add the correct display in IE 10.
*/

[hidden] {
display: none;
}