响应式布局
本人在写项目时使用响应式布局查找的资料、得到的收获和遇到的Bug
以下有引用了其他作者的文章,若有侵权,联系删除!
疑问
1rem
为何不能为1px
当前浏览器设定的最小字体大小为12px,所以浏览器自动把html{font-size: 1px}
识别为html{font-size: 12px}
,所以效果也就是1rem = 12px
。
在调整浏览器最小字体大小以后,也验证了以上原因是正确的。
所以设定为1rem=100px
,也是最简便的开发方式。
注意
-
宽度需要使用百分比
例如这样:
#head { width: 100% } #content { width: 50%; }
-
处理图片缩放的方法
- 简单的解决方法可以使用百分比,但这样不友好,会放大或者缩小图片。那么可以尝试给图片指定的最大宽度为百分比。假如图片超过了,就缩小。假如图片小了,就原尺寸输出。
img { width: auto; max-width: 100%; }
- 用
::before
和::after
伪元素 +content 属性来动态显示一些内容或者做其它很酷的事情,在 css3 中,任何元素都可以使用 content 属性了,这个方法就是结合 css3 的 attr 属性和 HTML 自定义属性的功能: HTML结构:
<img src="image.jpg" data-src-600px="image-600px.jpg" data-src-800px="image-800px.jpg" alt="">
CSS 控制:
@media (min-device-width:600px) { img[data-src-600px] { content: attr(data-src-600px, url); } } @media (min-device-width:800px) { img[data-src-800px] { content: attr(data-src-800px, url); } }
-
其他属性
例如
pre
,iframe
,video
等,都需要和img
一样控制好宽度。对于table
,建议不要增加 padding 属性,低分辨率下使用内容居中:table th, table td { padding: 0 0; text-align: center; }
方案
PC端
方法1
function setRem() {
var ui_w = 375;
// 获取屏幕的宽度
var clientWidth = document.documentElement.clientWidth || document.body.clientWidth;
console.log(ui_w, clientWidth);
// 通过js动态改变html根节点字体大小
var html_ = document.getElementsByTagName('html')[0];
html_.style.fontSize = (clientWidth / ui_w) * 10 + 'px';
}
// window.onresize 浏览器被重置大小执行事件
window.onresize = setRem;
移动端
方法1
移动端自适应单用 rem,设置他HTML的字体的话会出现更换手机字体,元素大小会改变
解决方式:可以引入这个js
'use strict'
!(function(e, t) {
var n,
i = document,
d = window,
o = i.documentElement,
a = document.createElement('style')
function s() {
var n = o.getBoundingClientRect().width
n > (t = t || 540) && (n = t)
var i = (100 * n) / e
a.innerHTML = 'html{font-size:' + i + 'px;}'
}
if (o.firstElementChild) o.firstElementChild.appendChild(a)
else {
var r = i.createElement('div')
r.appendChild(a), i.write(r.innerHTML), (r = null)
}
s(),
d.addEventListener(
'resize',
function() {
clearTimeout(n), (n = setTimeout(s, 300))
},
!1
),
d.addEventListener(
'pageshow',
function(e) {
e.persisted && (clearTimeout(n), (n = setTimeout(s, 300)))
},
!1
),
'complete' === i.readyState
? (i.body.style.cssText =
'fontSize:16px;maxWidth:' + t + 'px;margin:0 auto;')
: i.addEventListener(
'DOMContentLoaded',
function(e) {
i.body.style.cssText =
'font-size:16px;max-width:' + t + 'px;margin:0 auto;'
},
!1
)
})(750, 750)
然后直接将你设计图上的px/100换成rem就可以了
方法2
(function () {
function setRootFontSize() {
let dpr, rem, scale, rootWidth;
let rootHtml = document.documentElement;
dpr = window.devicePixelRatio || 1; //移动端必须设置
//限制展现页面的最小宽度
rootWidth = rootHtml.clientWidth < 1366 ? 1366 : rootHtml.clientWidth;
rem = rootWidth * dpr / 19.2; // 19.2 = 设计图尺寸宽1920 / 100(设计图的rem = 100)
scale = 1 / dpr;
// 设置viewport,进行缩放,达到高清效果 (移动端添加)
let vp = document.querySelector('meta[name="viewport"]');
vp.setAttribute('content', 'width=' + dpr * rootHtml.clientWidth + ',initial-scale=' + scale + ',maximum-scale=' + scale + ', minimum-scale=' + scale + ',user-scalable=no');
// 动态写入样式
rootHtml.style.fontSize = `${rem}px`;
}
setRootFontSize();
window.addEventListener("resize", setRootFontSize, false);
window.addEventListener("orientationchange", setRootFontSize, false); //移动端
})();
方法3
(function(){
var originWidthByDesign = 750 / 2;
var originRootFontSize = 50;
var maxLimitWidth = 667;
var doc = document.documentElement;
var div = document.createElement('div');
div.setAttribute('style', 'font-size: 1rem');
if (!!document.addEventListener && '1rem' === div.style.fontSize) {
var reCalculate = function reCalculate() {
var clientWidth = doc.clientWidth;
if (!clientWidth) {
return;
}
clientWidth = clientWidth < maxLimitWidth ? clientWidth : maxLimitWidth;
doc.style.fontSize = originRootFontSize * clientWidth / originWidthByDesign + 'px';
doc.style.display = 'none';
doc.clientWidth;
doc.style.display = '';
};
window.addEventListener('resize', reCalculate, false);
document.addEventListener('DOMContentLoaded', reCalculate, false);
reCalculate();
}
function getQueryString (name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]); return null;
}
})()
方法4
方式
1. 媒体查询
注意:IE6、7、8不支持媒体查询
分割点
-
600px
,900px
,1200px
,1800px
-
480px
,800px
,1400px
,1400px
-
移动优先 OR PC优先
后面的样式会覆盖前面的样式。因此,移动端优先首先使用的是
min-width
,PC端优先使用的max-width
。 -
移动优先
/* iphone6 7 8 */ body { background-color: yellow; } /* iphone 5 */ @media screen and (max-width: 320px) { body { background-color: red; } } /* iphoneX */ @media screen and (min-width: 375px) and (-webkit-device-pixel-ratio: 3) { body { background-color: #0FF000; } } /* iphone6 7 8 plus */ @media screen and (min-width: 414px) { body { background-color: blue; } } /* ipad */ @media screen and (min-width: 768px) { body { background-color: green; } } /* ipad pro */ @media screen and (min-width: 1024px) { body { background-color: #FF00FF; } } /* pc */ @media screen and (min-width: 1100px) { body { background-color: black; } }
-
PC优先
/* pc width > 1024px */ body { background-color: yellow; } /* ipad pro */ @media screen and (max-width: 1024px) { body { background-color: #FF00FF; } } /* ipad */ @media screen and (max-width: 768px) { body { background-color: green; } } /* iphone6 7 8 plus */ @media screen and (max-width: 414px) { body { background-color: blue; } } /* iphoneX */ @media screen and (max-width: 375px) and (-webkit-device-pixel-ratio: 3) { body { background-color: #0FF000; } } /* iphone6 7 8 */ @media screen and (max-width: 375px) and (-webkit-device-pixel-ratio: 2) { body { background-color: #0FF000; } } /* iphone5 */ @media screen and (max-width: 320px) { body { background-color: #0FF000; } }
2. 百分比布局
Bootstrap里面的栅格系统就是利用百分比来定义元素的宽高,CSS3
支持最大最小高,可以将百分比和max(min)
一起结合使用来定义元素在不同设备下的宽高。
-
height
或width
是分别相对于父元素高宽 -
top
、bottom
相对于非static
定位(默认定位)的父元素的高度 -
left
、right
相对于非static
定位(默认定位)的父元素的宽度 -
padding
、margin
都相对于父亲元素的width
-
border-radius
是相对于自身的宽度 -
translate
、background-size
等都是相对于自身的 -
border
、font-size
不能用百分比设置的
缺点:
- 计算困难,换算成百分比单位。
- 参照物不同
/* pc width > 1100px */
html, body { margin: 0;padding: 0;width: 100%;height: 100%;}
aside {
width: 10%;
height: 100%;
background-color: red;
float: left;
}
main {
height: 100%;
background-color: blue;
overflow: hidden;
}
/* ipad pro */
@media screen and (max-width: 1024px) {
aside {
width: 8%;
background-color: yellow;
}
}
/* ipad */
@media screen and (max-width: 768px) {
aside {
float: none;
width: 100%;
height: 10%;
background-color: green;
}
main {
height: calc(100vh - 10%);
background-color: red;
}
}
/* iphone6 7 8 plus */
@media screen and (max-width: 414px) {
aside {
float: none;
width: 100%;
height: 5%;
background-color: yellow;
}
main {
height: calc(100vh - 5%);
background-color: red;
}
}
/* iphoneX */
@media screen and (max-width: 375px) and (-webkit-device-pixel-ratio: 3) {
aside {
float: none;
width: 100%;
height: 10%;
background-color: blue;
}
main {
height: calc(100vh - 10%);
background-color: red;
}
}
/* iphone6 7 8 */
@media screen and (max-width: 375px) and (-webkit-device-pixel-ratio: 2) {
aside {
float: none;
width: 100%;
height: 3%;
background-color: black;
}
main {
height: calc(100vh - 3%);
background-color: red;
}
}
/* iphone5 */
@media screen and (max-width: 320px) {
aside {
float: none;
width: 100%;
height: 7%;
background-color: green;
}
main {
height: calc(100vh - 7%);
background-color: red;
}
}
3. rem布局
rem是以HTML根的font-size为基准的
em是以父元素的font-size为基准的
4. 视口单位
单位 | 含义 |
---|---|
vw | 相对于视窗的宽度,1vw 等于视口宽度的1%,即视窗宽度是100vw |
vh | 相对于视窗的高度,1vh 等于视口高度的1%,即视窗高度是100vh |
vmin | vw和vh中的较小值 |
vmax | vw和vh中的较大值 |
单位 | 含义 |
---|---|
% | 大部分相对于祖先元素,也有相对于自身的情况比如(border-radius、translate等) |
vw/vh | 相对于视窗的尺寸 |
5. 弹性布局
绝大多数设备尤其是移动端都很好的支持FLEX,所以可以放心使用。
6. 图片响应式
这里的图片响应式包括两个方面,一个就是大小自适应,这样能够保证图片在不同的屏幕分辨率下出现压缩、拉伸的情况;一个就是根据不同的屏幕分辨率和设备像素比来尽可能选择高分辨率的图片,也就是当在小屏幕上不需要高清图或大图,这样我们用小图代替,就可以减少网络带宽了。
1.使用max-width(图片自适应):
图片自适应意思就是图片能随着容器的大小进行缩放,可以采用如下代码:
img {
display: inline-block;
max-width: 100%;
height: auto;
}
inline-block
元素相对于它周围的内容以内联形式呈现,但与内联不同的是,这种情况下我们可以设置宽度和高度。 max-width
保证了图片能够随着容器的进行等宽扩充(即保证所有图片最大显示为其自身的 100%。此时,如果包含图片的元素比图片固有宽度小,图片会缩放占满最大可用空间),而height
为auto
可以保证图片进行等比缩放而不至于失真。如果是背景图片的话要灵活运用background-size
属性。
那么为什么不能用width:100%
呢?因为这条规则会导致它显示得跟它的容器一样宽。在容器比图片宽得多的情况下,图片会被无谓地拉伸。
2.使用srcset
<img srcset="photo_w350.jpg 1x, photo_w640.jpg 2x" src="photo_w350.jpg" alt="">
如果屏幕的dpi = 1的话则加载1倍图,而dpi = 2则加载2倍图,手机和mac基本上dpi都达到了2以上,这样子对于普通屏幕来说不会浪费流量,而对于视网膜屏来说又有高清的体验。
如果浏览器不支持srcset
,则默认加载src里面的图片。
但是你会发现实际情况并不是如此,在Mac上的Chrome它会同时加载srcset
里面的那张2x的,还会再去加载src里面的那张,加载两张图片。顺序是先把所有srcset
里面的加载完了,再去加载src的。这个策略比较奇怪,它居然会加载两张图片,如果不写src,则不会加载两张,但是兼容性就没那么好。这个可能是因为浏览器认为,既然有srcset
就不用写src了,如果写了src,用户可能是有用的。而使用picture
就不会加载两张
3.使用background-image
.banner{
background-image: url(/static/large.jpg);
}
@media screen and (max-width: 767px){
background-image: url(/static/small.jpg);
}
4.使用picture标签
picturefill.min.js :解决IE等浏览器不支持 的问题
<picture>
<source srcset="banner_w1000.jpg" media="(min-width: 801px)">
<source srcset="banner_w800.jpg" media="(max-width: 800px)">
<img src="banner_w800.jpg" alt="">
</picture>
<!-- picturefill.min.js 解决IE等浏览器不支持 <picture> 的问题 -->
<script type="text/javascript" src="js/vendor/picturefill.min.js"></script>
picture
必须要写img标签,否则无法显示,对pictur
e的操作最后都是在img上面,例如onload事件是在img标签触发的,picture
和source
是不会进行layout的,它们的宽和高都是0。
另外使用source
,还可以对图片格式做一些兼容处理:
<picture>
<source type="image/webp" srcset="banner.webp">
<img src="banner.jpg" alt="">
</picture>
总结:响应式布局的实现可以通过媒体查询+px
,媒体查询+百分比,媒体查询+rem
+js
,vm/vh
,vm/vh
+rem
这几种方式来实现。但每一种方式都是有缺点的,媒体查询需要选取主流设备宽度尺寸作为断点针对性写额外的样式进行适配,但这样做会比较麻烦,只能在选取的几个主流设备尺寸下呈现完美适配,另外用户体验也不友好,布局在响应断点范围内的分辨率下维持不变,而在响应断点切换的瞬间,布局带来断层式的切换变化,如同卡带的唱机般“咔咔咔”地一下又一下。通过百分比来适配首先是计算麻烦,第二各个属性中如果使用百分比,其相对的元素的属性并不是唯一的,这样就造成我们使用百分比单位容易使布局问题变得复杂。通过采用rem
单位的动态计算的弹性布局,则是需要在头部内嵌一段脚本来进行监听分辨率的变化来动态改变根元素字体大小,使得CSS
与JS
耦合了在一起。通过利用纯css
视口单位实现适配的页面,是既能解决响应式断层问题,又能解决脚本依赖的问题的,但是兼容性还没有完全能结构接受。
7. 设置mate标签
下面的视图标签告诉浏览器,使用设备的宽度作为视图宽度并禁止初始的缩放。在<head>
标签里加入这个meta标签。
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
[1](user-scalable = no 属性能够解决 iPad 切换横屏之后触摸才能回到具体尺寸的问题。 )
响应式布局的成型方案
现在的css,UI框架等都已经考虑到了适配不同屏幕分辨率的问题,实际项目中我们可以直接使用这些新特性和框架来实现响应式布局。可以有以下选择方案:
- 利用上面的方法自己来实现,比如CSS3 Media Query,rem,vw等
- Flex弹性布局,兼容性较差
- Grid网格布局,兼容性较差
- Columns栅格系统,往往需要依赖某个UI库,如Bootstrap
响应式布局的要点
在实际项目中,我们可能需要综合上面的方案,比如用rem
来做字体的适配,用srcset
来做图片的响应式,宽度可以用rem
,flex
,栅格系统等来实现响应式,然后可能还需要利用媒体查询来作为响应式布局的基础,因此综合上面的实现方案,项目中实现响应式布局需要注意下面几点:
- 设置viewport
- 媒体查询
- 字体的适配(字体单位)
- 百分比布局
- 图片的适配(图片的响应式)
- 结合flex,grid,BFC,栅格系统等已经成型的方案
遇到的BUG
1. webkit的Font Boosting
其默认最小为12px
原理,Font Boosting 的计算规则伪代码如下:
multiplier = Math.max(1, deviceScaleAdjustment * textScalingSlider * systemFontScale * clusterWidth / screenWidth);
if (originFontSize < 16) {
computedFontSize = originFontSize * multiplier;
}
else if (16 <= originFontSize <= (32 * multiplier - 16)) {
computedFontSize = (originFontSize / 2) + (16 * multiplier - 8);
}
else if (originFontSize > (32 * multiplier - 16)) {
computedFontSize = originFontSize;
}
originFontSize: 原始字体大小
computedFontSize: 经过计算后的字体大小
multiplier: 换算系数,值由以下几个值计算得到
deviceScaleAdjustment: 当指定 viewport width=device-width 时此值为 1,否则值在1.05 - 1.3之间,有专门的计算规则
textScalingSlider: 浏览器中手动指定的缩放比例,默认为 1
systemFontScale: 系统字体大小,Android设备可以在「设备 - 显示 - 字体大小」处设置,默认为 1
clusterWidth: 应用 Font Boosting 特性字体所在元素的宽度(如何确定这个元素请参考上边两个链接)
screenWidth: 设备屏幕分辨率(DIPs, Density-Independent Pixels),如 iPhone 5 为 320
解决方法:
1.
body,body *{*
max-height:1000000px
}
或
p { max-height: 999999px; } //只在安卓上有用
或
max-height: 100%
2.用viewport的width手动指定宽度,但是对我的页面没什么效果
3.给body设置max-width等于99999px(这是唯一有效的属性,max-height是无效的)
4.单独给搞事的那段标签设置max-width,这样问题就不会出现了
5.<meta name="viewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, user-scalable=no"> 缩放比设为1,至于1px之类的问题可以采取其他方案解决。
6.设置text-size-adjust:none,不过大部分浏览器都不兼容。
2. 浏览器兼容问题–插件Autoprefixe
vscode搜索Autoprefixer
配置如下:
"git.ignoreLimitWarning": true,
"autoprefixer.browsers": [
"> 1%",
"last 2 versions",
"not ie <= 8",
"ios >= 8",
"android >= 4.0",
"firefox >= 8",
"chrome >= 24",
"Opera>=10"
],
使用快捷键 Ctrl+Shift+p 显示所有命令 ,然后搜索Autoprefixer,然后点击它就行了
知识:
- -moz代表firefox浏览器私有属性
- -ms代表IE浏览器私有属性
- -webkit代表chrome、safari私有属性
- -o代表opera私有属性
3. 手机端百度、夸克浏览器和PC端360浏览器极速模式的样式混乱
4. vue打包后,element组件的宽度会改变
5. 引入组件
<script>
import Car from './components/Car.vue'
export default {undefined
name: 'App',
components:{//添加自定义组件
Car
}
}
</script>
6. 引入全局组件
main.js:
//加载中组件
import loadingLayer from "@/components/loadingLayer.vue"
Vue.component("loadingLayer",loadingLayer)
7. 兄弟组件间的传值
**第一步:创建一个js文件,eventBus.js,**位置随便放,我是放在了src目录下
import Vue from 'vue'
export default new Vue()
第二步:在top组件中,引入刚才的js
import '@/eventBus.js'
然后在methods里边定义一个函数(要发送数据的组件)
methods:{
changesize(){
eventBus.$emit('add',this.arg)
}
}
假设点击button触发changesize函数,然后将arg传出去
第三步:在left组件中也先让引入eventBus.js,然后使用created生命周期函数(要接受数据的组件)
created(){
eventBus.$on('add',(message)=>{
//一些操作,message就是从top组件传过来的值
console.log(message)
})
},
8. 定义全局变量
只读全局变量
方案一:Vue.prototype
Vue.prototype.baseURL = "http://120.76.52.65/phpsaomaserver";
方案二:设置并引入全局变量文件
创建一个 Store.vue 文件并暴露出去, 用来保存全局变量
<script>
const name = 'shenxianhui';
const age = 24;
export default {
name,
age
};
</script>
在 Test.vue 组件中使用
<template>
<div>{{ myName }}</div>
<div>{{ myAge }}</div>
</template>
<script>
import myStore from '@/components/Store'; // 引用模块
export default {
data () {
return {
myName: myStore.name,
myAge: myStore.age
}
}
}
</script>
可读可写全局变量
-
main.js 中定义
new Vue({ router, data: function(){ return { ORDERID: 'PLDxxxxxx0001', } }, render: h => h(App) }).$mount('#app');
-
引用
// 修改 this.$root.ORDERID = "xxxxx" // 引用 let orderId = this.$root.ORDERID
本地存储
HTML5新增
localStorage:永久性,一直存在于浏览器中,除非用户手动清除localStorage;一般为5M浏览器不同有些许区别;不参与和服务器的通信。
sessionStorage:在当前会话下有效,关闭页面和浏览器清除后失效;一般为5M浏览器不同有些许区别;不参与和服务器的通信。
API:二者的api形式相同
localStorage.setItem("key","value"); //以“key”为名称存储一个值“value”
localStorage.getItem("key"); //获取名称为“key”的值
localStorage.removeItem("key"); //删除名称为“key”的信息。
localStorage.clear(); //清空localStorage中所有信息
设置localStorage过期时间的实例
let setTime = new Date().getTime() + (1000 * 60); // 测试,设置1分钟后数据过期
localStorage.setItem('test', JSON.stringify({
data: 'data1',
expiration: setTime
}));
let data = localStorage.test;
data = JSON.parse(data)
let time = data.expiration;
let value = data.data;
if(new Date().getTime() > time) {
delete localStorage.test;
// 这里开始执行超时的代码
}
else {
// 这里开始执行未超时的代码
}
Cookie存储
这种方式极不推荐,毕竟大小限制,还需要设置过期时间。
cookie在过期时间之前一直有效即使窗口或浏览器关闭;
存放数据大小为4k左右;
有个数限制(随浏览不同)一般不能超过20个;
有域的概念的,在不同的域下,cookie不能互相使用。
与服务端通信,子域名访问http请求的话都是带上主域名下的cookie,会减慢访问速度,如果使用cookie保存过多数据会带来性能问题。
9. 自动同步到服务器
方案一:vue的package.json文件
"push": "npm run build && scp -r dist/* root@120.76.52.65:/www/wwwroot/120.76.52.65"
免密登录
-
登录宝塔获取ssh密钥
-
将密钥导入本地.ssh文件夹中
-
配置config文件
# 腾讯轻量云 Host <主机名> HostName <自定义> PreferredAuthentications publickey IdentityFile ~/.ssh/<密钥文件名>
方案二:SFTP插件
配置文件
{
"name": "本地文件夹名称(可自定义)",
"host": "ip或域名",
"protocol": "协议:[sftp/ftp]默认ftp",
"port": 22,
"username": "username",
"password":"password",
"remotePath": "远程文件夹地址,默认/",
"context": "本地文件夹地址,默认为vscode工作区根目录",
"uploadOnSave": true,
"downloadOnOpen":false,
"connectTimeout":300,
"ignore": [
"**/.vscode/**",
"**/.git/**",
"**/.DS_Store"
],
"watcher": {
"files": "*",
"autoUpload": false,
"autoDelete": false
}
}
uploadOnSave:本地更新文件保存会自动同步到远程文件(不会同步重命名文件和删除文件)
downloadOnOpen:从远程服务器下载打开的文件
ignore:忽略的文件(匹配的文件不会同步)
watcher:监听器(可以重命名文件和删除文件)
autoUpload:文件变更会自动同步(修改和重命名)
autoDelete:文件删除会自动同步
实例
{
"name": "test",
"host": "abc.com",
"protocol": "ftp",
"port": 21,
"username": "username",
"password":"password",
"remotePath": "/",
"uploadOnSave": true,
"connectTimeout":300,
"ignore": [
"**/.vscode/**",
"**/.git/**",
"**/.DS_Store"
],
"watcher": {
"files": "*",
"autoUpload": false,
"autoDelete": false
}
}
10. 获取节点方法
1. vue
获取dom节点可以用ref属性
this.$refs.<ref的值>
2. 原生js
document.getElementById('<id>')
//以下获取的时数组,操作时需要加上[0]
document.getElementsByName('<name属性的值>')
document.getElementsByTagName('<标签名>')
document.getElementsByClassName('<类名>')
11. 修改ElementUI样式的几种方式
1. 新建全局样式表
新建 global.css 文件,并在 main.js 中引入。 global.css 文件一般都放在 src->assets 静态资源文件夹下的 style 文件夹下,在 main.js 的引用写法如下:
import "./assets/style/global.css";
在 global.css 文件中写的样式,无论在哪一个 vue 单页面都会覆盖 ElementUI 默认的样式。
2. 在当前 vue 单页面中添加一个新的style
标签
在当前的vue单页面的style
标签后,添加一对新的style
标签,新的style
标签中不要添加scoped
属性。在有写scoped
的style
标签中书写的样式不会覆盖 ElementUI 默认的样式。
3. 使用 /deep/
深度修改标签样式或>>>
找到需要修改的 ElementUI 标签的类名,然后在类名前加上 /deep/
,可以强制修改默认样式。这种方式可以直接用到有 scoped
属性的 style 标签中。
// 修改级联选择框的默认宽度
/deep/ .el-cascader {
width: 100%;
}
<style scoped>
.a >>> .b { /* ... */ }
//less中不能使用
</style>
//定义成变量使用
//也可以在全局样式表中为 >>> 取别名,那么就可以直接在页面任何 style 标签中使用其别名如 @{data} 来修改页面样式了
//多个 @{data} 可以同级使用,但不能相互嵌套,否则将不会生效
<style scoped lang='less'>
@deep: ~'>>>';
.box {
@{deep} .title {
...
}
}
</style>
4. 通过内联样式 或者 绑定类样式覆盖默认样式
通过内联样式 style ,绑定类样式的方式,可以在某些标签中可以直接覆盖默认样式,不是很通用。具体实例如下:
内联样式style
的方式:
<el-button :style="selfstyle">默认按钮</el-button>
<script>
export default {
data() {
return {
selfstyle: {
color: "white",
marginTop: "10px",
width: "100px",
backgroundColor: "cadetblue"
}
};
}
}
</script>
通过绑定修改样式方式修改:
<el-button :class="[selfbutton]">默认按钮</el-button>
<script>
export default {
data() {
return {
selfbutton: "self-button"
};
}
}
</script>
<style lang="stylus" rel="stylesheet/stylus" scoped>
.self-button {
color: white;
margin-top: 10px;
width: 100px;
background-Color: cadetblue;
}
</style>
5.总结
第一种全局引入css文件的方式,适合于对elementUI整体的修改,比如整体配色的修改;第二种添加一个style标签的形式,也能够实现修改默认样式的效果,但实际上因为是修改了全局的样式,因此在不同的vue组件中修改同一个样式有可能会有冲突。
第三种方式通过 /deep/ 的方式可以很方便的在vue组件中修改默认样式,也不会于其他页面有冲突。
第四种方式局限性比较大,可以使用,但不推荐使用。