{"id":16500239,"url":"https://github.com/toomuchdesign/postcss-nested-ancestors","last_synced_at":"2025-04-07T05:13:30.174Z","repository":{"id":8599820,"uuid":"59005237","full_name":"toomuchdesign/postcss-nested-ancestors","owner":"toomuchdesign","description":"👩‍👧‍👦 PostCSS plugin to reference any parent/ancestor selector in nested CSS.","archived":false,"fork":false,"pushed_at":"2024-04-14T11:03:55.000Z","size":388,"stargazers_count":100,"open_issues_count":7,"forks_count":5,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-04-14T15:24:03.513Z","etag":null,"topics":["ancestor-selector","css-selectors","postcss-plugins"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/toomuchdesign.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2016-05-17T08:39:51.000Z","updated_at":"2024-05-01T02:35:26.605Z","dependencies_parsed_at":"2023-11-16T04:28:13.094Z","dependency_job_id":"4c105d2e-5829-435b-8155-cb8331fe81cc","html_url":"https://github.com/toomuchdesign/postcss-nested-ancestors","commit_stats":{"total_commits":121,"total_committers":7,"mean_commits":"17.285714285714285","dds":0.5041322314049587,"last_synced_commit":"1d2d70d43a8fdc0707911e22ca689b093c6c9f21"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toomuchdesign%2Fpostcss-nested-ancestors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toomuchdesign%2Fpostcss-nested-ancestors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toomuchdesign%2Fpostcss-nested-ancestors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toomuchdesign%2Fpostcss-nested-ancestors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/toomuchdesign","download_url":"https://codeload.github.com/toomuchdesign/postcss-nested-ancestors/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247595335,"owners_count":20963943,"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":["ancestor-selector","css-selectors","postcss-plugins"],"created_at":"2024-10-11T14:56:29.105Z","updated_at":"2025-04-07T05:13:30.155Z","avatar_url":"https://github.com/toomuchdesign.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PostCSS Nested ancestors\n\n[![Build status][ci-badge]][ci]\n[![Npm version][npm-version-badge]][npm]\n[![Test coverage report][coveralls-badge]][coveralls]\n\n[PostCSS] plugin to reference any parent ancestor selector in nested CSS.\n\n## Getting ancestor selectors\n\nWhen writing modular nested CSS, `\u0026` current parent selector is often not enough.\n\n**PostCSS Nested ancestors** introduces `^\u0026` selector which let you reference **any parent ancestor selector** with an easy and customizable interface.\n\nThis plugin should be used **before** a PostCSS rules unwrapper like [postcss-nested].\n\nSee [PostCSS] docs for examples for your environment.\n\n### Ancestor selectors schema\n\n```\n    .level-1 {\n|   |   .level-2 {\n|   |   |   .level-3 {\n|   |   |   |   .level-4 {\n|   |   |   |   |\n|   |   |   |   --- \u0026 {}        /*      \u0026 = \".level-1 .level-2 .level-3 .level-4\" */\n|   |   |   ------- ^\u0026 {}       /*     ^\u0026 = \".level-1 .level-2 .level-3\"          */\n|   |   ----------- ^^\u0026 {}      /*    ^^\u0026 = \".level-1 .level-2\"                   */\n|   --------------- ^^^\u0026 {}     /*   ^^^\u0026 = \".level-1\"                            */\n------------------- ^^^^\u0026 {}    /*  ^^^^\u0026 = \"\"                                    */\n                }\n            }\n        }\n    }\n```\n\n### A real example\n\n```css\n/* Without postcss-nested-ancestors */\n.MyComponent\n    \u0026-part{}\n    \u0026:hover {\n        \u003e .MyComponent-part {} /* Must manually repeat \".MyComponent\" for each child */\n    }\n}\n\n/* With postcss-nested-ancestors */\n.MyComponent\n    \u0026-part{}\n    \u0026:hover {\n        \u003e ^\u0026-part {} /* Skip \":hover\" inheritance here */\n    }\n}\n\n/* After postcss-nested-ancestors */\n.MyComponent {\n    \u0026-part{}\n    \u0026:hover {\n        \u003e .MyComponent-part {}\n}\n\n/* After postcss-nested */\n.MyComponent {}\n.MyComponent-part {}\n.MyComponent:hover {}\n.MyComponent:hover \u003e .MyComponent-part {} /* No \":hover\" inheritance here! */\n\n```\n\n## Why?\n\nCurrently another plugin - [postcss-current-selector] - has tried to solve the problem of referencing ancestors selector. It works great, but its approach involves assigning ancestor selectors to special variables to be later processed by a further postcss plugin [postcss-simple-vars].\n\n**PostCSS Nested ancestors** instead replaces special ancestor selectors, makes no use of variable assignment and produces an output ready to be unwrapped with [postcss-nested].\n\n## Installation\n\n```console\n$ npm install --save-dev postcss postcss-nested-ancestors\n```\n\n## Usage\n\n```js\npostcss([require('postcss-nested-ancestors')]);\n```\n\n## Options\n\n### placeholder\n\nType: `string`\nDefault: `^\u0026`\n\nAncestor selector pattern (utility option to automatically set both `levelSymbol` and `parentSymbol`)\n\n### levelSymbol\n\nType: `string`\nDefault: `^`\n\nDefine ancestor selector fragment relative to the matching nesting level\n\n### parentSymbol\n\nType: `string`\nDefault: `\u0026`\n\nAncestor selector base symbol\n\n### replaceDeclarations (experimental)\n\nType: `boolean`\nDefault: `false`\n\nIf this is true then this plugin will look through your declaration values for the placeholder symbol and replace them with specified selector.\n\nAn use case for this if enabling [postcss-ref](https://github.com/morishitter/postcss-ref) to work with dynamic `@ref` selectors. Read discussion [here](https://github.com/toomuchdesign/postcss-nested-ancestors/pull/3).\n\n```css\n/* Before */\n.foo {\n  \u0026:last-child {\n    border-top: ref(^\u0026, border-bottom);\n  }\n}\n\n/* After PostCSS Nested ancestors and PostCSS Nested */\n.foo {\n}\n\n.foo:last-child {\n  border-top: ref(.foo, border-bottom);\n}\n```\n\n## Known issues\n\n### Multiple ancestor placeholders in same selector\n\nThis plugin currently fails when trying to replace **more than one different ancestor placeholder in a single rule selector**. This scenario has not been considered in order to not bloat the code with a remote use case.\n\nMore precisely, all ancestor placeholders are replaced, but processed as if they where the equal to the first ancestor placeholder found in selector.\n\nIn general, **do not use more than one ancestor placeholder in a single rule selector**. Anyway, this use case can be rewritten by **splitting the selectors in multiple nested rules** (see edge case 2).\n\n#### Edge case 1 (success)\n\n```css\n/* 2 equal ancestor placeholders in single rule selector */\n.a {\n  \u0026:hover {\n    ^\u0026^\u0026-b {\n    }\n  }\n}\n\n/* Output: It works but casts a warning */\n.a {\n  \u0026:hover {\n    .a.a-b {\n    }\n  }\n}\n```\n\n#### Edge case 2 (failing)\n\n```css\n/* 2 different ancestor placeholders in single rule selector */\n.a {\n  \u0026-b {\n    \u0026:hover {\n      /* Will be processed as ^\u0026^\u0026-c{}, sorry! */\n      ^\u0026^^\u0026-c {\n      }\n    }\n  }\n}\n\n/* Wrong output: All placeholder replaced with the value of the first one */\n.a {\n  \u0026-b {\n    \u0026:hover {\n      /* Expected output: .a-b.a-c{}*/\n      .a-b.a-b-c {\n      }\n    }\n  }\n}\n\n/* This use case can be rewritten as: */\n.a {\n  \u0026-b {\n    \u0026:hover {\n      ^\u0026 {\n        \u0026^^^\u0026-c {\n        }\n      }\n    }\n  }\n}\n```\n\n### Replace declaration values in complex nesting scenarios\n\n`replaceDeclarations` options used in a complex nesting scenario might have undesired outputs because of the different nature of CSS selectors and and declaration values.\n\nIn general, avoid replacing declaration values when inside a rule with multiple selectors (but why should you?). In other words don't get yourself into trouble!\n\nHere is an example of what you don't want to do.\n\n```css\n/* Don't replace declaration value inside multiple selector rules */\n.a1,\n.a2 {\n  \u0026:hover {\n    \u0026:before {\n      content: '^^\u0026';\n    }\n  }\n}\n\n/* Output */\n.a1,\n.a2 {\n  \u0026:hover {\n    \u0026:before {\n      content: '.a1,.a2';\n    }\n  }\n}\n```\n\n## Contributing\n\nContributions are super welcome, but please follow the conventions below if you want to do a pull request:\n\n- Create a new branch and make the pull request from that branch\n- Each pull request for a single feature or bug fix\n- If you are planning on doing something big, please discuss first with [@toomuchdesign](http://www.twitter.com/toomuchdesign) about it\n- Update tests (`test.js`) covering new features\n\n## Todo's\n\n- Better comment source code\n\n[postcss]: https://github.com/postcss/postcss\n[ci-badge]: https://github.com/toomuchdesign/postcss-nested-ancestors/actions/workflows/ci.yml/badge.svg\n[ci]: https://github.com/toomuchdesign/postcss-nested-ancestors/actions/workflows/ci.yml\n[coveralls-badge]: https://coveralls.io/repos/github/toomuchdesign/postcss-nested-ancestors/badge.svg?branch=master\n[coveralls]: https://coveralls.io/github/toomuchdesign/postcss-nested-ancestors?branch=master\n[npm]: https://www.npmjs.com/package/postcss-nested-ancestors\n[npm-version-badge]: https://img.shields.io/npm/v/postcss-nested-ancestors.svg\n[postcss-current-selector]: https://github.com/komlev/postcss-current-selector\n[postcss-nested]: https://github.com/postcss/postcss-nested\n[postcss-simple-vars]: https://github.com/postcss/postcss-simple-vars\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoomuchdesign%2Fpostcss-nested-ancestors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftoomuchdesign%2Fpostcss-nested-ancestors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoomuchdesign%2Fpostcss-nested-ancestors/lists"}