Theming Guidelines
Theming best practices
Style directly the SUI components without introducing new markup or classes
Here is why we shouldn't introduce new markup to SUI components:
Here is the generic markup defined by React Semantic UI documentation site https://react.semantic-ui.com/modules/accordion/#types-standard
Here is this component used within a package made by EEA: https://github.com/eea/volto-accordion-block/blob/master/src/components/manage/Blocks/Accordion/View.jsx#L50
When the theme is added, we expect for the normal
Accordion
component to look like it does now on the storybook without any modification to the component in the individual packages.
Therefore, when theming the stock components do the following:
- Remove any extra html tag elements and stick to the normal component markup
- Remove any extra
eea classes
, style the component class directly unless we have a neweea variant
- Use the variables to modify the design of the component, use overrides only if styles are missing altogether, or they are hard-coded
- If you add new styles, and they are presentational follow the convention of the semanticUI variables and name them likewise
Ex:
//if you have
.styled.active.child {
padding: 0;
}
// then add the value with a variable
@styledActiveChildPadding: 1rem;
// and use it
.styled.active.child {
padding: @styledActiveChildPadding;
}
Use variables everywhere it is possible:
Make use of already added styles and override
variables
instead of addingoverrides
:https://github.com/Semantic-Org/Semantic-UI/blob/master/src/definitions/elements/button.less https://github.com/eea/volto-eea-design-system/blob/develop-itml/theme/themes/eea/elements/button.variables
Introduce new variables if needed for
presentational styles
; some examples include:- border
- padding
- margin
- color
- background
- box-shadow
- font-size
- width
- height
- display
- position
- alignment
- text-decoration
Use variables also for link and buttons
states
, ex:- focus
- hover
- active
We will provide a
primary
button blue, but perhaps another EEA website will havegreen
with a border as theprimary
style.Having a design system that allows this level of customization through variables ensures that the design is flexible without adding any extra css to the final bundle.
If there aren't any, and you need to use
media queries
, definevariables
for media queries, ex:// button.variables
@buttonTabletBreakpoint: @tabletBreakpoint;This way, another design might choose to use a different breakpoint from the usual breakpoints.
If new variables are introduced, opt to use functionality naming instead of using color naming, ex:
// right
.ui .primary .button {}
// wrong
.blue .button {}
Remove or customize overrides
Delete overrides that modified variables, introduce overrides only when the style is hard-coded:
Ensure that text is a minimum of 16px
Except for .small
or .tiny
classes that make text small, we need to ensure that it is legible any time we have text by making it 16px or more
.
Consider using container visibility classes for hiding elements
If we have a custom component that we want visible only at specific browser widths, consider using the utility classes
available from the container.overrides
file.
They hide or show elements based on the combination of classes passed in the component.jsx
file.
See the container.overrides
file for details.
Extra code way:
@media screen and (max-width:768px) {
.component {
display: none;
}
}
Better way:
<Component className={"mobile hidden"}
Don't add HTML tags to the css specificity selector
If we have:
.ui.button.basic
Avoid adding:
button.ui.button.basic {}
table.ui.plain {}
Instead opt for variable overrides or add extra classes:
.ui.table.eea-table-plain {
tag: style
}
Add custom classes after the semantic ui classes
Wrong:
.ui.eea-button-action.button {}
Right:
.ui.button.eea-button-action {}
Use Semantic UI naming style
If you introduce a new variant of a Semantic UI component, ex new button variant: Wrong:
.ui.button.eea-button-action {}
Right:
.ui.button.action {}
If you add a new non-Semantic UI component:
Wrong:
.eea-header {}
.eea-header-action {}
Right:
.eea.header {}
.eea.header .action {}
Keep important rules to a minimum and make sure they are well documented
In general !important
should be used for utility classes
only where you need to have the highest specificity.
If you need to add any css !important
rules, they need detailed comments on what is fixed and where/what to check for fix reproduction with a FIXME comment
.
Wrong:
.ui.dropdown {
height: auto !important;
}
Better:
// FIXME reset left margin since help is a p tag
.help {
margin-left: 0 !important;
}
Best:
// ### Used in login page form /login_form
// FIXME reset left margin using !important since help is a p tag
// with margin set to important
.help {
margin-left: 0 !important;
}
Use relative units in general
Gutters/spacing are now measured using px instead of rem. SemanticUI uses rem.
So if designer set 20px, it must be transformed to rem units, by taking the base font-size of 16px then we get 20/16 = 1,25rem.
So that if in the future we change the base font-size the gutters/spacing
will also adjust.
Wrong:
@gutterWidth: 20px;
Right:
@gutterWidth: 2rem;
Think globally, act locally
If you have a section repeated in several components, consider introducing a global variable that will be default for all the components where that section is present. Ex:
Many components have a meta section
.
This section can be aligned either left
or right
.
Therefore, we should introduce a global variable within the site.variables
add a new global
variable:
// site.variables
/* This adjusts the meta alignment across all elements */
@metaAlign: left;
Then use this global variable in each component where we have a meta section
:
// blockquote.variables
/* This rule uses by default the global setting */
@blockquoteMetaAlign: @metaAlign;
If later the design calls to have the meta sections to the right, it's simply a job of changing one global variable:
// site.variables
/* This adjusts the meta alignment across all elements */
@metaAlign: right;
The same is true with colors used in components, try to avoid custom values set on components only as they should be part of the site.variables
color pallete.
Semantic UI global setting example
We see this rule played out in many places within site.variables
:
// site.variables
/*--------------
Form Input
---------------*/
/* This adjusts the default form input across all elements */
@inputBackground : @white;
Then within form.variables
we have several rules that make use of the global setting:
// form.variables
/* Text Area */
@textAreaBackground: @inputBackground;
/* Inverted */
@invertedInputBackground: @inputBackground;
Check components design when having odd numbers or images
As written down in the Card component issue, if your component accepts images consider how
they would adapt in case there is a mix between portrait
and landscapei
images.
What about situations where you have an odd number of elements or the body of the components differ in size?
The components need to be checked for such situations and to ensure they are flexible to deal with these mix and match elements.
Ex:
If the card is flex
based and the parent wrapper
is flex as well, consider adding a max-height to the card body
or image wrapper
so that they all keep a standard size.
Code formatting
- CSS and less files should be formatted using prettier. Indent space will be 2 spaces.
- Files should be edited as Unix files, with LF line endings.