让前端飞

CSS架构及Scss简单入门

2022-03-03  本文已影响0人  蓝海00

github项目地址

一、架构的重要性

二、为什么要做CSS架构

日益膨胀的CSS代码,无计可施
项目长期处于无CSS架构维护状态

css代码极度混乱
css难复用、难扩展、难维护

掌握各种CSS设计模式、解决难复用、难扩展等问题
搭建企业级css结构、解决代码混乱问题

三、CSS设计模式

3.1 OOCSS

oo 面向对象

3.1.1 原则
    <!-- 容器与内容分离 -->
    <!-- post中的meta-data -->
    <div class="post">
        <p class="metadata"><span>AAA</span><span>2022-01-01</span></p>
    </div>
    <!-- comment中的meta-data -->
    <div class="comment">
        <p class="metadata"><span>AAA</span><span>2022-01-01</span></p>
    </div>
    <!-- 
        内容在不同容器中的展示是一致的 这样写css 会导致metadata不能进行复用
        .post .metadata{ css code }
        .comment .metadata{ css code } 
        优化成 => 容器写容器的代码 内容写内容的代码
        .post {css code }
        .comment {css code }
        .metadata{ css code }
    -->
    <!-- 结构(基础对象)与皮肤分离 -->
    <div class="menu fix fix1"></div>
    <!-- 
        不用修改基础对象 可以多次新增多个皮肤对象进行修改
        .menu{
            color: green;
            font-size: 14px;
        }
        .fix{
            color: red;
        }
        .fix1{
            font-size: 24px;
        }
     -->
3.1.2 总结

追求元件的复用,其class命名更为抽象,一般不体现具体的事物,而注重表现层的抽取

3.2 BEM

3.2.1 作用

命名规范、让页面结构清晰,进阶版的OOCSS

    <!-- BEM -->
    <div class="menu">
        <div class="menu__table menu__tab--style1">tab1</div>
        <div class="menu__table menu__tab--style2">tab2</div>
        <div class="menu__table menu__tab--style3">tab3</div>
        <div class="menu__table menu__tab--style4">tab4</div>
    </div>

3.3 SMACSS

官网链接

3.3.1 分层
3.3.1.1 Base

这里的样式只会对标签元素本身做设定,不会出现任何classid,但是可以有属性选择器或是伪类

3.3.1.2 Layout

元素是有层级级别之分的,Layout属于较高的一层,可以作为层级较低的如:Module元素的容器

3.3.1.3 Module
3.3.1.4 State

任意元素在特定状态下的外观,如信息框可能有successerror等状态

3.3.1.5 Theme

不要求使用单独的class命名,如可以在Module中定义.header,在Theme中也定义.header来切换样式(换肤),后加载覆盖前加载的样式

3.3.2 命名规范

如:

3.3.3 总结

易维护、易复用、易扩展

3.4 ITCSS

3.4.1 分层
3.4.1.1 Settings
3.4.1.2 Tools
3.4.1.3 Generic
3.4.1.4 Elements/Base
3.4.1.5 Objects
3.4.1.6 Components
3.4.1.7 Trumps/Utilities
3.4.2 与SMCSS的区别

层次分得更细

3.5 ACSS

一个样式属性一个类
TailWind 框架

3.5.1 好处
3.5.2 坏处

结合多个设计模式总结的常用层

四、整合设计模式

4.1 Settings层代码实现

/* Color */
// 基础颜色 不区分类别 服务于其他类型的所有颜色
$color-primary: #ff5777;
$color-white: #fff;
$color-black: #000;

// 字体颜色
$color-text-primary: #333;
$color-text-secondary: #666;
$color-text-tertiary: $color-white;
$color-text-quaternary: $color-primary;

// 边框颜色
$border-color-base: #e5e5d5;

// 背景颜色
$background-color-primary: #f1f1f1;
$background-color-secondary: $color-white;
$background-color-tertiary: $color-primary;

/* Border */
$border-width-base: 1px !default;
$border-style-base: solid !default;
$border-base: $border-width-base $border-style-base $border-color-base !default;
// vue.config.js
module.exports = {
    css: {
        loaderOptions: {
            // @/ 是 src/ 的别名
            // 注意:在 sass-loader v8 中,这个选项名是 "prependData"
            scss: {
                additionalData: `@import "@/style/settings/var.scss";`
            },
        }
    }
}

