找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

3760

积分

0

好友

489

主题
发表于 1 小时前 | 查看: 2| 回复: 0

大家平时在写一些简单的网页,或者搞个小的开源项目 Demo 时,最头疼的是什么?我相信很多人都会脱口而出:写 CSS 样式。

既要考虑布局,又要设计配色,还得保证响应式,一套写下来常常让人筋疲力尽。最近我在 GitHub 上发现了一个开源项目 Oat UI,它让我重新找回了用原生 HTML 写页面的快乐。

这是一个超级轻量级的前端 UI 库,目前已经在 GitHub 上收获了 4.5k+ Star。它的理念简单直接:你只需要写标准的原生 HTML,引入它的库,页面就能自动拥有统一、美观的样式,完全不需要复杂的工程化配置。

Oat UI 在 GitHub 上的仓库页面截图

Oat UI 是什么?

Oat UI 是一个 “无类”(Classless)CSS 框架,或者说是一个超轻量级的语义化 HTML + CSS + JS UI 组件库。

这是什么意思呢?回想一下,传统的 UI 库(如 Bootstrap、Element UI)通常需要你在 HTML 标签上添加各种类名,比如 class=”btn btn-primary”。而 Oat UI 则反其道而行之,它通过 CSS 的标签选择器和属性选择器,直接对原生 HTML 元素进行美化。

你写的 <button><table><form>,只要引入了 Oat UI,就会自动拥有统一、现代的样式。它不需要任何第三方库依赖,纯原生实现,直接引入 CDN 文件即可,无需构建工具。

来看下示例效果

下面是一个完全没有任何 class 的、最原生的表单和表格 HTML 代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Oat UI 演示</title>
</head>
<style>
    body {
        width: 800px;
        margin: 0 auto;
    }
</style>
<body>
    <h1>用户注册</h1>
    <p>这是一个没有任何 class 的表单示例。</p>
    <form>
        <div>
            <label for="username">用户名</label>
            <input type="text" id="username" placeholder="请输入用户名">
        </div>

        <div>
            <label for="email">邮箱</label>
            <input type="email" id="email" placeholder="请输入邮箱">
        </div>

        <div>
            <label for="password">密码</label>
            <input type="password" id="password" placeholder="请输入密码">
        </div>

        <div>
            <label for="role">角色</label>
            <select id="role">
                <option>开发者</option>
                <option>设计师</option>
                <option>产品经理</option>
            </select>
        </div>

        <button type="submit">立即注册</button>
    </form>
    <hr>
    <h2>数据报表</h2>
    <table>
        <thead>
            <tr>
                <th>姓名</th>
                <th>年龄</th>
                <th>职业</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>张三</td>
                <td>28</td>
                <td>前端工程师</td>
            </tr>
            <tr>
                <td>李四</td>
                <td>32</td>
                <td>后端架构师</td>
            </tr>
        </tbody>
    </table>
</body>
</html>

如果不引入任何样式,它的界面会非常“原始”,就是浏览器默认的样式。

而使用 Oat UI 只需要在 HTML 的 <head> 标签中引入它的 CSS 和 JS 文件:

<link rel="stylesheet" href="https://unpkg.com/@knadh/oat/oat.min.css">
<script src="https://unpkg.com/@knadh/oat/oat.min.js" defer></script>

引入之后,无需修改上面 HTML 代码的任何一行,整个页面的表单、按钮、表格就会立刻变得美观、整洁,拥有统一的间距、边框、颜色和交互反馈。你可以清晰地看到,从“原始”到“美观”的转变,仅需两行引入代码。

引入 Oat UI 后表单和表格的美化效果

Oat UI 的作者 Kailash Nadh 创建这个项目的初衷,正是因为他受够了 JavaScript 生态系统中过度设计的臃肿和“依赖地狱”。他想要一个回归初心的方案。整个 UI 库只有 6KB 的 CSS + 2.2KB 的 JS(压缩后),轻得像一片燕麦,这也是它名字的由来。

虽然轻量,但 Oat UI 覆盖的组件种类非常齐全:

