PHPackages                             aklump/bem - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. aklump/bem

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

aklump/bem
==========

A PHP project to enforce the Block Element Modifier (CSS) methodology.

0.0.3(2y ago)061BSD-3-ClausePHPPHP &gt;=7.3

Since Nov 26Pushed 2y ago1 watchersCompare

[ Source](https://github.com/aklump/bem)[ Packagist](https://packagist.org/packages/aklump/bem)[ Docs](https://github.com/aklump/bem)[ RSS](/packages/aklump-bem/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (3)Versions (4)Used By (0)

BEM
===

[](#bem)

BEM — is a methodology that helps you to create reusable components and code sharing in front‑end development

Usage
-----

[](#usage)

Create a class instance to represent your BEM model. Pass the "block" as the constructor argument.

```
$bem = new \AKlump\Bem\Fluent\Bem('foo');
```

All methods return an object instance that can be typecast to a string. Or, you can also call `toString()` or `toArray()` as appropriate; see `\AKlump\Bem\Fluent\Interfaces\OutputInterface` for details. All of the following produce the same output.

```
(string) $bem->block(); // foo
strval($bem->block()); // foo
$bem->block()->toString(); // foo

```

For simplicity any remaining examples will show only the first form.

### The Basic Four

[](#the-basic-four)

```
(string) $bem->block(); // "foo"
(string) $bem->element('content'); // "foo__content"
(string) $bem->block()->modifier('has-image'); // "foo--has-image"
(string) $bem->element()->modifier('content', 'has-image'); // "foo__content--has-image"
```

### For Javascript Purposes

[](#for-javascript-purposes)

```
(string) $bem->block()->js(); // "js-foo"
(string) $bem->element('content')->js(); // "js-foo__content"
```

### Convenience Syntax

[](#convenience-syntax)

There are some conveniences you should take note of; pay special attention to the `plus*` methods.

```
// In both cases "foo js-foo" === $classes.
$classes = $bem->block() . ' ' . $bem->block()-js();
$classes = $bem->block()->plusJs();

// In both cases "foo foo--bar" === $classes.
$classes = $bem->block() . ' ' . $bem->block()->modifier('bar);
$classes = $bem->block()->plusModifier('bar);

// In both cases "foo foo--bar js-foo js-foo--bar" === $classes.
$classes = implode(' ', [
  $bem->block(),
  $bem->block()->modifier('bar),
  $bem->block()->js(),
  $bem->block()->modifier('bar)->js(),
]);

$classes = $bem->block()->plusModifier('bar)->plusJs()
```

"Global" Innovation
-------------------

[](#global-innovation)

You'll find an innovation in this project called *global*. It can be used to target common parts across all blocks at once. Refer to the example below where `component` and `component__content` represent the *global block* and *global element*, respectively. This innovation, in this case, allows you to target all three components' `content` in a single line of CSS. It can be thought of as a means of grouping. Use the the `plusGlobal()` method for this feature.

```

```

```
.component__content {
  width: 900px;
  margin: auto;
}
```

```
$story = new \AKlump\Bem\Fluent\Bem('story', 'component');
$film = new \AKlump\Bem\Fluent\Bem('film', 'component');
$copy = new \AKlump\Bem\Fluent\Bem('copy', 'component');

$story->element('content')->plusGlobal(); // "story__content component__content"
$film->element('content')->plusGlobal(); // "film__content component__content"
$copy->element('content')->plusGlobal(); // "copy__content component__content"
```

### Casting to Array

[](#casting-to-array)

Given a complex chain as shown next, you can see the helpfulness of the `plus*` methods and why you might want to use the `toArray()` method.

```
$bem = new \AKlump\Bem\Fluent\Bem('foo', 'components');
$classes = $bem->element('content')
  ->plusModifier('first')
  ->plusGlobal()
  ->plusJs()
  ->toArray();

$classes === [
  'foo__content',
  'foo__content--first',
  'js-foo__content',
  'js-foo__content--first',
  'js-components__content',
  'js-components__content--first',
  'components__content',
  'components__content--first',
];
```

Customizing Output Style
------------------------

[](#customizing-output-style)

To alter the way the classes are formatted, create a new, custom class implementing `\AKlump\Bem\Styles\StyleInterface` for control of the processing and output of the classes, including the division characters. Look to `\AKlump\Bem\Styles\Official` for a model. Pass your custom style to `\AKlump\Bem\Fluent\Bem` when constructing.

Usage With Twig
---------------

[](#usage-with-twig)

### Themers

[](#themers)

```
{{ bem_set_global('component') }}
{{ bem_set_block('story-section') }}

Twig Extension Example

{% set classes = [
  bem_block().plus_js(),
  bem_block().modifier('th-summary'),
  bem_block().modifier('lang-en'),
] %}
&lt;section>
  &ltdiv class="{{ classes|join(' ') }}">
    &lt;div class="{{ bem_element('width').plus_global() }}">
      &lt;div class="{{ bem_element('item').plus_modifier('first') }}">&lt;/div>
      &lt;div class="{{ bem_element('item') }}">&lt;/div>
      &lt;div class="{{ bem_element('item').plus_modifier('last') }}">&lt;/div>
    &lt;/div>
  &lt;/div>
&lt;/section>

```

### Developers

[](#developers)

See `\AKlump\Bem\Twig\BemExtension`

Contributing
------------

[](#contributing)

If you find this project useful... please consider [making a donation](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4E5KZHDQCEUV8&item_name=Gratitude%20for%20aklump%2Fbem).

Similar Packages
----------------

[](#similar-packages)

-
-

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity8

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity29

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~4 days

Total

3

Last Release

894d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/79476f3b82f9c766433c7eb401cbcfc636cd5d5ccf2b2e6b50ea81d1de6c2730?d=identicon)[aklump](/maintainers/aklump)

---

Top Contributors

[![aklump](https://avatars.githubusercontent.com/u/425737?v=4)](https://github.com/aklump "aklump (27 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/aklump-bem/health.svg)

```
[![Health](https://phpackages.com/badges/aklump-bem/health.svg)](https://phpackages.com/packages/aklump-bem)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
