Skip to content

Components

UI components at Tickster is, a bit confusingly, many things.

It's one part HTML markup, one part CSS and – starting with this new component library – sometimes a bit of Vue code as well. In some (legacy) cases it's maybe even some custom jQuery code too.

Let's look a bit into what each component "layer" does.

HTML

The HTML part of a web component defines the structure and content of the component. It consists of standard HTML elements that are used to create the skeleton of the component. This includes elements like <section>, <article>, <button>, and others, which are organized in a way that represents the component's layout and hierarchy.

When using a component, it's important to ensure that the HTML is semantic and accessible. This means using the appropriate HTML elements for their intended purposes.

For example, a simple card component might have the following HTML structure:

html
<article class="c-card">
    <div class="c-card__image">
        <img class="lazyload" alt="" data-src="../temp/skus/bilar.jpg" width="400" />
    </div>
    <div class="c-card__body">
        <h2 class="c-card__title">Candy</h2>
    </div>
</article>

Note that the <h2> (highlighted above) is appropriate in some cases but not in others – maybe a <h3> is better for you? It all depends on the semantic context: Heading levels should come in a descending order.

Heading hierarchy

  • <h1>: Use for the main title of the document. There should only be one <h1> per page.
  • <h2>: Use for major sections within the document. These should be used to denote primary subsections.
  • <h3>: Use for subsections within an <h2> section. These help to further organize content within a major section.
  • <h4>: Use for subsections within an <h3> section. These are less common but can be used for detailed organization.
  • <h5> and <h6>: Use sparingly for deep levels of nested content. These are rarely needed in most documents.

CSS

The CSS part is about styling. The naming structure follows the BEM naming convention (Block, Elements, Modifiers). E.g. .c-card__body means it's the body wrapper of the component Card.

About BEM

Blocks

Blocks are the standalone entities which are meaningful on its own. For examples, we can identify a header, a list, a label, etc. as an entity.

We use .x-block (where x- is a prefix, see more below) to denote a block in BEM.

Elements

An element is a part of a block that has no standalone meaning and is semantically tied to its block. For an example, we can identify a single item of a menu as an element, or the caption of a checkbox, or an item of a list, etc.

We use __element suffix to denote elements in BEM.

Modifiers

A modifier is a flag on a block or an element. We can use them to identify a change appearance or behavior of a particular block or an element. For an example, we can identify 'disabled' as the modifier in a disabled menu item, or the 'color yellow' of a container, etc.

We use --modifier suffix to denote modifiers in BEM.

By definition, CSS declarations map with HTML elements, id's and class attributes, even though they can seem complex when CSS specific operators like > or ~ are used.

To try to keep both markup and styling easy to use and read, Tickster uses a methodology (not a framework) called ITCSS.

ITCSS based architecture

ITCSS (Inverted Triangle CSS) is a methodology created by Harry Roberts (@csswizardry) for organizing CSS in a way that helps manage and scale large projects. The idea is to structure the CSS in an inverted triangle, where the broadest, most far-reaching styles are at the top, and the most specific styles are at the bottom.

Layers of ITCSS
  1. Settings: Global variables, config switches, etc.
  2. Generic: Reset and/or normalize styles, box-sizing definition, etc.
  3. Elements: Styling for bare HTML elements (like <ul>, <a>, etc.). These come with default styling from the browser, so we can redefine them here.
  4. Objects: Class-based selectors which define undecorated design patterns, for example, layout objects like grids. Has an o- prefix.
  5. Components: Specific UI components. This is where the majority of our work takes place and our UI components are often composed of Objects and Components. Has a c- prefix.
  6. Utilities: Utilities and helper classes with the ability to override anything which goes before in the triangle, e.g. hide helper class. Has a u- prefix.
  7. Themes: This is the highest specificity layer. It includes the most explicit types of rule, with the most narrow focus. Has an t- prefix.

By organizing our CSS in this way, we can ensure that our styles are predictable, maintainable, and scalable. ITCSS helps to avoid specificity issues and makes it easier to manage large codebases.

The CSS files in the UI framework are named in a way that maps to ITCSS; elements.heading.css sets some default styling to the heading elements whereas Component files are name components.[name].css.

CSS Tokens

CSS tokens are reusable, design-related variables that help maintain consistency across the UI. They can include values for colors, fonts, spacing, and more. By using tokens, we make our design system easy to maintain. In an ITCSS scenario, tokens are kept in the Settings layer (see details above).

In the context of Atomic Design, as defined by Brad Frost, tokens can be considered the smallest building blocks (atoms) that form the foundation of a design system. They provide a single source of truth for design decisions, making it easier to implement changes across the entire application.

Wrap-up

Having said all this, the way CSS is utilised at Tickster is the same in our Vue apps as in our server rendered applications; All CSS components are ulimately bundled in a framework.css file that is includes in our projects.

For a site like www.tickster.com this means that the whole CSS framework is included once and cached, whereas when used in a Vue app the same file is included within the app's CSS assets.

By doing this we ensure that we don't have to version track components indicidually. We can also keep one (and only one) way of linting, parsing and building that CSS, in the specific order (currently set by Gulp in its settings file)

JavaScript

The JavaScript part of a web component adds interactivity and dynamic behavior. In this styleguide, JavaScript is primarily used to enhance user interactions and provide a richer user experience. This can include tasks such as form validation, dynamic content updates, and handling user events.

We use a modern JavaScript framework called Vue to create reusable and modular components. In some legacy cases, you might encounter custom jQuery code. However, the goal is to transition towards a more standardized and maintainable codebase using Vue.