类别 组件
布局 Grid 网格、Card 卡片、Sidebar 侧边栏
表单 Button 按钮、Switch 开关、Form 表单元素
导航 Tabs 标签页、Breadcrumb 面包屑、Pagination 分页
反馈 Alert 警告框、Toast 通知、Progress 进度条、Spinner 加载
数据展示 Table 表格、Badge 徽章、Avatar 头像
交互 Accordion 折叠面板、Dropdown 下拉菜单、Tooltip 提示、Dialog 对话框

快速上手指南

方法一:CDN 引入(推荐,最快)

对于快速原型、演示或简单页面,CDN 是最方便的方式。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Oat UI 示例</title>

    <!-- 引入 Oat UI CSS -->
    <link rel="stylesheet" href="https://unpkg.com/@knadh/oat/oat.min.css">
</head>
<body>
    <!-- 在这里写你的页面内容 -->

    <!-- 引入 Oat UI JS(部分交互组件需要) -->
    <script src="https://unpkg.com/@knadh/oat/oat.min.js" defer></script>
</body>
</html>

方法二:npm 安装

如果你的项目使用构建工具,可以通过 npm 安装。

npm install @knadh/oat

然后在你的项目中导入:

// 方式一:导入全部
import '@knadh/oat/oat.min.css';
import '@knadh/oat/oat.min.js';

// 方式二:按需导入(如果你使用构建工具)
import '@knadh/oat/css/oat.min.css';
import '@knadh/oat/js/oat.min.js';

详细代码示例

1. 按钮组件

Oat UI 为 <button> 标签提供了多种样式变体,通过 data-variant 属性或 class 控制。

<!-- 基础按钮 -->
<button>默认按钮</button>
<button data-variant="secondary">次要按钮</button>
<button data-variant="danger">危险操作</button>

<!-- 样式变体 -->
<button class="outline">轮廓按钮</button>
<button data-variant="danger" class="outline">危险轮廓</button>
<button class="ghost">幽灵按钮</button>
<button disabled>禁用状态</button>

<!-- 尺寸 -->
<button class="small">小按钮</button>
<button>中按钮</button>
<button class="large">大按钮</button>

<!-- 按钮组 -->
<menu class="buttons">
    <li><button class="outline">左</button></li>
    <li><button class="outline">中</button></li>
    <li><button class="outline">右</button></li>
</menu>

2. 表单组件

所有原生表单元素 <input>, <select>, <textarea>, <radio>, <checkbox> 都会被自动美化。使用 data-field 属性可以创建带标签的输入框组合。

<form>
    <!-- 文本输入 -->
    <label data-field>
        用户名
        <input type="text" placeholder="请输入用户名" />
    </label>

    <!-- 邮箱输入 -->
    <label data-field>
        邮箱
        <input type="email" placeholder="you@example.com" />
    </label>

    <!-- 密码输入 -->
    <label data-field>
        密码
        <input type="password" placeholder="请输入密码" aria-describedby="pwd-hint" />
        <small id="pwd-hint">密码至少8位</small>
    </label>

    <!-- 下拉选择 -->
    <div data-field>
        <label>角色</label>
        <select>
            <option value="">请选择</option>
            <option value="admin">管理员</option>
            <option value="user">普通用户</option>
        </select>
    </div>

    <!-- 多行文本 -->
    <label data-field>
        简介
        <textarea placeholder="请输入简介..."></textarea>
    </label>

    <!-- 单选 -->
    <fieldset class="hstack">
        <legend>性别</legend>
        <label><input type="radio" name="gender"> 男</label>
        <label><input type="radio" name="gender"> 女</label>
    </fieldset>

    <!-- 多选 -->
    <label data-field>
        <input type="checkbox" /> 同意用户协议
    </label>

    <!-- 开关 -->
    <label>
        <input type="checkbox" role="switch" /> 接收推送通知
    </label>

    <!-- 提交按钮 -->
    <button type="submit">提交</button>
</form>

3. 卡片组件

使用 <article class=”card”> 快速创建卡片容器。

<article class="card">
    <header>
        <h3>文章标题</h3>
        <p>这是一段描述文字</p>
    </header>
    <p>卡片的主要内容区域,可以包含任意 HTML 元素。</p>
    <footer class="hstack">
        <button class="outline">取消</button>
        <button>确定</button>
    </footer>
