{"id":26221734,"url":"https://github.com/push-based/recalc-styles-research","last_synced_at":"2025-08-26T14:07:28.947Z","repository":{"id":77496401,"uuid":"489992849","full_name":"push-based/recalc-styles-research","owner":"push-based","description":null,"archived":false,"fork":false,"pushed_at":"2022-07-13T23:08:25.000Z","size":131,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-19T20:48:23.954Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/push-based.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":"2022-05-08T16:13:06.000Z","updated_at":"2022-07-07T14:12:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"82ccec01-cde0-4d5b-ba68-eed3883a2fe9","html_url":"https://github.com/push-based/recalc-styles-research","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/push-based/recalc-styles-research","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/push-based%2Frecalc-styles-research","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/push-based%2Frecalc-styles-research/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/push-based%2Frecalc-styles-research/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/push-based%2Frecalc-styles-research/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/push-based","download_url":"https://codeload.github.com/push-based/recalc-styles-research/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/push-based%2Frecalc-styles-research/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272227799,"owners_count":24895685,"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-08-26T02:00:07.904Z","response_time":60,"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":"2025-03-12T16:29:20.853Z","updated_at":"2025-08-26T14:07:28.941Z","avatar_url":"https://github.com/push-based.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Recalculate Styles - Research\n\n## Test\n\nTo check the specificity of a selector in the CLI run:\n```bash\nnpx specificity \u003cselectors\u003e\n```\n\nThis will return the specificity as array. e.g. `npx specificity .test` returns `0,0,1,0`;\n\n\n## Results:\n\n### The total amount of styles is irrelevant\n\nProof: add the following styles x times to the head of an application and trigger recalculate styles\non any element.\n\n```css\n.dummy${i}{color:red;display:block;border:1px solid blue;}\n```\n\n\u003e This means, the work being done by recalculate styles is always only related to DOM nodes which \n\u003e are actually affected by a change\n\n### The total amount of DOM is irrelevant\n\nThe total amount of DOM is irrelevant for the style recalculations. It is only relevant _where_ the styles\nare applied in the DOM.\n\n### The amount of children of a Node affects recalculate styles\n\nThe recalculate styles effort grows with the depth of a node targeted by a change.\nToggling a class on a node with many children does create more work for the browser compared to a node\nwith no children.\n\ne.g.\nToggling a class on `deeply-nested` will cause less styles recalculations compared to toggling the class\non the `div` element\n\nWe assume this behavior is described as [`Descendant Invalidation Sets`](https://docs.google.com/document/d/1vEW86DaeVs4uQzNFI5R-_xS9TcS1Cs_EUsHRSgCHGu8/edit#bookmark=id.mh94lek836rn)\n\n```html\n\u003cdiv\u003e\n  \u003cnested\u003e\n    \u003cnested\u003e\n      \u003cnested\u003e\n        \u003cdeeply-nested\u003e\u003c/deeply-nested\u003e\n      \u003c/nested\u003e\n    \u003c/nested\u003e\n  \u003c/nested\u003e\n\u003c/div\u003e\n```\n\n```css\n/* A lot of work */\ndiv.active {\n color: red; \n}\n\n/* less work then above */\ndeeply-nested.active {\n  color: red;\n}\n```\n\n### Changes of the selector of an element cause work that is independent of the work needed to apply styles to the decendents\n\nThis finding stays in contrast to `The amount of children of a Node affects recalculate styles`.\nApplying a style change to a container causing one of its children to be affected always costs the \nsame amount of style recalculation work, regardless of its depth.\n\ne.g.\nToggling a class on `div` will always cause the same amount of style recalculations regardless of it's nested children and the nesting level.\n \n\n```html\n\u003cdiv\u003e\n  \u003cnested id=\"first\"\u003e\n    \u003cnested\u003e\n      \u003cnested\u003e\n        \u003cdeeply-nested\u003e\u003c/deeply-nested\u003e\n      \u003c/nested\u003e\n    \u003c/nested\u003e\n  \u003c/nested\u003e\n\u003c/div\u003e\n```\n\nThe following style changes will result in the same style recalculation work:\n\n```css\ndiv.active #first {\n color: red; \n}\n\n/* same work as */\ndiv.active deeply-nested {\n  color: red;\n}\n```\n\n## Assumptions without a demo:\n\n**Styles**:\n* amount of total rules shipped by styles of application that are applicable to a existing DOM node  \n* cardinality\n  * id \u003e class \u003e tag\n* specificity of style rule\n* selector\n  * :not(:has(:is(nth-of(...))))\n  * there are selectors that are harder to compute than others\n\n**DOM**:\n* amount of currently affected DOM nodes (selector change) and its children\n  * checked\n* nesting depth\n\n## Improvements for the click demo\n\n* input box to change applied class on items\n* text-area for css rules on item\n\n\n# Documentation\n\n## Code samples\n\n## Slides\n\n## Specificity\n* https://developer.mozilla.org/de/docs/Web/CSS/Specificity\n* https://levelup.gitconnected.com/how-to-understand-css-specificity-2caabc5f67a9\n* https://dev.to/coderarchive/css-specificity-explained-4n31\n* https://specificity.keegan.st/\n\n## General\n* 💪 https://docs.google.com/document/d/1vEW86DaeVs4uQzNFI5R-_xS9TcS1Cs_EUsHRSgCHGu8/view#heading=h.v5uqxeqtd5uh\n* https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/core/css/style-invalidation.md \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpush-based%2Frecalc-styles-research","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpush-based%2Frecalc-styles-research","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpush-based%2Frecalc-styles-research/lists"}