npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@txjs/bem

v1.1.1

Published

遵循 BEM 规范的 CSS 类名生成工具,支持 CSS Modules

Downloads

90

Readme

@txjs/bem

CSS 命名函数库,遵循 BEM 规范,支持普通模式和 CSS Modules 模式。

安装

# npm
npm i @txjs/bem

# pnpm
pnpm add @txjs/bem

# yarn
yarn add @txjs/bem

导入方式

import { BEM } from '@txjs/bem'

基本概念

BEM(Block Element Modifier)是一种 CSS 命名方法论:

  • Block(块):独立的页面组件,如 headermenu
  • Element(元素):块的子部分,如 menu__itemheader__logo
  • Modifier(修饰符):块的变体,如 menu--activebutton--disabled

基础用法

const [name, bem] = BEM('home')

name
// => 'home'

bem()
// => 'home'

bem('container')
// => 'home__container'

bem('item', ['active', 'disabled'])
// => 'home__item home__item--active home__item--disabled'

函数签名

// 不使用 CSS Modules
function BEM(name: string): [string, (el?: Mods, mods?: Mods) => string]

// 使用 CSS Modules
function BEM(name: string, css: Record<string, string>): [string, (el?: Mods, mods?: Mods) => string]

参数

  • name - 块名称
  • css -(可选)CSS Modules 的类名映射对象

修饰符类型

bem 函数接受两种修饰符格式:

// 数组形式 - 直接指定修饰符名
bem('item', ['active', 'disabled'])

// 对象形式 - 根据值决定是否添加修饰符
bem('item', { active: true, disabled: false })

常规使用

import { BEM } from '@txjs/bem'

const [name, bem] = BEM('button')

// 获取块名
name
// => 'button'

// 无修饰符 - 返回块名
bem()
// => 'button'

// 字符串修饰符 - 作为块/元素添加
bem(['primary'])
// => 'button button--primary'

bem('text', ['small'])
// => 'button__text button__text--small'

// 对象修饰符 - 根据布尔值决定是否添加
bem('body', { safearea: true })
// => 'button__body button__body--safearea'

bem('body', { safearea: false })
// => 'button__body' (false 的修饰符被忽略)

// 组合使用
bem('item', ['active'])
// => 'button__item button__item--active'

bem('item', { active: true, loading: true })
// => 'button__item button__item--active button__item--loading'

// 空修饰符
bem([])
// => 'button'

bem('item', {})
// => 'button__item'

CSS Modules 模式

配合 CSS Modules 使用,自动将 BEM 名称映射到哈希化的类名。

使用示例

import { BEM } from '@txjs/bem'
import styles from './Button.module.less'

// styles 内容示例:
// {
//   button: 'button_abc123',
//   'button--primary': 'button--primary_def456',
//   button__text: 'button__text_ghi789',
//   'button__text--small': 'button__text--small_jkl012'
// }

const [name, bem] = BEM('button', styles)

// name 返回原始块名
name
// => 'button'

// bem() 返回哈希化的块类名
bem()
// => 'button_abc123'

// 自动查找对应的哈希化类名
bem('text')
// => 'button__text_ghi789'

bem('text', ['small'])
// => 'button__text_ghi789 button__text--small_jkl012'

bem(['primary'])
// => 'button_abc123 button--primary_def456'

在 React/Vue 中的使用

import { BEM } from '@txjs/bem'
import styles from './Menu.module.less'

function Menu() {
  const [name, bem] = BEM('menu', styles)

  return (
    <nav className={bem()}>
      <ul className={bem('list')}>
        <li className={bem('item', { active: true })}>
          <a className={bem('link')} href="#">
            首页
          </a>
        </li>
        <li className={bem('item', { active: false })}>
          <a className={bem('link')} href="#">
            关于
          </a>
        </li>
      </ul>
    </nav>
  )
}

// 生成的类名:
// <nav class="menu_abc123">
//   <ul class="menu__list_def456">
//     <li class="menu__item_ghi789 menu__item--active_jkl012">
//       <a class="menu__link_mno345">首页</a>
//     </li>
//     <li class="menu__item_ghi789">
//       <a class="menu__link_mno345">关于</a>
//     </li>
//   </ul>
// </nav>

全局配置

通过 BEM.config 方法可以设置全局配置,影响所有 BEM 实例的行为。

BEM.config(options: { mode?: 'match' | 'always' }): void

mode 选项

| 模式 | 说明 | |------|------| | match(默认) | 样式类名匹配不到时返回空字符串 | | always | 样式类名匹配不到时返回原始 BEM 名称 |

使用示例

import { BEM } from '@txjs/bem'

// 默认模式 (match)
const [, bem] = BEM('button', {})
bem('text', ['small'])
// => '' (匹配不到时返回空)

// 切换到 always 模式
BEM.config({ mode: 'always' })
bem('text', ['small'])
// => 'button__text button__text--small'

// 恢复默认模式
BEM.config({ mode: 'match' })

API 参考

BEM(name)

创建 BEM 实例。

const [name, bem] = BEM('block')

bem()

返回块名。

bem()
// => 'block'

bem(modifiers)

使用修饰符数组或对象。

bem(['modifier'])
// => 'block block--modifier'

bem({ active: true, disabled: true })
// => 'block block--active block--disabled'

bem(element)

使用元素。

bem('element')
// => 'block__element'

bem(element, modifiers)

同时使用元素和修饰符。

bem('element', ['active'])
// => 'block__element block__element--active'

bem('element', { active: true })
// => 'block__element block__element--active'

常见问题

Q: 为什么使用 BEM?

  • 可预测性:类名格式固定,易于理解和维护
  • 作用域隔离:避免样式冲突
  • 语义化:类名直接表达结构关系
  • CSS Modules 兼容:天然支持哈希化类名

Q: 如何处理动态修饰符?

const isActive = true
const isDisabled = false

bem('button', { active: isActive, disabled: isDisabled })
// => 'button__button button__button--active'

Q: 如何组合多个修饰符?

bem('item', ['active', 'selected', 'highlighted'])
// => 'block__item block__item--active block__item--selected block__item--highlighted'

Q: CSS Modules 中映射不存在会怎样?

match 模式下(默认),找不到映射时返回空字符串:

BEM.config({ mode: 'match' })
const [, bem] = BEM('button', { button: 'btn_xxx' })

bem('nonexistent')
// => ''

bem('nonexistent', ['missing'])
// => ''