将很多可重复使用的样式提取出来,放在一个公共的css文件中,一方面自己书写很方便,另一方面可以大量减少vue文件里的css代码,进而减少vue文件的size。
atom.css定义为提供基础类的CSS库,一个class对应一个单独的CSS属性,与Bootstrap、Ant Design等UI框架提供的块状CSS不同的是,atom.css单一属性class将各种CSS块状属性解耦,开发者在书写模板时拥有了极大的自由,在布局时基本上不要去写单独的CSS,而这为后续开发和维护提供了足够的灵活性。atom.css更为强大的一点是,它极大地缩短了开发者书写模板的时间,也就是说让开发者有更多的时间去关注业务逻辑,让许多业务特别重的开发人员可以更快地完成工作。
atom.css的灵感来源于有机化学。在有机化学中,元素作为最小单位,构成各种有机物,不同的元素经过排列组合可以形成不同的有机物,再由这些有机物构成物质。
atom.css将常用的 CSS属性转换成单一的class,比如 display:flex 转化为 .flex {display:flex},当我们在使用HTML写页面骨架的时候,你就可以一边写结构,一边写样式,省去了一部分在写完HTML结构之后再去写界面样式的时间。
.flex{
display:flex;
}
.justify_center{
justify-content:center;
}
.align_center{
align-items:center;
}
atom.css目前有100+个单元class,其实我们没必要用他的类库,我们只需要这种思想即可,然后我们可以写一个公共的public.css,写上我们自己网页经常用到的样式,形成自己的css库,然后在写页面html结构的时候,就直接在class里通过几个class类名组合达到想到的效果。
以下面这个贡献排行榜为例,对比传统写法和atom.css
<template>
<div class="emcs-panel">
<div class="panel-title">
<div class="title">每日一题</div>
</div>
<div class="daily-box">
<div class="desc">
<div>作者:{{task.author}}</div>
<div>贡献 {{task.contributes}} 题</div>
<div>参与答题 {{task.submittedCount}} 人</div>
<div>答对 {{task.correctCount}} 人</div>
</div>
<div class="title">{{task.question.title}}</div>
<div class="btn-box">
<router-link class="emcs-btn bold" to="/test">去答题</router-link>
<router-link class="btn-txt ml15" to="/homePage?daily">每日任务</router-link>
</div>
</div>
</div>
</template>
<style lang="stylus" scoped>
.daily-box{
padding 20px
.desc{
font-size 12px
line-height 18px
color #999
div{
display inline-block
margin-right 10px
}
}
.title{
font-size 14px
line-height 20px
color #333333
margin-top 15px
word-break break-all
}
.btn-box{
margin-top 20px
text-align center
}
}
</style>
传统写法的缺点:
取名困难,节点结构一多,取名真的是个难事。当然了,我们可以用一些规范或者选择器的方式去规避一些取名问题。
需要用 JS 控制样式的时候又得多写一个类,尤其交互多的场景。
组件复用大家都懂,但是样式复用少之又少,这样就造成了冗余代码变多。
全局污染,这个其实现在挺多工具都能帮我们自动解决了。
采用atom.css的写法
<template>
<div class="emcs-panel">
<div class="panel-title">
<div class="title">每日一题</div>
</div>
<div class="pad20">
<div class="font12 mb15">
<span class="mr10">作者:{{task.author}}</span>
<span class="mr10">贡献 {{task.contributes}} 题</span>
<span class="mr10">参与答题 {{task.submittedCount}} 人</span>
<span>答对 {{task.correctCount}} 人</span>
</div>
<div class="font14">{{task.question.title}}</div>
<div class="vc mt20">
<router-link class="emcs-btn bold" to="/test">去答题</router-link>
<router-link class="btn-txt ml15" to="/homePage?daily">每日任务</router-link>
</div>
</div>
</div>
</template>
使用atom-style CSS的思想,优点如下:
1、样式复用:自己写好定义的类,在写html结构的时候就可以直接将样式写出来了,不需要再到style里去写样式,这样的话,我的一个vue页面,有时候基本都不需要写style。相当于我们把通用的样式拆分为原子形式,然后拼接组合成自己想要的样式效果,vue的style里就只写一些页面特定的样式效果。这样我做的几个项目里基本上都是一个public.css通用样式文件,再加少量特定的页面内的style就可以完成绝大部分设计效果。因为设计美感本来就讲究对称美,所以很多比如字体、间距、颜色、盒子padding等,都会是固定的几种,不可能会花里胡哨、大小不一等。
2、避免代码冗余,可以极大减少文件体积
3、全局修改很方便
PS:以下是自己平时用的公共css
// 字体
.f30{
font-size: 30px;
line-height 40px
}
.f24{
font-size 24px
line-height 30px
}
.f20{
font-size 20px
line-height 30px
font-weight 600
color #333
word-break break-all
}
.font18{
font-size 18px
line-height 20px
font-weight 600
color #333
word-break break-all
}
.f18{
font-size 18px
line-height 30px
color: #333;
word-break break-all
}
.font16{
font-size 16px
line-height 22px
color #333
word-break break-all
}
.f16{
font-size 16px
line-height 20px
word-break break-all
}
.font14{
font-size 14px
line-height 22px
color #666
word-break break-all
}
.h44{
height: 44px;
}
.f13{
font-size 13px
line-height 18px
word-break break-all
}
.font12{
font-size 12px
line-height 18px
color #999
word-break break-all
}
.f10{
font-size: 10px;
}
.c3{
color: #333;
}
.c6{
color: #666;
}
.c9{
color: #999;
}
.cf{
color: #fff;
}
.b{
font-weight bold
}
.p-wrap{
white-space pre-wrap
}
.m10{
margin: 10px;
}
.mb5{
margin-bottom: 5px;
}
.mb10{
margin-bottom: 10px;
}
.mb15{
margin-bottom: 15px;
}
.mb20{
margin-bottom: 20px;
}
.mb30{
margin-bottom: 30px;
}
.mt5{
margin-top: 5px;
}
.mt10{
margin-top: 10px;
}
.mt20{
margin-top: 20px;
}
.mt40{
margin-top: 40px;
}
.mt110{
margin-top: 110px;
}
.mr30{
margin-right: 30px;
}
.mr20{
margin-right: 20px;
}
.mr10{
margin-right: 10px;
}
.ml15{
margin-left: 15px;
}
.ml50{
margin-left: 50px;
}
.ml4{
margin-left: 5px;
}
.ml80{
margin-left: 80px;
}
.mlr20{
margin: 0 20px;
}
.mtb20{
margin 20px 0
}
.pdtb10{
padding 10px 0
}
.pdtb5{
padding 5px 0
}
.pdlr10{
padding: 0 10px;
}
.pdlr20{
padding: 0 20px;
}
.pd10{
padding: 10px;
box-sizing: border-box;
}
.pad20{
padding: 20px;
box-sizing: border-box;
}
.pb10{
padding-bottom: 10px;
}
.pb20{
padding-bottom: 20px;
}
.pb15{
padding-bottom: 15px;
}
.pt10{
padding-top: 10px;
}
.vc{
text-align: center;
}
.vr{
text-align: right;
}
.vj{
text-align: justify;
}
.verm{
vertical-align: middle;
}
.pr{
position relative
}
.op8{
opacity 0.8
}
.op6{
opacity 0.6
}
.rad50{
border-radius: 50%;
}
.rad4{
border-radius: 4px;
}
.border{
border 1px solid #E6E6E6
}
.duration{
font-family: monospace;
}
.mono{
font-family: monospace;
}
.txt-red{
color #F56C6C
}
.txt-hot{
color: #D82E2A;
}
.txt-green{
color #67C23A
}
.txt-blue{
color #409eff
}
.txt-blue2{
color: #168fca;
}
.txt-yel{
color #FBB03B
}
.cs-hot2{
color #f00
}
.txt-primary{
color #409eff
margin 0 3px
}
.txt-price{
font-size 12px
color #C0C4CC
text-decoration line-through
}
.c-tag{
border: 1px solid #F56C6C;
border-radius: 2px;
color: #F56C6C;
text-align center
font-size 12px
line-height 20px
padding 0 5px
cursor pointer
&.f16{
font-size 16px
line-height 26px
}
}
.lh30{
line-height 30px
}
.emcs-bg{
background rgba(22,143,202,0.04)
padding-bottom: 1px;
}
.b-border-item{
padding: 15px 0;
box-sizing: border-box;
border-bottom: 1px solid #f5f5f5;
}
.border-t{
border-top: 1px solid #f5f5f5;
}
.com-image{
width 150px
min-width 150px
height 90px
border-radius 2px
background-repeat no-repeat
background-size cover
background-position center
}
.w100{
width: 100%
}
.w50{
width: 50%
}
.w24{
width: 24%;
}
.wd250{
width: 250px;
}
.wd200{
width: 200px;
}
.wd190{
width: 190px;
}
.wd150{
width: 150px;
}
.wd50{
width: 50px;
}
.wd40{
width: 40px;
min-width: 40px;
}
.maxw80{
max-width: 80px;
}
.maxw150{
max-width: 150px
}
.minw150{
min-width: 150px
}
.minh800{
min-height: 800px;
}
.cur-p{
cursor pointer
}
.bf7{
display: block;
background-color:#f7f7f7;
}
.bf{
background-color:#FFFFFF;
}
.bf7-hov:hover{
background-color:#f7f7f7;
}
.wd1200{
max-width: 1200px;
margin: 0 auto 20px;
}
.wd1000{
max-width: 1000px;
margin: 0 auto;
}
.emcs-line{
height 12px
line-height 12px
border-left 1px solid #E1E1E1
margin 0 20px
}
// 提交表单上的title
.emcs_form_title{
text-align: center;
margin-bottom: 20px;
font-size: 16px;
}
// 提交表单上传图片
.upload-box {
& > div {
display inline-block
vertical-align middle
}
.image-box {
width 100px
height 100px
margin-right 20px
background-size contain
background-position left center
background-repeat no-repeat
}
.upload-des {
margin 0
font-size:12px;
font-weight:400;
line-height:18px;
color #909399
}
.upload {
input[type='file'] {
display: none;
}
label {
width: 80px;
height: 24px;
font-size: 12px;
line-height: 24px;
display: inline-block;
border-radius: 4px;
text-align: center;
border: 1px solid #ddd;
cursor pointer
}
}
}
// 微信分享二维码样式
.wx_share_box{
text-align center
margin 10px 0
}
.wx_share_title{
font-size 12px
line-height 18px
text-align center
}
// 表格里背景图
.emcs_img{
width 100%
height 32px
background-repeat no-repeat
background-size contain
background-position left center
}
// 角色标签
.role_tag{
font-size 10px
line-height 20px
padding 0 5px
display inline-block
border-radius 3px
color #fff
&.user{
background #7CC1E3
}
&.pending{
background #7CC1E3
}
&.std{
background #D9D2C7
}
&.pro{
background #F2DC5F
}
&.master{
background #FF8E8E
}
&.dba{
background #4183D7
}
&.mvp{
background #F95F6A
}
&.sys{
background #725C5C
}
&.admin{
background #725C5C
}
}
// 表格容器
.emcs-table{
background: #FFFFFF;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.10);
padding: 20px;
box-sizing: border-box;
}
.emcs-b-shadow{
background: #FFFFFF;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.10);
box-sizing: border-box;
}
.shadow{
background: #FFFFFF;
box-shadow:0px 1px 5px 0px rgba(0, 0, 0, 0.1);
box-sizing: border-box;
}
// table样式(原,待删除)
.table_container {
background: #FFFFFF;
border: 1px solid #EBEEF5;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.10);
border-radius: 4px;
padding: 40px;
}
// 前台容器样式
.emcs-container{
background rgba(22,143,202,0.04)
padding-bottom 50px
}
.emcs-main-box{
max-width 1140px
margin 0 auto
box-sizing border-box
}
// 前台头部导航样式
.emcs-page-head{
max-width 1200px
margin 0 auto
padding 20px 0
display flex
justify-content space-between
align-items center
.breadcrumb{
margin-bottom 0
color #666666
white-space: nowrap
overflow hidden
text-overflow ellipsis
}
}
// 前台内容区布局
.emcs-page-content{
max-width 1200px
margin-left: auto;
margin-right: auto;
display flex
align-items flex-start
box-sizing border-box
& > .other-box{
width 275px
margin-left 10px
&.wd300{
width 300px
}
}
.main-box{
flex 1
width 0
max-width 915px
}
}
// 二级导航内容
.emcs-submenu{
height 48px
padding 10px 0
box-sizing: border-box;
background #ffffff
&.h28{
height 28px
padding 0
}
.submenu-item{
max-width 1200px
margin 0 auto
font-size 12px
line-height 28px
.active{
background #409eff
color #ffffff
}
& > div{
display inline-block
padding 0 15px
cursor pointer
margin-right 10px
color #409eff
background #ecf5ff
border-radius 15px
&:hover{
background #409eff
color #ffffff
}
}
}
}
// 前台分页不需要总数
.emcs-index-page{
text-align center
margin 20px 0
.btn-quicknext + .number{
display: none
}
}
// 搜索数据为空的情况
.searching{
display flex
align-items center
justify-content center
font-size 12px
color #909399
min-height 200px
width 100%
}
// 内容抬头样式
.h-comment{
margin 20px 0
padding-left 15px
position relative
padding-bottom 10px
border-bottom 1px solid #eaeeef
line-height 20px
&:before{
content " "
display block
position absolute
left 0
width 4px
height 20px
background #168fca
}
}
// 锚点
.anchor-dot{
height 0
position relative
top -60px
}
// 悬浮按钮
.suspen-box{
position: fixed;
right: 30px;
bottom: 70px;
z-index: 1000;
.suspen{
width 30px
height 30px
background #ffffff
box-shadow 0 2px 12px 0 rgba(0,0,0,.1)
border-radius 50%
display: flex;
align-items: center;
justify-content: center;
i{
font-size 16px
color #909399
}
}
}
// 个人中心链接样式
.emcs-user{
display inline-block
max-width 90px
overflow hidden
white-space nowrap
text-overflow ellipsis
color #333
&:hover{
cursor pointer
color #168fca
}
}
.emcs-name{
display inline-block
max-width 70px
overflow hidden
white-space nowrap
text-overflow ellipsis
}
.emcs-text-overflow{
overflow hidden
text-overflow ellipsis
word-break: break-all;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
&.clamp3{
-webkit-line-clamp: 3;
}
&.clamp5{
-webkit-line-clamp: 5;
}
&.clamp7{
-webkit-line-clamp: 7;
}
}
// 消息
.message-bellring{
display flex
align-items center
cursor pointer
.message-tip-dot{
background #f1403c
font-size 11px
line-height 1
padding 2px 4px
color: #ffffff;
margin-top: -15px;
margin-left: -8px;
border: 2px solid #fff;
border-radius: 20px;
}
}
// 查看更多
.fetch-more{
display block
padding 10px 0
font-size 14px
text-align center
color #168fca
cursor pointer
user-select: none
}
.btn-txt{
font-size 12px
color #168fca
cursor pointer
display inline-block
}
.emcs-search{
background #f9f9f9
padding 15px
display flex
align-items center
justify-content space-between
.left{
display flex
align-items center
flex-wrap wrap
.name{
font-weight 700
font-size 12px
}
.el-select{
width 120px
margin-right 5px
.el-input{
width 120px
}
}
.el-input{
width 180px
margin-right 5px
}
.filter-select{
width 180px
.el-input{
width 180px
}
}
}
.el-icon-search{
cursor pointer
}
}
i.encrypt{
color #f56c6c !important
font-size 18px !important
margin-right 5px
&.cs-PUBLIC{
margin-right 0
}
}
// 选项
.option-box{
font-size 13px
line-height 20px
color #909399
.option{
margin-bottom 10px
display flex
cursor pointer
.radio{
width 9px
min-width 9px
height 9px
border-radius 50%
border 1px solid #ddd
margin-right 10px
margin-top 5px
&.active{
background #409eff
position relative
&:after{
content ''
display inline-block
width 3px
height 3px
border-radius 50%
background #fff
position absolute
top 3px
left 3px
}
}
}
.checkbox{
width 12px
min-width 12px
height 12px
border 1px solid #ddd
margin-right 10px
margin-top 4px
&.active{
background-color: #409eff;
border-color: #409eff;
position relative
&:after{
box-sizing: content-box;
content: "";
border: 1px solid #fff;
border-left: 0;
border-top: 0;
height: 7px;
left: 4px;
position: absolute;
top: 1px;
transform: rotate(45deg) scaleY(1);
width: 3px;
transition: transform .15s ease-in .05s;
transform-origin: center;
}
}
}
}
}
.wx-share-box {
text-align center
color #909399
font-size 12px
& .title {
padding-bottom 5px
}
}
// 右侧panel
.emcs-panel{
margin-bottom 10px
background #ffffff
box-shadow 0 2px 12px 0 rgba(0,0,0,0.1)
font-size 12px
line-height 18px
&.bold{
.panel-title{
padding 20px 20px 0
border-bottom none
.title{
font-weight 400
font-size: 20px;
line-height: 20px
border-left: 3px solid #168fca;
}
}
}
.panel-title{
padding 10px 20px
border-bottom 1px solid #f2f6fc
display: flex;
align-items: center;
justify-content: space-between;
color: #999999
.title{
font-weight 700
padding-left: 10px;
line-height 14px
color #333
border-left: 2px solid #409EFF;
}
a, span{
cursor: pointer;
&:hover{
color: #409EFF;
}
}
}
.rank-filter{
color #909399
cursor pointer
font-size 12px
line-height 17px
span{
margin-left 5px
}
.active{
color #409EFF
}
}
}
.emcs-avatar{
width 30px
min-width 30px
height 30px
border-radius 50%
background-size cover
background-position center
}
/*webkit内核*/
.emcs-scroll::-webkit-scrollbar {
display: none;
}
/*IE10,IE11,IE12*/
.emcs-scroll {
-ms-overflow-style: none;
}
.topic-title{
display inline-block
font-size 12px
line-height 20px
background #D9F3FF
padding 0 11px
border-radius 10px
color #00A0E9
margin-top 10px
cursor pointer
}
/*webkit内核*/
.emcs-scroll::-webkit-scrollbar {
display: none;
}
/*IE10,IE11,IE12*/
.emcs-scroll {
-ms-overflow-style: none;
}
.emcs-nav-box{
background:rgba(255,255,255,1);
box-shadow:0px 1px 5px 0px rgba(0, 0, 0, 0.08);
height:36px;
font-size:16px;
color:#666666;
line-height:36px;
display flex
align-items center
margin-bottom 20px
.item{
width:104px;
text-align center
cursor pointer
}
.active{
color #168FCA
background:rgba(22,143,202,0.3);
}
}
.emcs-btn{
display: inline-block;
height:30px;
min-width 88px
padding 0 10px
box-sizing border-box
white-space nowrap
border:1px solid #409EFF;
border-radius:4px;
font-size:14px;
line-height:30px;
color:#409EFF;
text-align center
cursor pointer
&.bold{
background #409EFF
color #fff
border none
}
&.round{
border-radius 16px
}
&.disabled{
background #E6E6E6
border none
color #999999
cursor default
}
&.h28{
min-width: 50px;
height: 26px;
line-height: 26px;
}
}
// 关注btn
.f-btn{
display inline-block
min-width 40px
text-align center
font-size 12px
line-height 18px
padding 2px 5px
box-sizing border-box
color #168fca
border 1px solid #168fca
cursor pointer
&.red{
border 1px solid #f56c6c
color #f56c6c
}
&.disabled{
border-color #ddd
color #999999
}
}
// 右侧banner title
.emcs-banner-box{
padding:20px 0;
background:#fff;
box-shadow:0px 1px 5px 0px rgba(0, 0, 0, 0.16);
margin-bottom:10px;
}
.emcs-banner-title{
font-size:18px;
font-family:Microsoft YaHei;
line-height:18px;
border-left:4px solid #168fca
padding-left:10px;
margin-left:10px;
}
// wiki icon
.wiki-icon{
background:rgba(22,143,202,.5);
border-radius:2px;
width 30px
height 30px
display flex
align-items center
justify-content center
font-size:20px;
font-weight:bold;
color:#fff;
}
.flex {
display flex
align-items center
}
.between{
justify-content space-between
}
.center{
justify-content center
}
.end{
justify-content: flex-end;
}
.flex-st{
display: flex;
align-items: flex-start;
}
.flex-se{
display: flex;
align-items: flex-end;
}
.column{
flex-direction: column;
}
.wrap{
flex-wrap: wrap;
}
.emcs-expand{
flex 1
width 100px
}
.block{
display: block;
}
.inl-block{
display: inline-block;
}
.hide{
display: none;
}
// 过滤
.filter-box{
display flex
align-items center
padding-bottom 10px
border-bottom 1px solid #f2f6fc
font-size 14px
line-height 20px
.filter-item{
margin-right 15px
cursor pointer
padding-bottom 5px
&.active, &:hover{
color #168fca
border-bottom 1px solid #168fca
}
}
}