Windi CSS 边框工具类:圆角、宽度、颜色与样式
Windi CSS(和 Tailwind 同一套原子类思路)把边框拆成了五个互相独立的维度:圆角、宽度、颜色、透明度、线型。要画出一个可见的边框,至少得同时给出宽度和颜色——只写 border-red-500 是看不到边框的,因为宽度默认为 0;反过来只写 border-10 会用默认颜色(通常是 currentColor)。这是刚上手最容易卡住的地方。
下面按维度列出常用类名,最后用一个组件把它们渲染出来对比效果。Windi 是按需生成的——扫描源码里出现过的类名再生成对应 CSS,所以类名必须以完整字符串出现在代码里,动态拼接('border-' + n)扫不到,生成不出样式。
border-radius
圆角。rounded-none 是 0,rounded-10px 直接写具体值,rounded-[50%] 是任意值语法——方括号里可以塞任何合法的 CSS 值,用来处理预设档位覆盖不到的情况,50% 配合正方形就是一个圆。
['rounded-[50%]', 'rounded-10px', 'rounded-none']
border-width
边框宽度,数字即像素值。想只改单边就加方位后缀:border-t-10(上)、border-b/l/r-10 对应下左右,border-x-10 / border-y-10 分别是左右和上下。
['border-10', 'border-20', 'border-30']
border-color
颜色。gray-500 这种是「色系-深浅」的格式,数字越大越深,范围 50 到 900。border-transparent 是透明——它和不设边框不一样,边框依然占位撑开尺寸,只是看不见,常用来做「hover 时才显示边框但布局不跳动」的效果。
['border-transparent', 'border-gray-500', 'border-pink-500']
border-opacity
边框透明度,0 到 100。它只作用于边框颜色,不影响元素内容——和 opacity 是两回事,后者会把整个元素(含子节点)一起变透明。实现上是通过 CSS 变量参与边框颜色的 alpha 计算,所以必须配合 border-<color> 使用,单独写不生效。
['border-opacity-0', 'border-opacity-50', 'border-opacity-100']
border-style
线型。默认是实线,所以 border-solid 一般可以省。border-double 是双线,需要宽度足够大(至少 3px)才看得出两条线。border-none 会把 border-style 设成 none,效果上等于连宽度一起清掉。
['border-solid', 'border-dashed', 'border-dotted', 'border-double', 'border-none']
示例
把上面五组类名放进 borderCfg,双层 v-for 渲染成网格,每个方块上直接把自己的类名显示出来,效果和写法一一对照。
注意 colorArrs、opacityArrs、typeArrs 这三组里每一项都额外拼上了 border-10(透明度那组还带了 border-blue-500)——这正好印证前面说的:颜色、透明度、线型都得有宽度才看得见,缺了宽度整行都是空白。
baseClass 是各方块共用的基础样式:固定 150px 见方,leading-150px 让行高等于高度实现单行垂直居中,whitespace-nowrap 防止类名文字换行撑变形。类名全部以完整字符串写死在 ref 里,这样 Windi 扫描源码时能识别到并生成对应的 CSS。
<template>
<div class="flex justify-around align-middle flex-wrap bg-black">
<div
v-for="(value, index) in borderCfg"
:key="index"
class="flex align-middle justify-between w-screen mt-10px"
>
<div
v-for="(item, subIndex) in value"
:key="subIndex"
:style="{ width: 100 / value.length + '%' }"
>
<div :class="[baseClass, item]">{{ item }}</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const baseClass = ref(
'w-150px h-150px leading-150px bg-red-500 m-auto text-white whitespace-nowrap',
);
const borderCfg = ref({
roundedArrs: ['rounded-[50%]', 'rounded-10px', 'rounded-none'],
widthArrs: ['border-10', 'border-20', 'border-30'],
colorArrs: [
'border-transparent border-10',
'border-gray-500 border-10',
'border-pink-500 border-10',
],
opacityArrs: [
'border-opacity-0 border-blue-500 border-10',
'border-opacity-50 border-blue-500 border-10',
'border-opacity-100 border-blue-500 border-10',
],
typeArrs: [
'border-solid border-blue-500 border-10',
'border-dashed border-blue-500 border-10',
'border-dotted border-blue-500 border-10',
'border-double border-blue-500 border-10',
'border-none border-blue-500 border-10',
],
});
</script>

还没有留言,来发表第一条吧~