Styling
Introduction[edit | edit source]
All styling within SocialStack uses SASS (https://sass-lang.com/guide). As this is a superset of CSS, any valid CSS can be used, but it's worth taking the time to get to grips with SASS syntax and the built-in functions it provides, as these can both save time and improve the readability of your styles. Please note, SocialStack uses SCSS syntax rather than the old SASS indented syntax (see https://sass-lang.com/documentation/syntax).
Filename conventions[edit | edit source]
All SASS stylesheets within a SocialStack project are combined and included within the resulting site. Changing the order in which these files are combined (and thus potentially affecting the cascade, causing overlapping rules to be overridden or not) can be done by adding a value from 1-100 within the filename itself, e.g. foobar.50.scss
(SCSS files without a value default to a level of 100).
Styles which include definitions which should be available to the entire project (e.g. SASS variables, mixins, etc) should be prefixed with "global.", e.g. global.variables.scss
.
There's no need to minify your styling as this is handled by the compiler.
Theme styling[edit | edit source]
[TODO] Styles can be defined at both the theme and component level - theme styles are global and available throughout the SocialStack site.
Component styling[edit | edit source]
Each SocialStack component includes optional styling - for instance, running socialstack generate UI/FooBar
in a SocialStack project folder will create both UI/FooBar/FooBar.js
for the component itself, along with UI/FooBar/FooBar.scss
- this can then be used to define component-specific styling.
Responsive styling[edit | edit source]
All styling within SocialStack should aim to be responsive and mobile-first (i.e., start with mobile-specific styling and layer other device / resolution overrides on top as necessary). As SocialStack uses the Bootstrap framework by default (https://getbootstrap.com/docs), we can utilise Bootstrap SASS mixins to target specific breakpoints. For instance, the following example will cause the component to show a green background for mobile devices, switching to red when viewed on anything 768px wide or above (defined by the Bootstrap medium or md
breakpoint):
.foobar {
background: green;
}
@include media-breakpoint-up(md) {
.foobar {
background: red;
}
}
This resolves to:
.foobar {
background: green;
}
@media (min-width: 768px) {
.foobar {
background: red;
}
}
Please refer to https://getbootstrap.com/docs/5.1/layout/breakpoints/ for details on which other breakpoints are available.
Note[edit | edit source]
Defining multiple
@media
queries in ascending order is highly recommended in order to avoid unexpected bugs where a "smaller" media query overrides a larger one.
Naming conventions[edit | edit source]
Whilst not strictly enforced, the use of the BEM (Block Element Modifier) methodology (https://en.bem.info/methodology) when naming classes is strongly recommended:
- Targetting styles to a class such as
foobar__header--secondary
is way less brittle than using specific HTML elements (e.g.h2
), as changes during development inevitably result in changes to markup
- Descriptive classes defined in this way are both more consistent and descriptive
- Much more obvious which element(s) on the page will be affected
Example[edit | edit source]
Taking the following menu design as a guide:
This could be defined with the following markup:
<nav className="foobar">
<ul className="menu">
{/* home */}
<li className="menu__item">
<a href="#" className="menu__link">
<svg className="menu__icon" ... />
</a>
</li>
{/* calendar */}
<li className="menu__item">
<a href="#" className="menu__link menu__link--active">
<svg className="menu__icon" ... />
</a>
</li>
{/* video */}
<li className="menu__item">
<a href="#" className="menu__link">
<svg className="menu__icon" ... />
</a>
</li>
{/* chat */}
<li className="menu__item">
<a href="#" className="menu__link">
<svg className="menu__icon" ... />
</a>
</li>
</ul>
</nav>
Corresponding styles could then be defined as:
$menu_background: #000;
$menu_foreground: #fff;
$menu_foreground_inactive: rgba($menu_foreground, .5);
$menu_foreground_hover: rgba($menu_foreground, .75);
$menu_icon_size: 24px;
.foobar {
.menu {
list-style: none;
padding: 0;
background-color: $menu_background;
&__item {
display: inline-block;
}
&__link {
display: flex;
align-items: center;
justify-content: center;
padding: 0 25px;
border-bottom: 4px solid transparent;
&:hover {
border-bottom-color: $menu_foreground_hover;
.menu__icon {
color: $menu_foreground_hover;
}
}
&--active {
border-bottom-color: $menu_foreground;
.menu__icon {
color: $menu_foreground;
}
}
}
&__icon {
width: $menu_icon_size;
height: $menu_icon_size;
color: $menu_foreground_inactive;
}
}
}
- Defining variables for values which are used in multiple instances (or which are likely to change) allows for easier editing
- Wrapping all the rules within a parent
.foobar
block ensures these styles will only affect elements parented by that class (namely, those within this component)
- Use of
&__item
style concatenation reduces repetitive typing of common elements in class names - in the above example, this would resolve to.menu__item
- Note that we're not using
&__icon
within the&:hover
or&--active
blocks - this would result in.menu__link--active__icon
and not.menu__link--active .menu__icon
- While stock CSS doesn't allow #RGB values to be used within
rgba()
, SASS does - here we usergba($menu_foreground, .5)
which resolves torgba(255, 255, 255, .5)
in the resulting CSS
- Note that nesting of rules is kept to a minimum - there's no need to follow the markup structure religiously (e.g.
.menu .menu__item .menu__link
), as the classnames are descriptive and unique enough