</article>

4. 警告框(Alert)

使用 role=”alert”data-variant 属性创建不同状态的提示信息。

<div role="alert" data-variant="success">
    <strong>✅ 成功!</strong> 您的操作已成功完成。
</div>

<div role="alert" data-variant="warning">
    <strong>⚠️ 警告!</strong> 请在继续之前检查所有信息。
</div>

<div role="alert" data-variant="error">
    <strong>❌ 错误!</strong> 发生了未知错误,请重试。
</div>

<div role="alert">
    <strong>💡 提示</strong> 这是一条普通的消息通知。
</div>

5. 表格组件

原生 <table> 会被自动美化。在外层添加 <div class=”table”> 可以使其支持水平滚动。

<div class="table">
    <table>
        <thead>
            <tr>
                <th>姓名</th>
                <th>邮箱</th>
                <th>角色</th>
                <th>状态</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>张三</td>
                <td>zhangsan@example.com</td>
                <td>管理员</td>
                <td><span class="badge success">活跃</span></td>
            </tr>
            <tr>
                <td>李四</td>
                <td>lisi@example.com</td>
                <td>编辑</td>
                <td><span class="badge">活跃</span></td>
            </tr>
            <tr>
                <td>王五</td>
                <td>wangwu@example.com</td>
                <td>访客</td>
                <td><span class="badge secondary">待审核</span></td>
            </tr>
        </tbody>
    </table>
</div>

6. 标签页(Tabs)

Oat UI 使用 Web Components 技术实现了 <ot-tabs> 组件,用于创建可访问的标签页。

<ot-tabs>
    <div role="tablist">
        <button role="tab" aria-selected="true">账户</button>
        <button role="tab">安全</button>
        <button role="tab">通知</button>
    </div>

    <div role="tabpanel">
        <h3>账户设置</h3>
        <p>在这里管理您的账户信息...</p>
    </div>

    <div role="tabpanel" hidden>
        <h3>安全设置</h3>
        <p>修改密码和安全设置...</p>
    </div>

    <div role="tabpanel" hidden>
        <h3>通知设置</h3>
        <p>配置您的通知偏好...</p>
    </div>
</ot-tabs>

7. 对话框(Dialog)

基于原生 <dialog> 元素增强,使用 commandforcommand 属性控制开关。

<!-- 打开对话框的按钮 -->
<button commandfor="my-dialog" command="show-modal">打开对话框</button>

<!-- 对话框 -->
<dialog id="my-dialog" closedby="any">
    <form method="dialog">
        <header>
            <h3>编辑资料</h3>
            <p>修改您的个人信息</p>
        </header>
        <div class="vstack">
            <label>姓名 <input name="name" required></label>
            <label>邮箱 <input name="email" type="email"></label>
        </div>
        <footer>
            <button type="button" commandfor="my-dialog" command="close" class="outline">取消</button>
            <button type="submit" value="save">保存</button>
        </footer>
    </form>
</dialog>

<script>
    // 处理对话框返回值
    const dialog = document.querySelector("#my-dialog");
    dialog.addEventListener('close', (e) => {
        if (dialog.returnValue === 'save') {
            console.log('用户点击了保存');
        }
    });
</script>

8. Toast 通知

通过全局 ot 对象提供的 toast 方法显示临时通知。

<button onclick="showSuccess()">显示成功通知</button>
<button onclick="showError()">显示错误通知</button>

<script>
    // 成功通知
    function showSuccess() {
        ot.toast('操作已完成', '成功', { variant: 'success' });
    }

    // 错误通知
    function showError() {
        ot.toast('发生了错误', '失败', { variant: 'danger', placement: 'top-center' });
    }

    // 自定义通知配置
    ot.toast('新消息', '通知中心', {
        variant: 'warning',           // success | danger | warning
        placement: 'bottom-right',     // top-left | top-center | top-right | bottom-left | bottom-center | bottom-right
        duration: 5000                 // 显示时间(毫秒),0 为永久
    });
</script>