4.1 Tools层代码实现

4.1.1 SassMagic工具库

git
文档

4.1.1.1 直接在github下载至本地
4.1.1.2 将src内的文件复制进自己项目的tools文件夹内
// Import Functions
@import "functions/_amcss.scss";
// @import "functions/_calc-percent.scss";
@import "functions/_convert.scss";
@import "functions/_decimal.scss";
@import "functions/_exponent.scss";
@import "functions/_leastSquaresFit.scss";
@import "functions/_linear-interpolation.scss";
@import "functions/_list-remove.scss";
@import "functions/_list-sort.scss";
@import "functions/_map-sort.scss";
@import "functions/_number.scss";
@import "functions/_polygon.scss";
@import "functions/_strip-units.scss";
@import "functions/_unit-length.scss";
@import "functions/_z-index.scss";

// Import Mixins
// @import "mixins/_alerts.scss";
@import "mixins/_amcss.scss";
@import "mixins/_angled-edges.scss";
@import "mixins/_animation.scss";
@import "mixins/_BEM.scss";
@import "mixins/_box-center.scss";
@import "mixins/_box-clamp.scss";
@import "mixins/_burger.scss";
// @import "mixins/_buttons.scss";
@import "mixins/_calc.scss";
@import "mixins/_caret.scss";
@import "mixins/_corners.scss";
@import "mixins/_equal-parts.scss";
@import "mixins/_fade-text.scss";
@import "mixins/_flex-grid.scss";
@import "mixins/_fluid-ratio.scss";
@import "mixins/_full-width.scss";
@import "mixins/_geometric-size.scss";
// @import "mixins/_gradient.scss";
@import "mixins/_haslines.scss";
@import "mixins/_HolyGrail-layout.scss";
@import "mixins/_media-queries.scss";
@import "mixins/_open-color.scss";
@import "mixins/_palettetown.scss";
@import "mixins/_plumber-box.scss";
@import "mixins/_plumber.scss";
@import "mixins/_poly-fluid-sizing.scss";
@import "mixins/_polygon.scss";
@import "mixins/_position.scss";
// @import "mixins/_resize.scss";
// @import "mixins/_ribbon.scss";
@import "mixins/_scrollbars.scss";
@import "mixins/_selector.scss";
@import "mixins/_sprite-spirit.scss";
@import "mixins/_sticky-footer.scss";
@import "mixins/_tilted.scss";
// @import "mixins/_triangle.scss";
@import "mixins/_typographic.scss";
// @import "mixins/_visuallyhidden.scss";
4.1.1.3 全局导入_sassMagic.scss
// vue.config.js
module.exports = {
    css: {
        loaderOptions: {
            // @/ 是 src/ 的别名
            // 注意:在 sass-loader v8 中,这个选项名是 "prependData"
            scss: {
                additionalData: `@import "@/style/tools/_sassMagic.scss";`
            },
        }
    }
}
4.1.1.4 可以对SassMagic瘦身,根据项目定制化需要的功能

4.2 Base层代码实现

4.2.1 Generic层

npm install --save normalize.css
main.js => import "normalize.css/normalize.css"

4.2.2 Base层

对各类元素基础样式进行补充根据当前自己的项目进行设计

4.3 Components层代码实现

4.3.1 OOCSS => BEM (进阶版 OOCSS)
4.3.2 经典组件
4.3.2.1 栅格组件

配置按需使用vant

import {
    Col,
    Row
} from 'vant';

const components = {
    CCol: Col,
    CRow: Row
}

const install = (app) => {
    Object.keys(components).forEach(key => {
        app.component(key, components[key])
    });
}

const mgjUI = {
    install
}

export default mgjUI
import mgjUI from '@/components/index.js'
createApp(App).use(mgjUI)
    <c-row>
      <c-col span="8">span: 8</c-col>
      <c-col span="8">span: 8</c-col>
      <c-col span="8">span: 8</c-col>
    </c-row>
4.3.2.2 布局组件

按照BEM的规范
component => layout

<template>
  <section class="c-layout" :class="{ 'c-layout--horizontal': horizontal }">
    <slot></slot>
  </section>
</template>

<script>
export default {
  name: "CLayout",
  props: {
    horizontal: {
      type: Boolean,
      default: false
    }
  }
}
</script>

