Closed philipwalton closed 6 years ago
Should all variables be scoped to the module…
The custom properties are "global", and the components shouldn't expose the internal structure, so having a flat structure after the namespace seems like a suitable choice: --ComponentName-someVariableName
. The non-component variables would be --someVariableName
…have you thought about a conversion plan…
Not possible to do outside of the browser. See https://github.com/reworkcss/rework-vars/issues/30. I don't think there's anything wrong with namespacing them now – it provides a clear link that would make it easy to migrate to native custom properties at the component level.
Yeah, I know it's not actually possible to do this outside of the browser, but I see this as similar to how calc
is supported despite not being full-featured.
Given the conventions of SUIT, someone could write the following CSS in their module and a rework plugin could handle it:
.ComponentName {
--space: calc(var(--space)*2);
}
.ComponentName-subElementName {
color: var(--space);
}
The plugin would apply the following logic:
.ComponentName {
--space: calc(var(--space)*2);
}
/**
* Rework sees that a custom property is being set on a component and
* translates that into this:
*/
:root {
--ComponentName-space: calc(var(--space)*2);
}
/**
* Because this selector starts with `.ComponentName` and `.ComponentName`
* defined the property `--space`, Rework would know to use the property
* `--ComponentName-space` instead of `--space`.
*/
.ComponentName-subElementName {
color: var(--space);
}
Anyway, I'm not necessarily suggesting this idea, I was just wondering if you or anyone had been thinking about how to handle this moving forward.
Also, the value isn't just to save a few characters and not have to prefix things, the value is that browser that do support custom properties could potentially get them (with obvious caveats) before having to wait until full support exists.
Given what I've described above, the Rework plugin could output something like this:
/* Output fallback, translating `var(--Component-space)` to a value. */
.ComponentName-subElementName {
color: var(--Component-space);
}
@supports (/* some custom property check */) {
.ComponentName-subElementName {
/* Literally output this, without translating to a value. */
color: var(--space);
}
}
Yeah it could work in some form when you have a convention like SUIT, and you bake that into the assumptions. But the native implementation would expose --space
to any element in the sub-tree, including other components. So you'd be depending on behaviour in the preprocessing that doesn't exist in the native implementation, which is risky because it's not longer forward-compatible.
What I find myself wanting quite often is local variables that aren't exposed outside the file.
I am a bit late to the party but I am using suit in a project and all of a sudden some of these issue are relevant to me.
so having a flat structure after the namespace seems like a suitable choice: --ComponentName-someVariableName. The non-component variables would be --someVariableName
Agreed, I use the following convention:
--ComponentName[-descendant|--modifier][-onState]-(cssProperty|variableName)
Examples
--ComponentName-backgroundColor
--ComponentName-descendant-backgroundColor
--ComponentName--modifier-backgroundColor
--ComponentName-onHover-backgroundColor
--ComponentName-descendant-onHover-backgroundColor
...
@philipwalton thoughts?
If you like it I will try to implement this convention in postcss-bem-linter
.
Looks good to me. Be a good one to add to the docs and finally close this issue
Hi guys, since this has been already merged, shall we close the issue?
@racse1 Good spot!
How would you guys approach to naming variables if it involves numbers? In SUIT I guess I shouldn't be separating numbers with a dash but it reads better with a dash.
--colorNeutral-0: #FFFFFF;
--colorNeutral-50: #......;
--colorNeutral-100: #......;
--colorNeutral-200: #......;
...
--colorNeutral-900: #......;
--spacing-0: 4px;
--spacing-1: 8px;
--spacing-2: 16px;
--spacing-3: 24px;
...
--spacing-9: 72px;
I didn't see any docs on the variable naming convention, but you've implicitly outlined some type of convention in your examples:
As far as I can tell, the only real "rule" is that component variables should be prefixed with the full component name. However, I think the example above can be confusing given the other conventions. For example,
--Excerpt-padding
is clearly a variable scoped to the.Excerpt
component, but is--Excerpt-highlight-color
the highlight color for.Excerpt
or is it the color for the sub-element.Excerpt-highlight
? Granted, in this case it's pretty clear from the semantics, but there may be other cases where it's not nearly as obvious. Perhaps it should be camelCase after the component namespace, e.g.--Excerpt-hightlightColor
.I haven't spent much time thinking about this, so consider these just a few ideas/questions off the top of my head:
Tweet-bgColor
vs.--Tweet-btn-bgColor
--Tweet-textColor
vs--textColor