{"id":21594440,"url":"https://github.com/meduzen/v-helper","last_synced_at":"2025-09-09T19:12:03.312Z","repository":{"id":57389952,"uuid":"157694896","full_name":"meduzen/v-helper","owner":"meduzen","description":"A shorter SCSS access to CSS custom properties.","archived":false,"fork":false,"pushed_at":"2024-02-02T22:47:45.000Z","size":39,"stargazers_count":16,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-08-03T02:49:07.879Z","etag":null,"topics":["css","css-custom-properties","css-variables","sass","scss","scss-function"],"latest_commit_sha":null,"homepage":"https://dev.to/meduzen/write-css-variables-faster-in-scss-1mon","language":"SCSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"wtfpl","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/meduzen.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,"zenodo":null}},"created_at":"2018-11-15T10:41:24.000Z","updated_at":"2024-12-19T19:23:34.000Z","dependencies_parsed_at":"2025-04-10T23:42:00.807Z","dependency_job_id":"c1e88490-9ab8-4c5e-8375-27769ebc9d23","html_url":"https://github.com/meduzen/v-helper","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/meduzen/v-helper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meduzen%2Fv-helper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meduzen%2Fv-helper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meduzen%2Fv-helper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meduzen%2Fv-helper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/meduzen","download_url":"https://codeload.github.com/meduzen/v-helper/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meduzen%2Fv-helper/sbom","scorecard":{"id":634542,"data":{"date":"2025-08-11","repo":{"name":"github.com/meduzen/v-helper","commit":"aa62ad4898a72154f7a74da661b09dbe498c3f5d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"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":"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":"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":"Code-Review","score":0,"reason":"Found 0/22 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":"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":"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":"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":"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":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Do What The F*ck You Want To Public 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":-1,"reason":"no releases found","details":null,"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 'main'"],"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 15 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"}}]},"last_synced_at":"2025-08-21T08:45:48.464Z","repository_id":57389952,"created_at":"2025-08-21T08:45:48.464Z","updated_at":"2025-08-21T08:45:48.464Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274347949,"owners_count":25268971,"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","status":"online","status_checked_at":"2025-09-09T02:00:10.223Z","response_time":80,"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":["css","css-custom-properties","css-variables","sass","scss","scss-function"],"created_at":"2024-11-24T17:18:21.980Z","updated_at":"2025-09-09T19:12:03.270Z","avatar_url":"https://github.com/meduzen.png","language":"SCSS","funding_links":[],"categories":[],"sub_categories":[],"readme":"# v.scss\n\n`v.scss` brings a single SCSS function for shorter access (4 characters saved!) to [CSS custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/var) : `v(propName)` instead of `var(--propName)`. It also improves fallbacks chaining.\n\n\u003e [!NOTE]  \n\u003e This helper has cool features, but I have decided to not use it outside of personal projects. Compared to IDE auto-completion, its benefits might not be worth the cognitive load linked to an additional abstraction.\n\n## Table of contents\n\n- [Installation](#installation)\n- [Usage](#usage)\n  - [Fallback value as optional second parameter](#fallback-value-as-optional-second-parameter)\n  - [Multiple fallbacks](#multiple-fallbacks)\n- [Edge cases](#edge-cases)\n  - [SCSS interpolation](#scss-interpolation)\n  - [`--` is a valid custom property name](#---is-a-valid-custom-property-name)\n- [Changelog](#changelog)\n- [Seel also](#see-also)\n\n## Installation\n\n1. `npm install v.scss` pulls the package into your project.\n2. `@import '~v.scss';` in a SCSS files makes `v()` available.\n\n## Usage\n\nDeclare your CSS custom properties as you usually do:\n```css\n:root {\n  --primary: #000;\n  --bg: #fff;\n}\n```\nThen, access them with `v()`.\n```scss\nhtml {\n  background: v(bg);\n  color: v(primary);\n}\n```\nThat’s it! Here’s the generated CSS:\n\n```css\nhtml {\n  background: var(--bg);\n  color: var(--primary);\n}\n```\n\n### Fallback value as optional second parameter\n\nThe CSS `var()` function can take a fallback value as second parameter: if the wanted custom property isn’t defined or valid for the browser, the fallback will be used.\n\n```scss\n:root {\n  --primary: cyan;\n  --bg: #433221;\n}\n\nhtml {\n  background: v(bg, brown); // `background: var(--bg, brown);`\n  color: v(primaryyyy, yellow); // `color: var(--primaryyyy, yellow);`\n}\n```\n\nThe `background` will be `#433221` (`--bg` value) but the `color` will be `yellow` because `--primaryyyy` doesn’t exist.\n\n\u003e **Note**\n\u003e\n\u003e If you need the last parameter to be a string, wrap its quotes in more quotes:\n\u003e\n\u003e ```scss\n\u003e .shrug::after {\n\u003e   content: v(shrug-emoji, \"'¯\\_(ツ)_/¯'\"); /* double quotes around single ones */\n\u003e\n\u003e   // generates\n\u003e   content: var(--shrug-emoji, '¯\\_(ツ)_/¯'); /* single quotes */\n\u003e }\n\u003e ```\n\u003e\n\u003e You can swap double and single quotes. CSS will be fine.\n\n### Multiple fallbacks\n\nYou can have multiple fallbacks by chaining multiple custom properties names. The last parameter is always a fallback value.\n\n```scss\nhtml {\n  color: v(primary, accent, bg, #f0f0f0);\n\n  // generates\n  color: var(--primary, var(--accent, var(--bg, #f0f0f0)));\n}\n```\n\nIf you need the last parameter to not be a fallback value, replace it by `null`:\n\n```scss\nhtml {\n  color: v(primary, accent, null);\n\n  // generates\n  color: var(--primary, var(--accent));\n}\n```\n\n\u003e **Note**\n\u003e\n\u003e If you need [a list of values to not be considered as fallback](https://github.com/meduzen/v-helper/issues/8), wrap them in quotes: as described [in a comment](https://github.com/meduzen/v-helper/issues/8#issuecomment-1368505230), the list will be considered as one value, and the quotes will be stripped.\n\u003e\n\u003e ```scss\n\u003e .my-class {\n\u003e   transition-property: v(transition-properties, 'opacity, visibility');\n\u003e\n\u003e   // generates\n\u003e   transition-property: var(--transition-properties, opacity, visibility);\n\u003e }\n\u003e ```\n\n## Edge cases\n\n### SCSS interpolation\n\nIn order to assign a value to a custom property using a SCSS variable or a SCSS function, [interpolation](https://github.com/sass/sass/issues/2516) is required:\n```scss\n$primary: #000;\n\n.my-class {\n  --primary: $primary; // error 🚫, custom property assignment needs interpolation\n  --primary: #{$primary}; // correct ✅, value interpolated with `#{}`\n  --primary: #000; // correct ✅, regular syntax\n\n  --accent: v(secondary); // error 🚫, custom property assignment needs interpolation\n  --accent: #{v(secondary)}; // correct ✅, function interpolated\n  --accent: var(--secondary); // correct ✅, regular syntax\n\n  color: v(accent); // correct ✅, `color` is not a custom property\n}\n```\n\nInterpolation means “Have a look at `#{what is inside the curly braced}` and replace the `$value-string` by its computed value (`$000`)”.\n\nIn situations where interpolation is needed, using `v()` is less readable (`#{v(propName)}`) than the standard syntax (`var(--propName)`).\n\n### `--` is a valid custom property name\n\nIt turns out that [`--` is a valid name for a CSS custom property](https://twitter.com/alexzaworski/status/1127688935541338112).\n\nDeclaring and using it is all about edge cases:\n```scss\n.my-class {\n  --: .5; // error 🚫\n  --#{''}: .5; // correct ✅\n  #{'--'}: .5; // correct ✅\n\n  opacity: var(--); // error 🚫\n  opacity: var(#{'--'}); // correct ✅\n  opacity: v(); // correct ✅, thanks to v() ✌️\n}\n```\n\nAnother example, with three dashes:\n```scss\n.my-class-with-more-dashes {\n  --#{'-'}: .5; // correct ✅\n  #{'---'}: .5; // correct ✅\n\n  opacity: var(#{'---'}); // correct ✅, interpolated\n  opacity: v('-'); // correct ✅, thanks to v() ✌️\n}\n```\n\n## Changelog\n\nSee [releases](https://github.com/meduzen/v-helper/releases).\n\n## See also\n\n- Custom properties [on Can I Use](https://caniuse.com/#feat=css-variables).\n- [davidkpiano/sass-v](https://github.com/davidkpiano/sass-v), a similar project with more features, done way before mine 🤭.\n- [malyw/css-vars](https://github.com/malyw/css-vars), a SCSS mixin allowing you to start writing some CSS custom properties even if the browsers you target don’t support them.\n- [postcss-custom-properties](https://github.com/postcss/postcss-custom-properties), a PostCSS plugin with a similar purpose.\n- [_Dark theme in a day_](https://medium.com/@mwichary/dark-theme-in-a-day-3518dde2955a), an all-round article with a lot of CSS custom properties.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeduzen%2Fv-helper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeduzen%2Fv-helper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeduzen%2Fv-helper/lists"}