Unocss 写 border太费劲?试试这样

在css中, border 是高频使用的一个属性,但它的写法有非常非常多。

按属性分类,border 属性可以分为以下几类:

  • border-width:设置边框的宽度。
  • border-style:设置边框的样式。
  • border-color:设置边框的颜色。

按方向分类,border 属性可以分为以下几类:

  • border-top:设置上边框的宽度、样式和颜色。
  • border-right:设置右边框的宽度、样式和颜色。
  • border-bottom:设置下边框的宽度、样式和颜色。
  • border-left:设置左边框的宽度、样式和颜色。

一般情况下我们会直接使用 border 属性,它是一个简写属性,可以同时设置边框的宽度、样式和颜色。

css 复制代码
div {
  border: 1px solid red;
}

如果我们要单独设置某个方向边框的某个属性,可以使用以下属性:

  • border-top-width:设置上边框的宽度。
  • border-top-style:设置上边框的样式。
  • border-top-color:设置上边框的颜色。
css 复制代码
div {
  border-top-width: 1px;
  border-top-style: solid;
  border-top-color: red;
}

我们也可以单独设置某个方向的边框宽度、样式和颜色,可以使用以下属性:

  • border-top:设置上边框的宽度、样式和颜色。
  • border-right:设置右边框的宽度、样式和颜色。
  • border-bottom:设置下边框的宽度、样式和颜色。
  • border-left:设置左边框的宽度、样式和颜色。
css 复制代码
div {
  border-top: 1px solid red;
}

以上的写法,最常用的还是简写方式,如:

  • 简写属性:border: 1px solid red;
  • 单个方向的属性:border-top: 1px solid red;

在 unocss 中,我们怎么写边框呢?

可以使用 border 的预设,比如:

html 复制代码
<!-- border-width: 1px; -->
<div class="b"></div>

<!-- border-width: 2px; -->
<div class="b-2px"></div>

<!-- border-width: 2px; border-style: solid;-->
<div class="b b-solid"></div>

<!-- border-width: 1px; border-color: red; -->
<div class="b b-red"></div>

<!-- border-width: 1px; border-color: red; border-style: dashed; -->
<div class="b b-dashed b-red"></div>

为什么只设置 boder-width: 1px; 也能看到边框效果呢?这是因为浏览器为每个元素都设置了一个默认的边框样式,只是 boder-width 的默认值是 0px,所以最少只需要设置 border-width 就能看到边框效果

当然 unocss 预设中边框的写法也可以单独定义每个方向的宽度、样式和颜色,比如

html 复制代码
<!-- border-left-width: 1px; 效果:只有左边边框 -->
<div class="b-l"></div>

<!-- border-width: 1px; border-left-style: dashed; 效果:四边边框,左边边框 dashed -->
<div class="b b-l-dashed"></div>

<!-- border-width: 1px; border-left-color: red; 效果:四边边框,左边边框为红色 -->
<div class="b b-l-red"></div>

<!-- border-width-left: 2px; border-left-color: red; border-left-style: dashed; 效果:只有左边 2px red dashed 的边框 -->
<div class="b-l-2px b-l-red b-l-dashed"></div>

由上可知 unocss 的 border 预设其实就是将 border-width 、 border-style 和 border-color 分别定义,然后又可以各自组合上 left、right、top 和 bottom,这样就可以控制每一个方向的边框

这样写当然没什么问题,也非常的灵活,但仔细想想是不是过于麻烦了呢,为什么会觉得麻烦呢?原因就是这样写没有利用到 border 的简写方式,比如 左边 2px red dashed 的边框 我们其实是可以简写成这样的:

css 复制代码
div {
  border-left: 2px dashed red;
}

甚至我们写行内样式也比 b-l-2px b-l-red b-l-dashed 这种写法更简洁易懂

html 复制代码
<div style="border-left: 2px dashed red;"></div>

那么,有没有办法不写 css 也能做到这么简洁呢,并且还不能损失它的灵活性

当然有,答案就是自定义rules

js 复制代码
// unocss配置文件, uno.config.js|ts

import { defineConfig, presetUno } from 'unocss'
const DIRECTION_MAPPIINGS = { t: 'top', r: 'right', b: 'bottom', l: 'left' }

export default defineConfig({
  presets: [
    presetUno,
  ],
  rules: [
    [
      /^b(t|r|b|l|d)-(.*)/,
      ([, d, c]) => {
        const direction = DIRECTION_MAPPIINGS[d] || ''
        const p = direction ? `border-${direction}` : 'border'
        const attrs = c.split('_')
        if (
          // 属性中不包含 border-style 则默认 solid
          !attrs.some((item) =>
            /^(none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset)$/.test(item),
          )
        ) {
          attrs.push('solid')
        }
        // 属性中不包含 border-width 则默认 1px
        if (!attrs.some((item) => /^\d/.test(item))) {
          attrs.push('1px')
        }
        return {
          [p]: attrs.join(' '),
        }
      },
    ],
  ],
})

怎么用呢?

  1. 完整的写法
html 复制代码
<!-- border: 2px dashed red; -->
<div class="bd-2px_dashed_red"></div>
<!-- border-left: 2px dashed red; -->
<div class="bl-2px_dashed_red"></div>
<!-- border-right: 2px dashed red; -->
<div class="br-2px_dashed_red"></div>
  1. 缺省的写法

border-width 、 border-style 和 border-color 都可以缺省(但最少写一个),border-style 默认 solid,border-width 默认 1px,border-color 默认继承父容器的 color

html 复制代码
<!-- border: 2px solid; border-color 继承父容器的 color-->
<div class="bd-2px"></div>

<!-- border: red solid 1px; -->
<div class="bd-red"></div>

<!-- border: dashed 1px; border-color 继承父容器的 color-->
<div class="bd-dashed"></div>

<!-- border-left: 2px solid; border-color 继承父容器的 color-->
<div class="bl-2px"></div>

<!-- border-left: red solid 1px; -->
<div class="bl-red"></div>

<!-- border-left: dashed 1px; border-color 继承父容器的 color-->
<div class="bl-dashed"></div>

<!-- border-left: 2px solid; border-color 继承父容器的 color-->
<div class="bl-2px"></div>

<!-- border-left: red solid 1px; -->
<div class="bl-red"></div>

<!-- border-left: dashed 1px; border-color 继承父容器的 color-->
<div class="bl-dashed"></div>

可以看出这种写法是不是更简洁、更容易理解呢!

为什么 border-width 、 border-style 和 border-color 最少得写一个,全部缺省不是更好吗?

答: unocss 的默认写法就是可以全缺省的,没必要多此一举了,如 b b-r b-l b-t b-b

为什么用 bd 表示 border 而不用 b?

主要是为了跟 unocss 的默认写法区分开来,其次 bd 也勉强符合 border 语义的简写。

以上就是本篇文章分享的所有内容了,希望对大家有帮助。


关注我,大脸怪将持续分享更多实用知识和技巧

相关推荐
y先森2 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy2 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189112 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿3 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡4 小时前
commitlint校验git提交信息
前端
虾球xz5 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇5 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒5 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员5 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐5 小时前
前端图像处理(一)
前端