{"id":21890833,"url":"https://github.com/chantastic/practical-bem","last_synced_at":"2025-03-22T03:11:45.205Z","repository":{"id":141974501,"uuid":"57335147","full_name":"chantastic/practical-bem","owner":"chantastic","description":"The TL;DR on BEM IRL","archived":false,"fork":false,"pushed_at":"2016-09-02T17:39:41.000Z","size":4,"stargazers_count":32,"open_issues_count":0,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-02-02T22:29:12.502Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chantastic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-04-28T21:32:48.000Z","updated_at":"2024-03-11T21:32:30.000Z","dependencies_parsed_at":null,"dependency_job_id":"a2c1c15f-caa3-4d54-adc7-e16e5ee77d46","html_url":"https://github.com/chantastic/practical-bem","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chantastic%2Fpractical-bem","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chantastic%2Fpractical-bem/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chantastic%2Fpractical-bem/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chantastic%2Fpractical-bem/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chantastic","download_url":"https://codeload.github.com/chantastic/practical-bem/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244898458,"owners_count":20528341,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-28T12:17:24.868Z","updated_at":"2025-03-22T03:11:45.199Z","avatar_url":"https://github.com/chantastic.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Practical BEM\nThe TL;DR on BEM IRL\n\n## Table of contents\n\n1. [BEM anatomy](#bem-anatomy)\n1. [Dialects](#dialects)\n1. [Entity](#entity)\n1. [Block](#block)\n1. [Element](#element)\n1. [Modifier](#modifier)\n\n## BEM anatomy\n\n```css\n/*\n * Entity\n * A set of Elements and Modifiers related to a single Block\n */\n\n/*\n * Block\n * The single root-class of your Entity\n */\n\n.todo-item { }\n\n/*\n * Element\n * Any number of Block-descendants\n */\n\n.todo-item__mark { }\n.todo-item__text { }\n\n/*\n* Modifier\n* Any number of Block/Element modifiers\n*/\n\n.todo-item--complete { }\n.todo-item--due { }\n```\n\n**[⬆ back to top](#table-of-contents)**\n\n## Dialects\nThere are a few alternative BEM dialects. These examples use the most popular [`--` dialect](http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/) by Harry Roberts. Using `--` for modifiers removes a small ambiguity around [key/value modifiers](https://en.bem.info/methodology/naming-convention/#element-modifier).\n\n**[⬆ back to top](#table-of-contents)**\n\n## Entity\nAn Entity is a collections of Elements and Modifiers, related to a single Block. Entities are analogous to \"modules\" or \"components\" in other CSS philosophies.\n\n**[⬆ back to top](#table-of-contents)**\n\nPractically, Entities should live in a single file and be easily transportable to other projects.\n\n## Block\nA Block is the single, root-level, classes of any Entity.\n\n```css\n.todo-item { }\n```\n\nA bunch of Blocks:\n\n```css\n.report { }\n.report-item { }\n.report-subtotal { }\n\n.person { }\n.person-name { }\n.person-child-list { }\n\n.admin-person { }\n.admin-person-responsibilities-list { }\n.admin-person-responsibilities-item { }\n```\n\n### Relationships\n* Block `belongs_to` Entity\n* Block `has_many` Elements\n* Block `has_many` Modifiers\n\n**[⬆ back to top](#table-of-contents)**\n\n## Element\nAn Element is anything nested in a Block.\n\n*\"Descendent\" is actually a better word but `BDM` doesn't roll off the tongue.*\n\nHere are some elements:\n\n```css\n.todo-item__mark { }\n.todo-item__text { }\n.todo-item__input { }\n.todo-item__delete-button { }\n```\n\nElements can have Modifiers. Though they're not preferred.\n\n```css\n.todo-item__delete-button--blingy { }\n```\n\n### Prefer Block-Modifiers\nI find Block-Modifiers to be more maintainable than Element-Modifiers. In most cases, Element-Modifiers are partial Block-Modifiers waiting to grow up. You can avoid refactoring by preferring Block-Modifiers.\n\n### No grandchildren\n\nBEM supports only one level of element. If you find yourself reaching for Element-Elements (grandchildren), you have two options:\n* Flatten out the Elements\n* Create a new Block\n\n#### This is incorrect\n```\n\u003cli class=\"todo-item\"\u003e\n  \u003cheader className=\"todo-item__header\"\u003e\n    \u003cspan className=\"todo-item__header__text\"\u003eMow Lawn\u003c/span\u003e\n  \u003c/header\u003e\n\u003c/li\u003e\n```\n\n#### Option 1: Flatten\n```\n\u003cli class=\"todo-item\"\u003e\n  \u003cheader className=\"todo-item__header\"\u003e\n    \u003cspan className=\"todo-item__header-text\"\u003eMow Lawn\u003c/span\u003e\n  \u003c/header\u003e\n\u003c/li\u003e\n```\n\n#### Option 2: New Block\n```\n\u003cli class=\"todo-item\"\u003e\n  \u003cheader className=\"todo-item-header\"\u003e\n    \u003cspan className=\"todo-item-header__text\"\u003eMow Lawn\u003c/span\u003e\n  \u003c/header\u003e\n\u003c/li\u003e\n```\n\nNow `.todo-item-header` can be composed with Elements from the `.todo-item` Entities.\n\n```\n\u003cli class=\"todo-item\"\u003e\n  \u003cheader className=\"todo-item__header todo-item-header\"\u003e\n    \u003cspan className=\"todo-item-header__text\"\u003eMow Lawn\u003c/span\u003e\n  \u003c/header\u003e\n\u003c/li\u003e\n```\n\n#### Why?\n\nThis may seem pedantic but it's critical to how BEM scales. Grandchildren introduce relationships into Entities. Once you have relationships, how many descendants do you cut off at? BEM makes it easy and cuts it off at 1.\n\n### Relationships\n* Entity `belongs_to` Block\n* Entity `has_many` Modifiers\n\n**[⬆ back to top](#table-of-contents)**\n\n## Modifier\nModifiers are like HTML attributes. They alter Blocks and Elements. They can be **boolean** or **key/value** pairs.\n\n```css\n/* boolean */\n.todo-item--hidden { }\n\n/* named attributes*/\n.todo-item--size_small { }\n.todo-item--type_radio { }\n\n/* Element_Modifier */\n.todo-item__header--fancy { }\n```\n\n### Prefer Block-Modifiers\nI find Block-Modifiers to be more maintainable than Element-Modifiers. In most cases, Element-Modifiers are partial Block-Modifiers waiting to grow up. You can avoid refactoring by preferring Block-Modifiers.\n\nThis code commonly gets outgrown:\n\n```html\n.todo-item__header--blingy { }\n```\n\nPrefer this by default:\n\n```html\n.todo-item--blingy { }\n.todo-item--blingy .todo-item__header { }\n```\n\n### Alternatives\nThe BEM approach to Modifiers is hotly contested. This stems from a desire to type less or a misunderstanding of early BEM documentation. Granted, the early docs were in pretty poor English.\n\nWhile I like variants with global states, e.g., `.is-visible`, it breaks the BEM model. More relevant, it makes utility-class libraries (e.g., minions.css and tachyons) harder to use.\n\n### Prefer inline for generic visibility changes\nFor generic visibility changes, prefer an inline-style on the Block.\n\n```html\n\u003c!-- ok --\u003e\n\u003cdiv class=\"todo-item todo--visible\"\u003e ... \u003c/div\u003e\n\n\u003c!-- preferred --\u003e\n\u003cdiv class=\"todo-item\" style=\"display: none\"\u003e ... \u003c/div\u003e\n```\n\n### Relationships\n* Modifier `belongs_to` Block\n* Modifier `belongs_to` Element\n\n**[⬆ back to top](#table-of-contents)**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchantastic%2Fpractical-bem","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchantastic%2Fpractical-bem","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchantastic%2Fpractical-bem/lists"}