不能。Storybook不原生支持纯HTML组件,需将HTML片段封装为框架组件或通过模板字符串+render函数实现预览,直接放入button.html无法识别、加载或热更新。

Storybook 能否直接支持纯 HTML 组件?
能,但必须绕过框架绑定逻辑。Storybook 默认对 React、Vue、Web Components 有开箱即用支持,而纯 HTML(即无 JS 框架、无自定义元素定义、仅含静态结构 + 内联样式)不属于任何组件模型,component 字段会失效,DocsPage 无法提取 props 或生成交互控件。
实际做法是:把 HTML 片段包装成“无状态函数”,在 story 中返回字符串或 DOM 节点,并手动启用 @storybook/addon-docs 和 @storybook/addon-controls —— 后者需配合 args 和模板函数模拟参数注入。
- 不要写
component: 'div'或component: null,这会导致 DocsPage 报错或空白 - 必须使用 CSF 格式(Component Story Format),且每个 story 必须导出一个可执行函数,例如
const Template = (args) => `<button class="${args.variant}">${args.label}</button>` - 若 HTML 含内联脚本或事件监听,需用
dangerouslySetInnerHTML(React)或innerHTML(HTML 预设)处理,但会失去 SSR 安全性与类型提示
如何为纯 HTML 按钮生成可调参的文档页?
关键不是让 Storybook “理解” HTML,而是让它“渲染并控制” HTML 字符串。你需要显式定义 argTypes,并用模板函数拼接最终 HTML,再交由 Storybook 的 DocsPage 渲染。
示例(Button.stories.js):
立即学习“前端免费学习笔记(深入)”;
export default {
title: 'HTML/Button',
argTypes: {
label: { control: 'text', defaultValue: 'Click me' },
variant: {
control: 'select',
options: ['primary', 'secondary', 'outline'],
defaultValue: 'primary'
},
disabled: { control: 'boolean', defaultValue: false }
}
};
<p>const Template = ({ label, variant, disabled }) => <code> <button class="btn btn-${variant}" ${disabled ? 'disabled' : ''} >${label}</button> </code>;</p><div class="aritcle_card flexRow">
<div class="artcardd flexRow">
<a class="aritcle_card_img" href="/xiazai/skill4293" title="Doc To HTML"><img
src="https://img.php.cn/upload/skill/000/000/081/178998486916110.jpg" alt="Doc To HTML" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a href="/xiazai/skill4293" title="Doc To HTML">Doc To HTML</a>
<p>使用 MinerU 文档处理引擎将 Word 文档(.doc、.docx)转换为保留结构和格式的干净 HTML。</p>
</div>
<a href="/xiazai/skill4293" title="Doc To HTML" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a>
</div>
</div><p>export const Default = Template.bind({});
Default.args = { label: 'Submit', variant: 'primary' };
-
Template.bind({})是必需的,否则 Controls 插件无法关联 args 与渲染结果 - 类名拼接必须严格匹配你项目中真实 CSS 的命名规则,Storybook 不校验 class 是否存在
- 如果按钮依赖外部 CSS(如 Milligram 或 Tailwind),确保
.storybook/preview.js中已正确引入,否则 Docs 页看到的是无样式的原始标签
DocsPage 为何不显示 props 表?怎么补救?
因为纯 HTML 没有 TypeScript 接口或 JSDoc 注释可解析,@storybook/addon-docs 的自动 props 提取完全失效。DocsPage 只会显示“无 props 可展示”,哪怕你写了 argTypes。
解决方式只有手动补全:在 story 文件末尾或配套的 .mdx 文档中,用 Markdown 表格硬编码参数说明。
例如,在 Button.docs.mdx 中:
<Meta of="Button.stories.js" /> <h2>Props</h2><table><thead><tr><th>参数</th><th>类型</th><th>默认值</th><th>说明</th></tr></thead><tbody><tr><td><code>label</code></td><td>string</td><td><code>"Click me"</code></td><td>按钮文字内容</td></tr><tr><td><code>variant</code></td><td>enum</td><td><code>"primary"</code></td><td>可选 <code>primary</code>/<code>secondary</code>/<code>outline</code></td></tr><tr><td><code>disabled</code></td><td>boolean</td><td><code>false</code></td><td>是否禁用</td></tr></tbody></table><p><Story of="Default" />
-
<Meta of="..." />的路径必须指向 JS story 文件,不能是 .mdx 自身 - 表格中所有技术名词(如
label、"primary")必须用<code>包裹,否则 DocsPage 不识别为代码片段 - 别指望
DocsPage自动生成这部分——它只对 React/Vue/TSX 组件有效,纯 HTML 场景下就是个空壳
本地调试时样式丢失或布局错乱怎么办?
纯 HTML 组件极度依赖全局 CSS 上下文。Storybook 的预览 iframe 默认不继承主页面样式,且默认重置了部分浏览器默认样式(如 margin/padding),导致按钮看起来“扁平”或尺寸异常。
修复路径只有两条:要么注入全局样式,要么重置 iframe 环境。
- 在
.storybook/preview.js中添加:import '../src/styles.css';(确保路径正确且无构建错误) - 若用 Tailwind,确认
tailwind.config.js已配置content包含stories/**/*.{js,ts},否则 class 会被 purge - 避免在 HTML 字符串里写
style="..."行内样式——它会覆盖 CSS 文件中的响应式断点或媒体查询 - 检查浏览器 DevTools 的 Elements 面板,确认 iframe 的
<html>根节点是否加载了预期的 CSS 文件;若缺失,说明 import 路径错误或构建未生效
最常被忽略的是 CSS 加载时机:Storybook 启动时若 CSS 尚未编译完成,预览页就会短暂白屏或失样式——等终端输出 info => Using prebuilt manager 之后再刷新页面。


















