Skip to content

Migrate 4 BEM components to CSS Modules#2013

Open
paskal wants to merge 1 commit intomasterfrom
bem-to-css-modules
Open

Migrate 4 BEM components to CSS Modules#2013
paskal wants to merge 1 commit intomasterfrom
bem-to-css-modules

Conversation

@paskal
Copy link
Collaborator

@paskal paskal commented Feb 24, 2026

Summary

  • Migrate dropdown/__item, list-comments, comment-form/__subscribe-by-rss, and settings from legacy BEM CSS (via bem-react-helper) to CSS Modules
  • Consolidate 13 BEM CSS files into 4 .module.css files, remove dead CSS and unused class references
  • 24 files changed, +124/-159 lines

Built artefact verification

  • 83 of 89 production files are byte-identical between master and branch
  • 6 files differ (remark.css/js/mjs, last-comments.css/js/mjs): only class name hash shifts from webpack module ordering and minified variable name shifts from changed import order; all CSS property:value pairs are preserved
  • 3 new var() fallback values added by the CSS modules build (matching existing migrated component pattern)
  • Bundle sizes decreased: remark.css -626 bytes, remark.js -512 bytes, last-comments.css -16 bytes (dead CSS removed)
  • Pixel-by-pixel screenshot comparison (light + dark themes) shows 0 different pixels

Dead code removed

  • .settings__blocked-users-username — CSS rule with no matching TSX element
  • comment-form/__rss-link/ — entire directory, class never referenced in any component
  • titleClass prop on subscribe-by-rss — referenced a class with no CSS rules
  • className="comments-list" on list-comments — global class with zero CSS rules anywhere

…from BEM to CSS Modules

Consolidate legacy BEM CSS files into CSS Modules for 4 components:
- dropdown/__item: 1 CSS file → dropdown-item.module.css
- list-comments: 1 CSS file → list-comments.module.css (removed unused
  comments-list class that had no CSS rules)
- comment-form/__subscribe-by-rss: 1 CSS file → subscribe-by-rss.module.css,
  removed dead titleClass prop and dead __rss-link directory
- settings: 10 CSS files → settings.module.css, removed dead
  .settings__blocked-users-username CSS rule

Built artefact comparison (master vs branch):
- 83 of 89 files in /srv/web/ are byte-identical (all locale bundles,
  SVGs, HTML pages unchanged)
- 6 files differ: remark.css/js/mjs and last-comments.css/js/mjs
- CSS changes are class name hash shifts (e.g. G_A → H_A) caused by
  webpack's module ordering, plus 3 new var() fallback values added
  by the CSS modules build; all property:value pairs are preserved
- JS changes are minified variable name shifts (O ↔ A, I ↔ L) from
  changed import order; no logic changes
- Visual comparison (pixel-by-pixel screenshots of both light and dark
  themes on the demo page) shows 0 different pixels
- Bundle sizes: remark.css -626 bytes, remark.js -512 bytes,
  last-comments.css -16 bytes (dead CSS removed)
@paskal paskal requested a review from umputun as a code owner February 24, 2026 17:02
@github-actions
Copy link

size-limit report 📦

Path Size
public/embed.mjs 2.06 KB (0%)
public/remark.mjs 73.76 KB (-0.09% 🔽)
public/remark.css 8.18 KB (-0.54% 🔽)
public/last-comments.mjs 36.18 KB (-0.05% 🔽)
public/last-comments.css 3.74 KB (-0.27% 🔽)
public/deleteme.mjs 12.42 KB (0%)
public/counter.mjs 747 B (0%)

@codecov
Copy link

codecov bot commented Feb 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 62.16%. Comparing base (b38d91c) to head (21cd3ec).
⚠️ Report is 7 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2013      +/-   ##
==========================================
- Coverage   62.17%   62.16%   -0.01%     
==========================================
  Files         132      132              
  Lines        3035     3037       +2     
  Branches      769      728      -41     
==========================================
+ Hits         1887     1888       +1     
- Misses       1144     1145       +1     
  Partials        4        4              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

paskal added a commit that referenced this pull request Feb 24, 2026
Migrate 8 components from BEM to CSS Modules:
- button (7 BEM files -> 1 module)
- dropdown (7 BEM files -> 1 module)
- thread (3 BEM files -> 1 module)
- auth-panel (2 BEM files -> 1 module)
- dropdown-item, list-comments, subscribe-by-rss, settings (from batch 0 PR #2013)

Consolidates 19 BEM CSS files into 8 CSS Module files. Uses clsx for
conditional class composition, replacing bem-react-helper's b() calls.
Class naming follows the established convention: BEM block = .root,
elements = camelCase, modifiers = camelCase.

Visual regression verification on built artefacts:
- remark.css: 43,779 -> 43,299 bytes (480 bytes smaller)
- last-comments.css: 18,792 -> 18,776 bytes (16 bytes smaller)
- remark.js: 256,709 -> 304,837 bytes (48KB larger, expected: CSS Module
  classname mappings now live in JS instead of plain strings)
- Dark theme: pixel-identical (zero difference)
- Light theme: pixel-identical (0.21% diff is the native demo page
  "Toggle theme" button, not any remark42 widget element)

Also updates CLAUDE.md CSS guideline to reflect the migration status.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant