{"id":20517193,"url":"https://github.com/iprit/sass-bem","last_synced_at":"2025-03-05T23:27:57.445Z","repository":{"id":27839736,"uuid":"115335147","full_name":"IPRIT/sass-bem","owner":"IPRIT","description":"A Sass library for building immutable and namespaced BEM-style CSS objects","archived":false,"fork":false,"pushed_at":"2022-12-08T12:53:50.000Z","size":670,"stargazers_count":2,"open_issues_count":9,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-14T20:51:26.959Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"SCSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/IPRIT.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-12-25T12:09:01.000Z","updated_at":"2021-06-18T15:08:54.000Z","dependencies_parsed_at":"2023-01-14T07:35:34.602Z","dependency_job_id":null,"html_url":"https://github.com/IPRIT/sass-bem","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IPRIT%2Fsass-bem","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IPRIT%2Fsass-bem/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IPRIT%2Fsass-bem/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/IPRIT%2Fsass-bem/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/IPRIT","download_url":"https://codeload.github.com/IPRIT/sass-bem/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242120945,"owners_count":20075020,"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-15T21:34:16.022Z","updated_at":"2025-03-05T23:27:57.423Z","avatar_url":"https://github.com/IPRIT.png","language":"SCSS","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Sass Bem [![npm version](https://badge.fury.io/js/sass-bem.svg)](https://badge.fury.io/js/sass-bem)\n\nBEM Constructor is a Sass library for building immutable and namespaced BEM-style CSS objects.\n\nBy enforcing a consistent and programatic way of defining objects (blocks, elements and modifiers) it ensures a more structured, robust and secure object codebase that is easy to understand and maintain. Objects defined using the constructor are impossible to modify and reassign by mistake or omission.\n\nJump to [:hamburger: The Burger Example™](#example) to see the mixins in action.\n\n\n## Key ideas\n\nThe key ideas behind this library are well explained by Harry Roberts in his articles [Immutable CSS](http://csswizardry.com/2015/03/immutable-css/), [More Transparent UI Code with Namespaces](http://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/) and [MindBEMding – getting your head ’round BEM syntax](http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/),\n\n### 1. Immutability\n\nSome CSS objects in your project shouldn't be able to change (mutate). They have a very specific role and you need to make sure they're not reassigned somewhere else in your codebase. In order to ensure immutability you'll need three things: a way of defining those objects, a way of recognising them and a way to guarantee you won't be able to modify them later on. By constructing objects programatically you can be confident that they are assigned once and just once.\n\n### 2. Namespacing\n\nObjects have a clear function. Whether they are components, utilities, or dirty hacks, we need a consistent way of telling them apart. By namespacing objects, our UI code becomes more transparent and understandable.  BEM Constructor supports the following object types:\n\n- Objects\n- Components\n- Utilities\n- Themes\n- States\n- Scopes\n- Hacks\n\nRead [Harry's post on namespaces](http://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/) to get a deep look at why and how they are used.\n\n\n### 3. BEM structure\n\nBEM objects are composed of a block and any number of elements and/or modifiers. Using the BEM syntax for naming classes you'll produce structured code that helps you and other developers understand at a glance the relationship between those classes. The BEM constructor takes care of generating bem-compliant selectors.\n\n### 4. Responsive suffixes\n\nWith [responsive suffixes](http://csswizardry.com/2015/08/bemit-taking-the-bem-naming-convention-a-step-further/) you are able to denote conditional states or breakpoints where permutations to an object may occur. This is specially useful when dealing with media queries that *modify* the base values of a given UI element.\n\n## Installation\n\nThere are 4 ways of installing BEM Constructor:\n\n### Download\n\nDownload [sass-bem-utils.scss](/dist/_sass-bem-utils.scss) and place it in your Sass directory.\n\n### Bower\n\nRun the following command:\n\n    bower install --save-dev sass-bem\n\n### NPM\n\nRun the following command:\n\n    npm install sass-bem --save-dev\n\n\n### Compass extension\n\n1. `gem install sass-bem`\n2. Add `require 'sass-bem'` to your `config.rb`\n\n## Usage\n\nImport it into your main stylesheet:\n\n    @import 'sass-bem';\n\n### block($name, $type)\n\nConstructs a new block element of a given type. `$type` being one of: `'object'`, `'component'` or `'utility'`.\n\n    @include block($name, $type) { ... }\n\n\n#### object($name)\n\nA shortcut for `block($name, $type: 'object')`\n\n#### component($name)\n\nA shortcut for `block($name, $type: 'component')`\n\n#### utility($name)\n\nA shortcut for `block($name, $type: 'utility')`\n\n\n### element($name...)\n\nCreates a new element of the parent block. It should always be nested within a block constructor. You can create multiple elements at once by passing a comma separated list (Arglist) of element names.\n\n    @include element($name...) { ... }\n\n\n### modifier($name...)\n\nCreates a new modifier of the parent block or element. Should always be nested within a block or element constructor. You can declare multiple modifiers at once by passing a comma separated list (Arglist) of modifier names.\n\n    @include modifier($name...) { ... }\n\n\n### modifies-element($modified-elements...)\n\nWhen declaring a block modifier, a theme, a state or a hack you may need to target and modify some of the block elements too. Use the following mixin to scope the ruleset to those elements.\n\n    @include modifies-element($modified-elements...) { ... }\n\n\n### theme($themes...)\n\nStyle your objects given a parent theme class.\n\n    @include theme($themes...) { ... }\n\n### state($states...)\n\nModifies objects by appending a state class\n\n    @include state($states...) { ... }\n\n### hack()\n\nSignals that the following code is a hack.\n\n    @include hack() { ... }\n\n\n### scope($name)\n\nCreates a new scope\n\nScopes allow you to isolate code you don't have control over.\n\n    @include scope($name) { ... }\n\n\n### suffix($name)\n\nAdds a suffix\n\nDenotes a conditional breakpoint that modifies the properties and/or values of an UI\n\n    @include suffix($name) { ... }\n\n## Options\n\n### Namespaces\n\nSwitch namespaces on/off by setting the following variable:\n\n    $bem-use-namespaces: false; // defaults to true\n\nOverride the default block namespaces:\n\n    $bem-block-namespaces: (\n        'object': 'obj',     // defaults to 'o'\n        'component': 'comp', // defaults to 'c'\n        'utility': 'helper', // defaults to 'u'\n    );\n\nOverride the default theme namespace:\n\n    $bem-theme-namespace: 'theme'; // defaults to 't'\n\nOverride the default state namespace:\n\n    $bem-state-namespace: 'has'; // defaults to 'is'\n\nOverride the default suffix namespace:\n\n    $bem-suffix-namespace: '-at-'; // defaults to ''\\\\@''\n\nOverride the default hack namespace:\n\n    $bem-hack-namespace: 'it-wasnt-me-'; // defaults to '_'\n\n\n\n### BEM separators\n\nBy default BEM Constructor uses the following BEM convention:\n- Two underscores (__) for elements\n- Two hyphens for modifiers (--).\n\nYou can customize them to whatever fits your needs:\n\n    $bem-element-separator: '-'; // Defaults to '__'\n\n    $bem-modifier-separator: '-_-_'; // Defaults to '--'\n\n### Suffixes\n\nBy default BEM Constructor uses `@` to denote suffixes (e.g. `.o-media@large`).\n\nYou can customize the suffix to whatever fits your needs:\n\n    $bem-suffix-namespace: '---'; defaults to '\\\\@'\n\n\n## \u003ca name=\"example\"\u003e\u003c/a\u003e :hamburger: The Burger Example™\n\n\n*Disclaimer: the following Sass code may not compile into a real burger.*\n\n````scss\n\n    @include object('burger') {\n        texture: juicy;\n\n        @include element('lettuce', 'tomato') {\n            quality: fresh;\n        }\n\n        @include element('cheese') {\n            type: gouda;\n\n            @include modifier('parmigiano') {\n                type: parmigiano;\n            }\n        }\n\n        @include element('extra-topping') {\n            ingredient: bacon;\n        }\n\n        @include element('meat') {\n            type: beef;\n        }\n\n        @include modifier('veggie') {\n            texture: smooth;\n\n            @include modifies-element('meat') {\n                type: lentils;\n            }\n\n            @include modifies-element('extra-topping') {\n                ingredient: avocado;\n\n                @include hack() {\n                    ingredient: bacon;\n                }\n            }\n        }\n\n        @include theme('mexican') {\n            spicy: hell-yeah;\n        }\n\n        @include state('cold') {\n            taste: terrible;\n        }\n\n        @include suffix('children') {\n            size: mini;\n        }\n    }\n````\n\nThe compiled CSS:\n\n````css\n\n    /* The main Burger object */\n    .o-burger { texture: juicy; }\n\n    /* Lettuce and Tomato elements */\n    .o-burger__lettuce, .o-burger__tomato { quality: fresh; }\n\n    /* Cheese element */\n    .o-burger__cheese { type: gouda; }\n\n    /* Cheese modifier */\n    .o-burger__cheese--parmigiano { type: parmigiano; }\n\n    /* Extra topping element */\n    .o-burger__extra-topping { ingredient: bacon; }\n\n    /* Meat element */\n    .o-burger__meat { type: beef; }\n\n    /* Veggie Burger block modifier */\n    .o-burger--veggie { texture: smooth; }\n\n    /* Veggie Burger block modifier modifies the Meat element too */\n    .o-burger--veggie .o-burger__meat { type: lentils; }\n\n    /* Veggie Burger block modifier modifies the Extra Topping element too */\n    .o-burger--veggie .o-burger__extra-topping { ingredient: avocado; }\n\n    /* But as hackers we couldn't resist the urge to add some Bacon back */\n    .o-burger--veggie ._o-burger__extra-topping { ingredient: bacon; }\n\n    /* When the party Theme is Mexican, we make everything spicy */\n    .t-mexican .o-burger { spicy: hell-yeah; }\n\n    /* And we're all sad when a burger Is Cold */\n    .o-burger.is-cold { taste: terrible; }\n\n    /* Mini burgers for children */\n    .o-burger\\@children { size: mini }\n\n````\n\n## Visual debugger\n\n![BEM constructor visual debugger](https://raw.githubusercontent.com/IPRIT/sass-bem/master/visual-debugger.png)\n\nPerform a visual healthcheck against your UI using the debugger mixin.\n\n### bem-debug($targets...)\n\n````scss\n@include bem-debug('modifiers', 'components'); // Outlines all modifiers and components\n````\n\n\nAvailable targets are `classes`,`modifiers`,`elements`,`objects`,`components`,`utilities` and `hacks`.\n\nUse it empty to outline all target types: `@include bem-debug();`\n\nCustomize outline styles by overriding the `$bem-debug-styles` map.\n\n````scss\n$bem-debug-styles: (\n    'classes'    : 5px solid #ddd,\n    'modifiers'  : 5px solid #aaa,\n    'elements'   : 5px solid #111,\n    'objects'    : 5px solid #FFDC00,\n    'components' : 5px solid #FF851B,\n    'utilities'  : 5px solid #0074D9,\n    'hacks'      : 5px solid #FF4136,\n);\n```\n\nExtended version of [bem-constructor](https://github.com/danielguillan/bem-constructor) by danielguillan.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiprit%2Fsass-bem","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fiprit%2Fsass-bem","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiprit%2Fsass-bem/lists"}