<style lang="scss">
@include b(c-layout) {
  display: flex;
  flex-direction: column;
  @include m(horizontal) {
    flex-direction: row;
  }
}
</style>
<template>
  <header class="c-header" :class="fixed && 'c-header--fixed'">
    <slot></slot>
  </header>
</template>

<script>
export default {
  name: "CHeader",
  props: {
    fixed: {
      type: Boolean,
      default: false
    }
  }
}
</script>

<style lang="scss">
@include b(c-header) {
  @include m(fixed) {
    position: fixed;
    top: 0;
    width: 100%;
    z-index: 10;
  }
}
</style>
<template>
  <main class="c-content"><slot></slot></main>
</template>

<script>
export default {
  name: "CContent"
}
</script>

<style lang="scss">
@include b(c-content) {
  overflow: auto;
  flex: 1;
}
</style>
<template>
  <div class="c-aside">
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: "CAside"
}
</script>

<style lang="scss">
@include b(c-aside) {
  overflow: auto;
  flex-shrink: 0;
}
</style>
<template>
  <footer class="c-footer">
    <slot></slot>
  </footer>
</template>

<script>
export default {
  name: "cFooter"
}
</script>

<style lang="scss">
@include b(c-footer) {
  position: fixed;
  bottom: 0;
  width: 100%;
  z-index: 10;
}
</style>
import Layout from "./layout.vue"
import Header from "./header.vue"
import Content from "./content.vue"
import Footer from "./footer.vue"
import Aside from "./aside.vue"

export {
    Layout,
    Header,
    Content,
    Footer,
    Aside
}
import {
    Col,
    Row
} from 'vant';
import {
    Layout,
    Header,
    Content,
    Footer,
    Aside
} from './layout';

const components = {
    CCol: Col,
    CRow: Row,
    Layout,
    Header,
    Content,
    Footer,
    Aside
}

const install = (app) => {
    Object.keys(components).forEach(key => {
        // 使用第三方组件
        if (key === 'CRow' || key === 'CCol') {
            app.component(key, components[key])
        } else {
            // 第一个参数获取当前vue中的name 赋值给组件的key
            app.component(components[key]['name'], components[key])
        }
    });
}

const mgjUI = {
    install
}

export default mgjUI
<template>
  <!-- <c-layout class="home__layout">
    <c-header style="background: #ff5777">header</c-header>
    <c-content style="background: #ff0">
      <div style="height: 2000px">123123</div>
    </c-content>
    <c-footer style="background: #666">footer</c-footer>
  </c-layout> -->
  <c-layout horizontal class="home__layout">
    <c-aside style="background: #ff5777">123</c-aside>
    <c-content style="background: #ff0">
      <div style="height: 2000px">123123</div>
    </c-content>
  </c-layout>
</template>

<script>
export default {
  name: 'Home'
}
</script>

<style lang="scss">
@include b(home) {
  @include e(layout) {
    height: 100vh;
  }
}
</style>
4.3.3 自定义组件

4.4 Acss层代码实现

参考代码

<div class="c-layout" fl p10></div>
[fl]{
  float: left;
}
[p10]{
  padding:10px;
}

4.5 Theme层代码实现

在html标签上新增一个属性,然后通过js改变这个属性实现换肤功能,(在属性下针对页面的class进行颜色大小等元素的修改即可)

4.6 两种不同的引入方式的区别

4.6.1 在vue.config.js中引入
module.exports = {
    css: {
        loaderOptions: {
            scss: {
                prependData: `
                @import "@/style/settings/var.scss";
                @import "@/style/tools/_sassMagic.scss";
                `
            },
        }
    }
}

xxx.scss

@import "@/style/settings/var.scss";
@import "@/style/tools/_sassMagic.scss";
.a{}

xxx.vue

<style lang="scss">
@import "@/style/settings/var.scss";
@import "@/style/tools/_sassMagic.scss";
.a{}
</style>
4.6.2 在main.js中引入

纯样式

五、响应式布局

5.1 什么是响应式布局

网页的元素会随着屏幕大小的变化而变化

5.2 方案