9. 进度条和加载指示器

使用原生 <progress> 标签创建进度条,使用 aria-busydata-spinner 属性创建加载动画。

<!-- 进度条 -->
<progress value="60" max="100"></progress>
<progress value="30" max="100"></progress>
<progress value="90" max="100"></progress>

<!-- 加载指示器 -->
<div class="hstack" style="gap: 2rem;">
    <div aria-busy="true" data-spinner="small"></div>
    <div aria-busy="true"></div>
    <div aria-busy="true" data-spinner="large"></div>
</div>

<!-- 带遮罩的加载状态 -->
<article class="card" aria-busy="true" data-spinner="large overlay">
    <header>
        <h3>卡片标题</h3>
        <p>卡片描述</p>
    </header>
    <p>内容区域会被遮罩</p>
</article>

10. 网格布局

Oat UI 提供了一个简单的 12 列网格系统,类名类似于传统框架。

<div class="container">
    <div class="row">
        <div class="col-4">col-4</div>
        <div class="col-4">col-4</div>
        <div class="col-4">col-4</div>
    </div>

    <div class="row">
        <div class="col-6">col-6</div>
        <div class="col-6">col-6</div>
    </div>

    <div class="row">
        <div class="col-3">col-3</div>
        <div class="col-6">col-6</div>
        <div class="col-3">col-3</div>
    </div>

    <!-- 带偏移的布局 -->
    <div class="row">
        <div class="col-4 offset-2">col-4 offset-2</div>
        <div class="col-4">col-4</div>
    </div>
</div>

适合哪些场景?

Oat UI 并非万能的银弹。如果你要开发复杂交互的单页面应用(SPA),拥有大量动态状态,那么 React、Vue 等现代框架依然是更好的选择。

但在以下这些场景中,Oat UI 的轻量与便捷优势会非常突出:

  • 内部工具/管理后台:为公司或团队快速搭建一个数据查询、内容管理的页面,没必要启动一个完整的前端项目。
  • 产品原型/MVP(最小可行产品):当你有一个新想法,需要在极短时间内做出一个可演示的界面给客户或团队看时,它让你专注于功能逻辑而非样式细节。
  • 静态内容网站/博客:个人博客、产品介绍页、活动落地页等,追求极致的加载速度与简单的维护方式。
  • 学习与教学:对于刚接触后端开发或数据分析的同学,想快速做一个带界面的 Demo 来展示结果,而不想深入前端框架。

如何定制主题?

Oat UI 的样式完全基于 CSS 变量(Custom Properties)构建,因此定制主题非常简单。你只需要在你的样式表中覆盖这些变量即可。

:root {
    --primary: #3498db;           /* 主色调 */
    --background: #ffffff;         /* 背景色 */
    --text: #2c3e50;              /* 文字颜色 */
    --border: #e0e0e0;            /* 边框颜色 */
    --radius: 0.5rem;             /* 圆角大小 */
}

库本身支持暗色主题,会根据用户的系统偏好(prefers-color-scheme: dark)自动切换。你也可以通过为 <html> 标签添加 data-theme=”dark” 属性来强制启用暗色模式。

写在最后

在如今前端工具链日益复杂、项目动辄需要安装上百个依赖的背景下,Oat UI 像一股清流,让我们重温了 Web 开发的初心:HTML 文档本身就是内容的载体,应该清晰可读

它可能不是构建大型应用的首选,但在追求“简单快速出活”的场景下,这种回归原生的轻量方案,往往能带来意想不到的高效率。它减少了在类名、构建配置和依赖管理上的心智负担,让你能更专注于内容和功能本身。

如果你也在为某个小项目简单而美观的界面发愁,不妨试试 Oat UI,或许它会给你带来惊喜。更多前沿的技术工具和实践分享,欢迎到 云栈社区 交流探讨。

项目地址https://github.com/knadh/oat




上一篇:前阿里P10谈儿童AI陪伴产品设计:NFC卡片、生命感与情绪算法的融合
下一篇:从基建到业务:我的AI Native开发实战与五个颠覆性发现
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-3-28 09:49 , Processed in 0.514632 second(s), 42 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表