{"id":16527675,"url":"https://github.com/benoitzugmeyer/sans-sel","last_synced_at":"2026-06-08T11:01:56.898Z","repository":{"id":66068211,"uuid":"31596062","full_name":"BenoitZugmeyer/sans-sel","owner":"BenoitZugmeyer","description":"Write your components styles in JavaScript, without selectors.","archived":false,"fork":false,"pushed_at":"2017-07-30T11:09:04.000Z","size":169,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-26T13:54:20.692Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BenoitZugmeyer.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-03-03T11:57:11.000Z","updated_at":"2026-01-11T04:51:06.000Z","dependencies_parsed_at":"2023-06-10T09:15:31.258Z","dependency_job_id":null,"html_url":"https://github.com/BenoitZugmeyer/sans-sel","commit_stats":{"total_commits":134,"total_committers":2,"mean_commits":67.0,"dds":0.007462686567164201,"last_synced_commit":"0a2ae0404f5cef16735d553c21ff1742334871e9"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/BenoitZugmeyer/sans-sel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenoitZugmeyer%2Fsans-sel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenoitZugmeyer%2Fsans-sel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenoitZugmeyer%2Fsans-sel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenoitZugmeyer%2Fsans-sel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BenoitZugmeyer","download_url":"https://codeload.github.com/BenoitZugmeyer/sans-sel/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BenoitZugmeyer%2Fsans-sel/sbom","scorecard":{"id":21257,"data":{"date":"2025-08-11","repo":{"name":"github.com/BenoitZugmeyer/sans-sel","commit":"0a2ae0404f5cef16735d553c21ff1742334871e9"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.5,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 1/29 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: ISC License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v1.0.0-beta.5 not signed: https://api.github.com/repos/BenoitZugmeyer/sans-sel/releases/7111267","Warn: release artifact v1.0.0-beta.0 not signed: https://api.github.com/repos/BenoitZugmeyer/sans-sel/releases/4643050","Warn: release artifact v1.0.0-dev.0 not signed: https://api.github.com/repos/BenoitZugmeyer/sans-sel/releases/3641622","Warn: release artifact v1.0.0-beta.5 does not have provenance: https://api.github.com/repos/BenoitZugmeyer/sans-sel/releases/7111267","Warn: release artifact v1.0.0-beta.0 does not have provenance: https://api.github.com/repos/BenoitZugmeyer/sans-sel/releases/4643050","Warn: release artifact v1.0.0-dev.0 does not have provenance: https://api.github.com/repos/BenoitZugmeyer/sans-sel/releases/3641622"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"65 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-fwr7-v2mv-hh25","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-cwfw-4gq5-mrqx","Warn: Project is vulnerable to: GHSA-g95f-p29q-9xw4","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-9vvw-cc9w-f27h","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-h6ch-v84p-w6p9","Warn: Project is vulnerable to: GHSA-4gmj-3p3h-gm8h","Warn: Project is vulnerable to: GHSA-qrmc-fj45-qfc2","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-q42p-pg8m-cqh6","Warn: Project is vulnerable to: GHSA-w457-6q6x-cgp9","Warn: Project is vulnerable to: GHSA-62gr-4qp9-h98f","Warn: Project is vulnerable to: GHSA-f52g-6jhx-586p","Warn: Project is vulnerable to: GHSA-2cf5-4w76-r9qv","Warn: Project is vulnerable to: GHSA-3cqr-58rm-57f8","Warn: Project is vulnerable to: GHSA-g9r4-xpmj-mj65","Warn: Project is vulnerable to: GHSA-q2c6-c6pm-g3gh","Warn: Project is vulnerable to: GHSA-765h-qjxv-5f44","Warn: Project is vulnerable to: GHSA-f2jv-r9rf-7988","Warn: Project is vulnerable to: GHSA-44pw-h2cw-w3vq","Warn: Project is vulnerable to: GHSA-jp4x-w63m-7wgm","Warn: Project is vulnerable to: GHSA-c429-5p7v-vgjp","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-4hpf-3wq7-5rpr","Warn: Project is vulnerable to: GHSA-f522-ffg8-j8r6","Warn: Project is vulnerable to: GHSA-2pr6-76vf-7546","Warn: Project is vulnerable to: GHSA-8j8c-7jfh-h6hx","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-282f-qqgm-c34q","Warn: Project is vulnerable to: GHSA-fvqr-27wr-82fm","Warn: Project is vulnerable to: GHSA-4xc9-xhrj-v574","Warn: Project is vulnerable to: GHSA-x5rq-j2xg-h7qm","Warn: Project is vulnerable to: GHSA-jf85-cpcp-j695","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-f9cm-qmx5-m98h","Warn: Project is vulnerable to: GHSA-7wpw-2hjm-89gp","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-w9mr-4mfr-499f","Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p","Warn: Project is vulnerable to: GHSA-6394-6h9h-cfjg","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-6g33-f262-xjp4","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-4rq4-32rv-6wp6","Warn: Project is vulnerable to: GHSA-64g7-mvw6-v9qj","Warn: Project is vulnerable to: GHSA-2m39-62fm-q8r3","Warn: Project is vulnerable to: GHSA-mf6x-7mm4-x2g7","Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v","Warn: Project is vulnerable to: GHSA-g7q5-pjjr-gqvp","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-14T16:50:38.911Z","repository_id":66068211,"created_at":"2025-08-14T16:50:38.912Z","updated_at":"2025-08-14T16:50:38.912Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34059157,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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-10-11T17:36:25.622Z","updated_at":"2026-06-08T11:01:56.878Z","avatar_url":"https://github.com/BenoitZugmeyer.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"sans-sel\n========\n\n[![Build status](https://travis-ci.org/BenoitZugmeyer/sans-sel.svg?branch=master)](https://travis-ci.org/BenoitZugmeyer/sans-sel)\n\n*sans-sel* is a small but powerful library to help you write modular, reusable and maintainable CSS in JavaScript.\n\nFeatures\n--------\n\n- Style inheritance\n- Parametric style mixins\n- Most CSS features available (pseudo classes, pseudo elements, media queries)\n- Framework agnostic, no dependency\n- Universal JS capable\n- 2KB minified + gzipped\n\nGetting started\n---------------\n\n*sans-sel* is distributed as a single UMD file with no dependency.\n\nTwo choices:\n\n- if you are using a bundler (ex: Webpack, Browserify, Rollup...), install it via `npm install sans-sel` ;\n- else, download it from the [Github release page](https://github.com/BenoitZugmeyer/sans-sel/releases) and include it with a `\u003cscript\u003e` tag (will expose a global `sansSel` variable) or load it with a AMD loader.\n\nDead simple example:\n\n```js\n// Create a root namespace\nconst styles = sansSel();\n\n// Define some CSS rules\nstyles.addRules({\n\n  // \"button\" is the rule name\n  button: {\n    border: \"1px solid #888\",\n    backgroundColor: \"#ccc\",\n\n    // Here is a pseudo class\n    hover: {\n      backgroundColor: \"#ddd\"\n    }\n  }\n});\n\nconst button = document.createElement(\"button\");\n\n// Apply the rule to an element by rendering a className\nbutton.className = styles(\"button\");\n\ndocument.body.appendChild(button);\n```\n\nAPI\n---\n\n- [`sansSel(...)`](#api-create) ∼ create a *sans-sel* object\n- [`sansSelObject.namespace(...)`](#api-namespace) ∼ create a *sans-sel* object inheriting from the current one\n- [`sansSelObject.addRule(...)`](#api-rule) ∼ define a rule\n- [`sansSelObject.addTransform(...)`](#api-transform) ∼ define a transform\n- [`sansSelObject(...)`](#api-render) ∼ render specified rules\n\n### \u003ca name=\"api-create\"\u003e\u003c/a\u003e `sansSel({ name: \"\", backend: defaultBackend }={})`\n\nCreate a root *sans-sel* object. A *sans-sel* object is a function with some extra methods. You can start by defining [transforms](#api-transform) and [rules](#api-rule), then [call it](#api-render) to get rendered rules.\n\n`name` is optional, but you can't create multiple *sans-sel* object with the same name. You probably don't need multiple root *sans-sel* objects in one project: you should use the [namespace method](#namespace) instead.\n\n`backend` is also optional. It defaults to a simple backend rendering the rules into a private DOM stylesheet injected in the document head. You can easily write your own backend to change this behavior: a backend is only a function that will be called with a string representing a CSS rule as argument.\n\nFor example, you could want to render your components on the server side (isomorphic, universal, whatever you call it):\n\n```js\nconst styleSheetContent = \"\";\n\nfunction isomorphicBackend(rule) {\n  styleSheetContent += rule;\n}\n\nconst styles = sansSel({ backend: isomorphicBackend });\n\n// render your components ...\n\n// ... then print styleSheetContent between \u003cstyle\u003e tags\n```\n\n### \u003ca name=\"api-namespace\"\u003e\u003c/a\u003e `sansSelObject.namespace(name)`\n\nCreate a *sans-sel* object inheriting from the current one.\n\nThe `name` is mandatory and should be unique among other namespaces created by the current *sans-sel* object. If you'll use the new object to style a component, you could use the component name as a namespace name.\n\nIt returns the newly created *sans-sel* object.\n\nThe new *sans-sel* object inherits rules and transforms from the parent ones. A rule can inherit from another rule defined in the current *sans-sel* object or any of its parent with the `inherit` property. Example:\n\n```js\nconst root = sansSel();\n\nroot.addTransform(\"darkBackground\", {\n  backgroundColor: \"#333\",\n  color: \"#fff\"\n});\n\nroot.addRule(\"button\", {\n  border: \"none\"\n});\n\n// Elsewhere...\n\nconst styles = root.namespace(\"DarkButton\");\n\nstyles.addRule(\"button\", {\n  inherit: \"button\",\n  darkBackground: true\n});\n\n// equivalent to\nstyles.addRule(\"button\", {\n  border: \"none\",\n  backgroundColor: \"#333\",\n  color: \"#fff\"\n});\n```\n\n### \u003ca name=\"api-rule\"\u003e\u003c/a\u003e `sansSelObject.addRule(name, declarations)`\n\n### `sansSelObject.addRules({ [name]: declarations ... })`\n\nDefine a rule or a set of rules.\n\n`name` is a string identifying the rule and should be unique inside the *sans-sel* object (root or namespace).\n\n`declarations` is a plain object. If a property value is an object, it will be treated as a pseudo class or a media query. Else, it will be treated as a CSS property. You can specify fallback values by using an array.\n\nIt returns the current *sans-sel* object.\n\nTo allow a more concise syntax, pseudo-classes will be automatically prefixed by a double colon, and pseudo-elements starting with a dollar sign will be prefixed by two double colons.\n\nExample:\n\n```js\nstyles.addRule(\"button\", {\n  // property\n  color: \"red\",\n\n  // property with fallback values\n  display: [\"flex\", \"-ms-flex\", \"inline\"],\n\n  // pseudo class\n  hover: {\n    color: \"blue\"\n  },\n\n  // pseudo element\n  $firstLetter: {\n    color: \"red\"\n  },\n\n  // media query\n  \"@media only screen\": {\n    color: \"green\"\n  }\n});\n```\n\n### \u003ca name=\"api-transform\"\u003e\u003c/a\u003e `sansSelObject.addTransform(name, definition)`\n\n### `sansSelObject.addTransforms({ [name]: definition ... })`\n\nDefine a transform or a set of transforms.\n\n`name` is a string identifying the transform and should be unique inside the *sans-sel* object (root or namespace).\n\n`definition` is either a plain object or a function returning a plain object. The transform will be triggered when a rule contains a property name equal to the transform name.\n\nIt returns the current *sans-sel* object.\n\nIf the definition is a function, it will be called with the property value as argument. If the returned value is a plain object, it will replace the property in the rule declaration, otherwise it will be ignored.\n\nIf the definition is invariant, it can be supplied directly as a plain object. This object will replace the property in the rule declaration only if the property value is truthy.\n\nThe property replacement is done in-place: property order is conserved.\n\nThe object replacing the property can also trigger transforms, but recursion will be avoided (a transform can't be triggered by the object it returns). Transforms are memoized according to the JSON value of the argument.\n\nTransforms are quite flexible and may serve multiple purposes. Common usages includes style mixins and automatic vendor prefixes.\n\nExample of mixin transforms:\n\n```js\n// Variable transform\nstyles.addTransform(\"foo\", (color) =\u003e {\n  return {\n    color: color,\n    borderRight: `1px solid ${color}`,\n  }\n})\n\n// Invariable transform\nstyles.addTransform(\"blueFoo\", {\n  foo: \"blue\",\n})\n\nstyles.addRule(\"link\", {\n  fontWeight: \"bold\",\n  blueFoo: true,\n})\n\n/* Is equivalent to\n.\u003clink\u003e {\n  font-weight: bold;\n  color: blue;\n  border-right: 1px solid blue;\n}\n*/\n```\n\nExample of vendor prefixing transforms:\n\n```js\nstyles.addTransforms({\n  flex(value) {\n    return {\n      flex: value,\n      WebkitFlex: value,\n    }\n  },\n\n  display(value) {\n    if (value === \"flex\") {\n      value = [ \"-webkit-flex\", \"flex\" ]\n    }\n    return { display: value }\n  }\n})\n\nstyles.addRule(\"root\", {\n  display: \"flex\",\n  flex: 1,\n})\n\n/* is equivalent to:\n.\u003croot\u003e {\n  display: -webkit-flex;\n  display: flex;\n  -webkit-flex: 1;\n  flex: 1;\n}\n*/\n```\n\n### \u003ca name=\"api-render\"\u003e\u003c/a\u003e `sansSelObject(...rules)`\n\nRender specified rules.\n\nThe `rules` arguments are either rule names or rendered rules coming from another *sans-sel* object. Arguments may be nested in arrays and falsy values are ignored.\n\nIt returns an opaque object with a `toString()` method. To apply those rules to an element, simply use the string value of this object as a `className`.\n\nContrary to standard class name lists, the order matters: rules specified later takes precedence over previous rules.\n\nApplying a rule to an element:\n\n```js\nstyles.addRule(\"body\", {\n  backgroundColor: \"rebeccapurple\"\n});\n\ndocument.body.className = styles(\"body\");\n```\n\nApplying rules to an element conditionally:\n\n```js\nstyles.addRules({\n  base: {\n    color: \"red\"\n  },\n  blue: {\n    color: \"blue\"\n  }\n});\n\nfunction createButton({ isBlue }) {\n  const button = document.createElement(\"button\");\n\n  button.className = styles(\"base\", isBlue \u0026\u0026 \"blue\");\n\n  return button;\n}\n```\n\nPassing extra rules to a component:\n\n```js\nstyles.addRules(\"base\", {\n  color: \"red\"\n});\n\nfunction createButton({ style }) {\n  const button = document.createElement(\"button\");\n\n  button.className = styles(\"base\", style);\n\n  return button;\n}\n\n// Elsewhere...\n\notherStyles.addRule(\"specialButton\", {\n  color: \"green\"\n});\n\ndocument.body.appendChild(\n  createButton({ style: otherStyles(\"specialButton\") })\n);\n```\n\nArgument flattening example:\n\n```js\nconst rules = styles(\"foo\", [\"bar\", null, [\"baz\"]]);\n// is equivalent to\nconst rules = styles(\"foo\", \"bar\", \"baz\");\n```\n\nHints\n=====\n\nAlways define rules statically, for example when the JS module is executed. *sans-sel* is \"append\nonly\" and won't clear unused styles, so if you add the same rules multiple times, memory will be\nleaked and perfs will be degraded.\n\nYou can still use standard CSS (ex: to define `@keyframes`) or inline styles (ex: for JS driven\nanimations).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenoitzugmeyer%2Fsans-sel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenoitzugmeyer%2Fsans-sel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenoitzugmeyer%2Fsans-sel/lists"}