{"id":19206866,"url":"https://github.com/html-next/optimizing-css-compiler","last_synced_at":"2025-07-02T21:37:35.877Z","repository":{"id":66281338,"uuid":"89196438","full_name":"html-next/optimizing-css-compiler","owner":"html-next","description":"CSS: but easier and faster","archived":false,"fork":false,"pushed_at":"2018-01-18T20:34:51.000Z","size":79,"stargazers_count":8,"open_issues_count":4,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-15T11:43:13.113Z","etag":null,"topics":["css","ember","ember-cli","glimmerjs","postcss","postcss-plugin","scoped-css"],"latest_commit_sha":null,"homepage":null,"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/html-next.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2017-04-24T04:03:45.000Z","updated_at":"2022-05-30T00:48:55.000Z","dependencies_parsed_at":"2023-07-08T03:46:14.634Z","dependency_job_id":null,"html_url":"https://github.com/html-next/optimizing-css-compiler","commit_stats":{"total_commits":10,"total_committers":2,"mean_commits":5.0,"dds":0.09999999999999998,"last_synced_commit":"5de8a86a30ed7793d4d5a88b5c2985af63509cfe"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/html-next/optimizing-css-compiler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/html-next%2Foptimizing-css-compiler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/html-next%2Foptimizing-css-compiler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/html-next%2Foptimizing-css-compiler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/html-next%2Foptimizing-css-compiler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/html-next","download_url":"https://codeload.github.com/html-next/optimizing-css-compiler/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/html-next%2Foptimizing-css-compiler/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260747478,"owners_count":23056507,"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":["css","ember","ember-cli","glimmerjs","postcss","postcss-plugin","scoped-css"],"created_at":"2024-11-09T13:17:15.016Z","updated_at":"2025-07-02T21:37:35.816Z","avatar_url":"https://github.com/html-next.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [WIP] optimizing-css-compiler\n\nWhat does a little convention get you? A lot, as it turns out.\n\nWhen following the conventions listed below, the Optimizing CSS Compiler\n will be able to aggressively optimize, compile and minify your CSS by\n taking the following steps:\n \n- builds a broccoli tree of handlebars templates and styles\n- constructs a graph of all possible style paths in your CSS files\n- constructs a new graph of all used style paths in your handlebars files\n- compiles css down to the smallest possible set of rules.\n- applies those rules to the templates, removing any existing classes\n- writes a style sheet containing the rules\n\n## The Guidelines\n\n- **Don't expect this to work (because it doesn't yet)**\n- Do contribute if you find this neat, ask in #dev-html-next in the Ember Slack\n- Componetize your CSS\n- Use `\u0026` for the component root element\n- Tag dynamic selectors (things to leave alone) with `@dynamic` or `/* @dynamic */`\n- Do assume your CSS is scoped by template context (route or component hbs file)\n\n## Things that don't work yet (but will)\n\n- **Everything! (but the basic cases are getting close to working)**\n- media-queries and breakpoints\n- CSS preprocessors\n- class names within `component.js` files (yet! a subset of usage in this pattern will eventually be allowed)\n- !important` (it'll still work, you just shouldn't)\n- global CSS\n-  `::pseudo-element` and `:pseudo-class` selectors\n\n## CSS\n\n- use mixins, not global selectors\n- no attr selectors\n- no sibling selectors\n- no ID selectors\n- classed and elements only\n\n## Why?\n\nExisting scoped and inline style solutions lead to selector bloat and limited\nstyle reusability.  While the scoping and isolation is a great mental model,\nit's not as great for the browser, which can better optimize styles it has\nalready seen.\n\nThe approach here allows us to write CSS as if it were scoped, and have it\nbehave scoped at runtime as well.  But unlike other solutions, you will ship\nthe smallest possible CSS file with the fewest possible selectors.\n\nThis has the double effect of reducing the size of your template files\nby eliminating long and multiple class names in favor of short \"sha\" based\nselectors.\n\nThis also has the ability to alert you to unused styles in your stylesheet,\nand to \"tree-shake\" your dead CSS.\n\nIn dev mode, we'll keep your selectors scoped but expanded so you can\nsee quickly what has been applied, while in production we will aggressively\nminimize and combine your selectors as much as possible.\n\n## Does \"compiler\" just mean \"minification\" ?\n\nNot at all.  Here's a quick (and contrived) example. Imagine this were\nths sum total of the CSS and html in your app:\n\n```css\nh1 {\n  font-size: 1rem;\n  display: block;\n  width: 100px;\n  height: 50px;\n  margin: 0;\n  padding: 0;\n}\n\n.foo {\n  font-size: 1rem;\n  width: 100px;\n  height: 50px;\n  margin: 5px;\n}\n\n.bar {\n  box-sizing: border-box;\n  width: 100%;\n  height: auto;\n  margin: 5px;\n  padding: 5px;\n}\n\n.baz {\n  color: #f00;\n}\n```\n\n```html\n\u003ch1 class=\"foo bar\"\u003eHello World\u003c/h1\u003e\n```\n\nLooking at this example, we can see that many of our CSS rules are either\noverridden or redundant.\n\nGiven the contrived nature of our example, we also see that we have 3\nselectors matching the html in our \"app\" when we could have used 1. We\nalso have one selector that goes completely unused.\n\nFor this example, the optimizing compiler would instead produce the following\nCSS and DOM.\n\n```css\n.s0 {\n  display: block;\n  font-size: 1rem;\n  box-sizing: border-box;\n  width: 100%;\n  height: auto;\n  margin: 5px;\n  padding: 5px;\n}\n```\n\n```html\n\u003ch1 class=\"s0\"\u003eHello World\u003c/h1\u003e\n```\n\n## Does \"optimizing\" just mean shorter class names and \"collapsed\" selector rules?\n\nNo. In addition to referring to the ability to simplify the combined rules\n for a single DOM element, \"optimizing\" refers to the ability to intelligently\n produce the smallest selector graph it can based on the actual usage of\n various rules in your app.\n \n A contrived example of this extends the above example.\n \n If any other elements use the same \"rule set\" as `s0`, they will also\nuse `s0`.\n\nFor the case where another element is just one style prop different from `s0`,\n  a clustering algorithm based on app usage is used to build a primary \n  selector group, and a modified selector group.\n  \nFor an example in which one group differs only by a different value for \npadding-top, something like the following would be produced:\n\n```css\n.s0 {\n  display: block;\n  font-size: 1rem;\n  box-sizing: border-box;\n  width: 100%;\n  height: auto;\n  margin: 5px;\n  padding: 5px;\n}\n\n.s1 {\n  padding-top: 10px;\n}\n```\n\n## Prior Art\n\nThe following links are some prior art we should investigate the usefulness of:\n\n- https://github.com/prototypal-io/prius\n- https://github.com/prototypal-io/cascada-es6\n- https://github.com/prototypal-io/cascada\n\n\n## Installation\n\n* `git clone \u003crepository-url\u003e` this repository\n* `cd optimizing-css-compiler`\n* `npm install`\n* `bower install`\n\n## Running\n\n* `ember serve`\n* Visit your app at [http://localhost:4200](http://localhost:4200).\n\n## Running Tests\n\n* `npm test` (Runs `ember try:each` to test your addon against multiple Ember versions)\n* `ember test`\n* `ember test --server`\n\n## Building\n\n* `ember build`\n\nFor more information on using ember-cli, visit [https://ember-cli.com/](https://ember-cli.com/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhtml-next%2Foptimizing-css-compiler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhtml-next%2Foptimizing-css-compiler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhtml-next%2Foptimizing-css-compiler/lists"}