{"action":"created","issue":{"url":"https://api.github.com/repos/ebryn/ember-component-css/issues/281","repository_url":"https://api.github.com/repos/ebryn/ember-component-css","labels_url":"https://api.github.com/repos/ebryn/ember-component-css/issues/281/labels{/name}","comments_url":"https://api.github.com/repos/ebryn/ember-component-css/issues/281/comments","events_url":"https://api.github.com/repos/ebryn/ember-component-css/issues/281/events","html_url":"https://github.com/ebryn/ember-component-css/issues/281","id":319244312,"number":281,"title":"Request: guide for extensible component CSS","user":{"login":"jamesarosen","id":2406,"avatar_url":"https://avatars3.githubusercontent.com/u/2406?v=4","gravatar_id":"","url":"https://api.github.com/users/jamesarosen","html_url":"https://github.com/jamesarosen","followers_url":"https://api.github.com/users/jamesarosen/followers","following_url":"https://api.github.com/users/jamesarosen/following{/other_user}","gists_url":"https://api.github.com/users/jamesarosen/gists{/gist_id}","starred_url":"https://api.github.com/users/jamesarosen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jamesarosen/subscriptions","organizations_url":"https://api.github.com/users/jamesarosen/orgs","repos_url":"https://api.github.com/users/jamesarosen/repos","events_url":"https://api.github.com/users/jamesarosen/events{/privacy}","received_events_url":"https://api.github.com/users/jamesarosen/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-05-01T16:11:25Z","updated_at":"2018-05-02T08:49:36Z","closed_at":null,"author_association":"NONE","body":"### Background\r\n\r\n> Design and document for inheritance or else prohibit it. -Joshua Bloch, Effective Java\r\n\r\nThere are many cases where I have a component with some internal structure:\r\n```hbs\r\n{{!-- my-component.hbs, outer HTML --}}\r\n<div class='{{styleNamespace}}'>\r\n  <div class='{{styleNamespace}}__sub-component'></div>\r\n</div>\r\n```\r\n\r\nThe SCSS for that might look like this:\r\n```scss\r\n// my-component.scss\r\n&__sub-component {\r\n  background-color: white;\r\n  color: rebeccapurple;\r\n}\r\n```\r\n\r\nThose class names are generated and not available to a _calling component_. That is, if the author of `my-component` didn't anticipate a use-case (bolder, grayer, rotated, or capitalized), then there's no way for consumers of `my-component` to extend it to get the effect they want.\r\n\r\nThere are a few standard practices for adding customization affordances:\r\n\r\n### Passed-In Class\r\n\r\nThe author of `my-component` accepts a class and adds it to the sub-component:\r\n```hbs\r\n{{!-- my-component.hbs, outer HTML --}}\r\n<div class='{{styleNamespace}}'>\r\n  <div class='{{styleNamespace}}__sub-component {{subComponentClass}}'></div>\r\n</div>\r\n```\r\n\r\n```hbs\r\n<div class='some-special-context'>\r\n  {{my-component subComponentClass='sub-component-override'}}\r\n</div>\r\n```\r\n\r\nThis lets the caller add any arbitrary customizations:\r\n\r\n```scss\r\n// caller.scss\r\n.some-special-context {\r\n  .sub-component-override {\r\n    background-color: azure;\r\n    font-weight: bold;\r\n    border-radius: 3px;\r\n    transform: rotate(10deg);\r\n  }\r\n}\r\n```\r\n\r\nOne benefit of this practice is that it lets callers pass in functional CSS classes:\r\n\r\n```hbs\r\n{{my-component subComponentClass='font--large flex--1 color--cornflowerblue'}}\r\n```\r\n\r\n### CSS Variables\r\n\r\n**NB: this currently doesn't work with ember-component-css**. See #48 and #282.\r\n\r\nThe author of `my-component` defines (some of) its styles using CSS variables. This allows consumers to customize specific aspects of the sub-component, but not add arbitrary CSS.\r\n\r\n```scss\r\n// my-component.scss\r\n:root {\r\n  --my-component-sub-component-background: white;\r\n  --my-component-sub-component-color: rebeccapurple;\r\n}\r\n\r\n&__sub-component {\r\n  background-color: var(--my-component-sub-component-background);\r\n  color: var(--my-component-sub-component-color);\r\n}\r\n```\r\n\r\nThe caller can customize those variables, but not anything else:\r\n```scss\r\n// caller.scss\r\n.some-special-context {\r\n  --my-component-sub-component-background: coral;\r\n  --my-component-sub-component-color: darkolivegreen;\r\n}\r\n```\r\n\r\n`.some-special-context` appears within the DOM between `:root` and `&__sub-component` so its variables override those from `:root`. Note that it wouldn't work to define those variables on `&` in `my-component.scss` because that element is within `.some-special-context`.\r\n\r\n### Static Classes\r\n\r\nThe author of `my-component` adds classes that don't depend on `{{styleNamespace}}` to each of the sub-components. These classes are only for customization and not used by the component itself.\r\n\r\n```hbs\r\n{{!-- my-component.hbs, outer HTML --}}\r\n<div class='{{styleNamespace}} my-component'>\r\n  <div class='{{styleNamespace}}__sub-component my-component__sub-component'></div>\r\n</div>\r\n```\r\n\r\n```scss\r\n// my-component.scss\r\n&__sub-component {\r\n  background-color: white;\r\n  color: rebeccapurple;\r\n}\r\n\r\n// .my-component and .my-component__sub-component don't appear in this file\r\n```\r\n\r\nCalling contexts target the \"for-specialization\" classes with regular CSS rules.\r\n\r\n### Static Attributes\r\n\r\nIn order to more clearly show that this is a hook for extensibility, we can turn the classes into attributes. For example,\r\n\r\n```hbs\r\n{{!-- foo.hbs, outer HTML --}}\r\n<div class='{{styleNamespace}}'>\r\n  <div class='{{styleNamespace}}__sub-component' data-subcomponent='foo:bar'></div>\r\n</div>\r\n```\r\n\r\n```scss\r\n// calling CSS:\r\n& {\r\n  [data-subcomponent=\"foo:bar\"] {\r\n    color: chartreuse;\r\n    background-color: magenta;\r\n  }\r\n}\r\n```\r\n\r\n### Summary / Request\r\n\r\nI'd love to hear about people's experiences with these different techniques. Do you have other ideas? What's a good medium for describing best practices for extensible component-css?"},"comment":{"url":"https://api.github.com/repos/ebryn/ember-component-css/issues/comments/385908126","html_url":"https://github.com/ebryn/ember-component-css/issues/281#issuecomment-385908126","issue_url":"https://api.github.com/repos/ebryn/ember-component-css/issues/281","id":385908126,"user":{"login":"webark","id":852194,"avatar_url":"https://avatars1.githubusercontent.com/u/852194?v=4","gravatar_id":"","url":"https://api.github.com/users/webark","html_url":"https://github.com/webark","followers_url":"https://api.github.com/users/webark/followers","following_url":"https://api.github.com/users/webark/following{/other_user}","gists_url":"https://api.github.com/users/webark/gists{/gist_id}","starred_url":"https://api.github.com/users/webark/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/webark/subscriptions","organizations_url":"https://api.github.com/users/webark/orgs","repos_url":"https://api.github.com/users/webark/repos","events_url":"https://api.github.com/users/webark/events{/privacy}","received_events_url":"https://api.github.com/users/webark/received_events","type":"User","site_admin":false},"created_at":"2018-05-02T08:49:36Z","updated_at":"2018-05-02T08:49:36Z","author_association":"COLLABORATOR","body":"I think i need a like bit of clearification. So are you saying that some addon author gives you access to “my-component” you have no way to customize those styles directly? You would have to do something with in a parent component or at the root level.. Am i reading that right? @jamesarosen"}}
{"actor":{"display_login":"webark"}}