5.2.1 REM
import 'lib-flexible/flexible.js'
module.exports = {
    css: {
        loaderOptions: {
            postcss: {
                plugins: [
                    require('postcss-plugin-px2rem')({
                        rootValue: 37.5,
                        exclude: /(node_module)/,
                        minPixelValue: 3,
                        selectorBlackList: ['van']
                    })
                ]
            },
        }
    }
}
5.2.2 VW
5.2.3 REM+VW

六、SvgIcon多色图标

6.1 有什么优势?

6.2 IconPark

链接

<template>
<home theme="filled"/>
</template>
<script>
import {Home} from '@icon-park/vue-next';
export default {
  components: {
    Home
  }
}
</script>

七、Css中文字体压缩: 字蛛(font-spider)

链接

八、Css Scroll Snap 优化滚动(移动端)

链接

九、border-radius 原理及实现复杂图形

9.1 水平上的半径 / 垂直上的半径

9.2 简写

先补齐,相当于盒子的宽度和高度来计算

border-radius: 10%; 假设:width = 600px ; height = 300px;
=>
border-radius: 10% 10% 10% 10% / 10% 10% 10% 10%;
border-radius: 60px 60px 60px 60px / 30px 30px 30px 30px;

9.3 示例

十、Scss

10.1 Sacc和Scss的区别

10.2 特色功能

10.3 css功能扩展

10.3.1 嵌套规则
.home {
  height: 100px;
  .redbox {
    background-color: red;
  }
}
10.3.2 父类选择器
.home {
  height: 100px;
  background: #000;
  &:hover {
    height: 200px;
  }
}

扩展

.home {
  height: 100px;
  background: #000;
  &-red {
    color: red;
  }
}
// ==
.home {
  height: 100px;
  background: #000;
}
.home-red {
  color: red;
}
10.3.3 属性嵌套
.home {
  height: 100px;
  background: #000;
  color: red;
  font: {
    size: 24px;
    weight: 400;
  }
}
// ==
.home {
  height: 100px;
  background: #000;
  color: red;
  font-size: 24px;
  font-weight: 400;
}
10.3.4 变量
.home {
  height: 100px;
  background: #000;
  &-red {
    $homeColor: red !global;
    color: $homeColor;
  }
  &-red-new {
    color: $homeColor;
  }
}

!global 将局部变量转换为当前页面的全局变量

10.3.5 数据类型

有引号字符串与无引号字符串
在编译css文件时不会改变其类型
使用 #{} 时除外,有引号字符串将被编译为无引号字符串,这样便于mixin中引用选择器名

@mixin homePage($name) {
  .home #{$name} {
    font: {
      size: 40px;
    }
  }
}
@include homePage(".home-red-new");
// ==
.home .home-red-new {
    font-size: 40px;
}

用空格或逗号作分隔符

相当于javascript的 object

10.3.6 运算
10.3.6.1 数字运算
$home-width: 600px;
.home {
  height: 100px + 1px;
  width: 100px - 50px;
  width: 200px * 2;
  width: (300px/2);
  width: $home-width/2;
}

“除”需要用括号包裹或者直接用变量相除

10.3.6.2 颜色值运算
10.3.6.3 字符串运算
.home {
  &::before {
    content: "Foo " + Bar;
    font: {
      family: sans- + "serif";
    }
  }
}
.home::before {
    content: "Foo Bar";
    font-family: sans-serif;
}
.home {
  margin: 100px + 3px auto;
}
.home {
  &::before {
    content: "1+1= #{1+1}";
  }
  &::before {
    content: "1+1= 2";
  }
}
.home {
  &::before {
    content: "1+1=#{$value}?";
  }
  &::before {
    content: "1+1=?";
  }
}
10.3.6.4 圆括号
.home {
  height: 100px * (1+1);
}
// ==
.home {
  height: 200px;
}
10.3.7 函数
@function grid-width($n) {
  @return $n * 100px;
}
.home {
  width: grid-width(4);
}
10.3.7.1 关键词参数
@mixin bordered($color, $width: 2px) {
  border: $width solid $color;
}
.home {
  @include bordered($width: 10px, $color: red);
}
10.3.7.2 变量参数
@mixin bordered($color, $width: 2px) {
  border: $width solid $color;
}
$colorValues: 10px yellow;
.home {
  @include bordered($colorValues...);
}

十一、XMind

css架构.png
上一篇下一篇

猜你喜欢

热点阅读