美文网首页让前端飞
CSS架构及Scss简单入门

CSS架构及Scss简单入门

作者: 蓝海00 | 来源:发表于2022-03-03 17:30 被阅读0次

    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;
            }
         -->
    
    • 面向对象开发
      vue中的组件 == oocss
      页面中引入同一个组件多次,可以为每个组件新增不同的class,来实现每个组件的样式区别
    3.1.2 总结

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

    3.2 BEM

    • B
      Block-
    • E
      元素 Element__
    • M
      修饰 Modifier--
    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
    • 对浏览器的默认样式进行重置
      normalize.css
      CSS Tools

    这里的样式只会对标签元素本身做设定,不会出现任何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 命名规范

    如:

    • Layout
      .l-header
      .l-layout-header
    • Module
      .todoList
      .todoList-title
      .todoList-img
    • State
      .is-hidden
      .is-active
    • Theme
      .theme-nav
      .theme-header
    3.3.3 总结

    易维护、易复用、易扩展

    3.4 ITCSS

    3.4.1 分层
    3.4.1.1 Settings
    • 包含字体、颜色定义等,通常定义可以自定义模版的变量
    3.4.1.2 Tools
    • mixinfunction 主要结合预处理器使用
    3.4.1.3 Generic
    • 对浏览器的默认样式进行重置
      normalize.css
      CSS Tools
    3.4.1.4 Elements/Base
    • 定义网站HTML元素的样式
    3.4.1.5 Objects
    • 类名样式中,不允许出现外观属性,例如: Color
    3.4.1.6 Components
    • UI组件
    3.4.1.7 Trumps/Utilities
    • 实用程序和辅助类,能够覆盖三角形中的任何层,唯一写important!的地方
    3.4.2 与SMCSS的区别

    层次分得更细

    3.5 ACSS

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

    3.5.1 好处
    • 极强的复用性、维护成本低
    3.5.2 坏处
    • 破坏了css命名的语义化

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

    四、整合设计模式

    4.1 Settings层代码实现

    • 定义一些公共的变量(某个样式经常出现)
    • 颜色、边框、文字大小、阴影、层级......
    • var.scss
    /* 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中全局引入
    // 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文件夹内
    • functions
    • minxins
    • _sassMagic.scss
      注意:需要根据启动项目的提示去掉functions和minxins中未存在且在_sassMagic.scss中引入的文件
    // 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层
    • 引入normalize.css ,重置浏览器默认样式

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

    4.2.2 Base层

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

    • article.scss
    • form.scss
    • images.scss
    • link.scss
    • page.scss
    • ...
      统一导入在一个scss文件中,然后再main.js中引入

    4.3 Components层代码实现

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

    配置按需使用vant

    • 在components下进行配置(新建index.js)
    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
    
    • 在main.js中引入
    import mgjUI from '@/components/index.js'
    createApp(App).use(mgjUI)
    
    • 使用
      这里的 c-row、c-col 是在 index.js 中进行了修改名称
        <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

    • 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>
    
    • header
    <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>
    
    • content
    <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>
    
    • aside
    <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>
    
    • footer
    <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>
    
    • 引入(统计新增index.js)
    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
    }
    
    • 优化components下的index.js
    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层代码实现

    参考代码

    • 让样式极限复用
    • 解决Acss无语义化缺点:属性选择器
    <div class="c-layout" fl p10></div>
    [fl]{
      float: left;
    }
    [p10]{
      padding:10px;
    }
    
    • Settings 与 Acss 层的关系
      大多数基于settings中的var.scss中进行属性选择器的封装

    4.5 Theme层代码实现

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

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

    4.6.1 在vue.config.js中引入
    • 相当于在任何scss和vue(style)的文件内都引入了配置的scss
    • 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>
    
    • 变量、minxins、function...
    4.6.2 在main.js中引入

    纯样式

    五、响应式布局

    5.1 什么是响应式布局

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

    5.2 方案

    5.2.1 REM
    • 安装 npm install lib-flexible
      main.js中导入
    import 'lib-flexible/flexible.js'
    
    • 安装 npm install postcss-plugin-px2rem -D
      配置 vue.config.js
    module.exports = {
        css: {
            loaderOptions: {
                postcss: {
                    plugins: [
                        require('postcss-plugin-px2rem')({
                            rootValue: 37.5,
                            exclude: /(node_module)/,
                            minPixelValue: 3,
                            selectorBlackList: ['van']
                        })
                    ]
                },
            }
        }
    }
    
    • 正常编写css即可,不需要转换为rem的可以将px单位首字母大写Px
    5.2.2 VW
    5.2.3 REM+VW

    六、SvgIcon多色图标

    6.1 有什么优势?

    • Svg 支持多色图标
    • Svg 可以控制图标不同部分、加入动画
    • Svg 是矢量图标、图标锐利、体积更小

    6.2 IconPark

    链接

    • install
      npm install @icon-park/vue-next --save
    • 使用
    <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: 5px; => border-radius: 5px 5px 5px 5px / 5px 5px 5px 5px;
    • 奇对奇补齐、偶对偶补齐
      border-radius: 5px 10px;=>border-radius: 5px 10px 5px 10px / 5px 10px 5px 10px;
      border-radius: 5px 10px 15px;=>border-radius: 5px 10px 15px 10px / 5px 10px 15px 10px;
    • 百分比

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

    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的区别

    • 文件扩展名不同
      sass是以.sass后缀为扩展名
      scss是以.scss后缀为扩展名
    • 语法不同
      sass是以严格的缩进式语法规则来书
      scss的语法以css语法非常相似

    10.2 特色功能

    • 完全兼容css3
    • 在css基础上增加了
      变量(variables)
      嵌套(nesting)
      混合(mixins)
    • 通过函数进行颜色值与属性值的运算
    • 提供控制指令等高级功能
    • 自定义输出形式

    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 数据类型
    • 数字
      1,2,13,10px
    • 字符串
      "foo","bus","bar"
      foo,bus,bar

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

    @mixin homePage($name) {
      .home #{$name} {
        font: {
          size: 40px;
        }
      }
    }
    @include homePage(".home-red-new");
    // ==
    .home .home-red-new {
        font-size: 40px;
    }
    
    • 颜色
      blue,#ff000,rgba(255,255,255,0)
    • 布尔值
      true,false
    • 空值
      null
    • 数组
      1em 0 2em 10em
      1em,Arial,Hellow

    用空格或逗号作分隔符

    • maps
      (key1: value1, key2: value2)

    相当于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=?";
      }
    }
    
    • 支持布尔 and or not
    • 数组不支持任何运算方式,只能使用 list functions 控制
    • 所有的数据类型均支持相等运算 == 或 !==
    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

    相关文章

      网友评论

        本文标题:CSS架构及Scss简单入门

        本文链接:https://www.haomeiwen.com/subject/kqfurrtx.html