Skip to content

Styling

Dmitri Pisarev edited this page Apr 26, 2016 · 7 revisions

Hey!

We have a few decisions to make regarding how we do the styling, so let's decide here and iterate upon this page.

Prerequisite reading: http://glenmaddern.com/articles/css-modules

Normalize vs Reset

Currently, we use Normalize. I would use reset.css. Saving a few lines of CSS code is less important than having a solid foundation to build upon. E.g. we just had a bug due to normalize.css removing curosor: pointer from buttons, relying on it was a bad idea.

What styles do we set on the body?

I think it makes sense to set font-face there, as we only use one font. Maybe line-height: 1? Everything else should come from reset.css.

Block-level scope

Currently, we use CSS modules to solve the global scope issue. With that we no longer need BEM naming to solve scope issues: all selectors within a file are local to that component.

But using BEM would allow putting multiple block styles within one file. That's, in general, is not a good idea and definitely is dirty, but from practical experience that sometimes makes sense on container component level, where you need just a few minor adjustments.

But I would drop BEM with pleasure if we decide so.

Styling reuse

Presentational components

We use presentational components as a method of styling reuse. Basically, they are our own "Bootstrap": a set of visual components that comprise our UI look and feel (buttons, dropdowns, dialogs etc). See here for a good overview.

Components are not meant to be extended, but rather configured. E.g. Button component may have multiple variants available via a configuration option, e.g. <Button style='brand'/>. An escape hatch to extend styling of components would be to merge class names, but that should be used sparingly and with great feeling of shame :)

Presentational components are a kind of our internal styling API, they should be carefully managed, tested, and perhaps in the future, it makes sense to put them into a separate package, to allow building apps in Neos style outside of the main UI.

Styling of container components.

Container components are not meant to be reused, and usually don't need a lot of styling on their own, just certain tweaks and adjustments here and there. Ideally, it should be possible to build container components just from presentational components, but adding some unique styles, that are not meant to be reused there is OK. Therefore, quality requirements to styling container components are much lower than for presentational components: you can iterate quickly on them, not be afraid to break affect code depending on them etc. Probably it doesn't make a lot of sense to document them as well.

CSS Modules' @value feature

See: https://github.com/css-modules/postcss-modules-values

We manage a set of constants via variables. In CSS Modules variables have to be explicitly imported, and that is very good, no global-scope SASS anymore! An example of constants we would need would be colors, spacing intervals and so on. BUT, these should not be treated like settings from SASS world. E.g. it is probably not a good idea to put @value inspectorWidth: 300px; into global constants file, much rather it should be defined at a component level, to ship everything related to that component in one place.

But let's prefix values with $, not to clash with CSS namespace, i.e.: @value $red: #c50502

CSS Modules' compose feature

CSS Modules allow another way of code reuse: to extend other CSS classes, similar to SASS' @extend keyword, but without its drawbacks. I think that could be used to DRY some common traits between components, but should go through the same consideration as using variables, or else we risk to couple components too much together.

Documentation

We could use just any fancy living styleguide, but Storybook tool is actually so much more cool.

It can be used as a styleguide, and in addition, it puts each component into isolation and allows to develop it without even starting Neos, having hot reloading and all fancy things. It would help to trace unwanted coupling and bugs early on, and also provide a nice place for documentation.

Testing

We already test React components, but it would be good to do visual regressions testing with a tool like Gemini by Yandex.