Skip to content

Code Styleguide

Iliana Nikolova edited this page Sep 14, 2023 · 3 revisions

To ensure the quality and consistency of the code when contributing to the kendo-themes repository, adhere to the following guide.

Terminology

Rule set

A "rule set", or "rule" for short, is the name given to a selector (or a group of selectors) with an accompanying group of properties. Here's an example:

selector {
    padding: 20px;
    border: 1px solid red;
}

Selector

In a rule set, "selector" is the bit that determine which elements in the DOM tree will be styled by the defined properties. Selectors can match HTML elements, as well as an element's class, ID, or any of its attributes. Here are some examples of selectors:

// Element selector
body {
    // ...
}

// Class selector
.k-combobox {
    // ...
}

// ID selector
#grid {
    // ...
}

// Attribute selector
[aria-hidden] {
    // ...
}

Declaration

A single rule like color: red; specifying which of the element's properties you want to style.

Properties

Finally, properties are what give the selected elements of a rule set their style. Properties are key-value pairs, and a rule set can contain one or more property declarations. Property declarations look like this:

color: #123456;
font-size: 20px;

Syntax

  • Use soft tabs with 4 spaces.
  • When grouping, keep individual selectors on separate lines.
  • Include one space before the opening brace of declaration blocks for legibility.
  • Place closing brace of declaration blocks on a new line.
  • Include one space after colon (:).
  • Each declaration should appear on its own line.
  • All declarations must end with semicolon (;).
  • Comma separated property values must include a space after each comma.
  • Don't prefix property values or color parameters with a leading zero.
  • Lowercase all hex values, e.g., #ffffff.
  • Use longhand hex values, e.g., #ffffff instead of #fff.
  • Quote attribute values in selectors, e.g., input[type="text"].
  • Avoid specifying units for zero values, e.g., margin: 0; instead of margin: 0px;.

Single declarations

If a rule set includes only one declaration, consider removing line breaks for readability.

// Single declarations on one line
.k-text-left { text-align: left; }

Shorthand notation

Limit shorthand declaration usage to instances where you must explicitly set all available values. Frequently used shorthand properties include:

  • margin
  • padding
  • border
  • border-radius
  • background
  • font

Usually we don't need to set all the values a shorthand property represents. For example, HTML headings only set top and bottom margin, so when necessary, only override those two values. A 0 value implies an override of either a browser default or previously specified value.

Excessive use of shorthand properties leads to unnecessary overrides and unintended side effects.

Overrides

Only override the parts you need, e.g., padding-left, border-color or font-size instead of padding, border or font.

// initial definition
.k-button .k-icon {
    margin: 0 4px 0 0;
}

// override for RTL
.k-rtl .k-button .k-icon {
    margin-right: 0;
    margin-left: 4px;
}

Declaration order

Related property declarations should be grouped together following the order:

  • Box, border and sizing
  • Visual
  • Typographic
  • Positioning
  • Display, flex and grid
  • Position and transforms
  • Opacity and visibility
  • Misc
.declaration-order {
    // Generated content
    content: "";

    // Box
    margin: 0;
    padding: 0;
    width: 100px;
    height: 100px;

    // Border
    border-width: 1px;
    border-style: solid;
    border-radius: 3px;
    outline: 0;

    // Box sizing
    box-sizing: border-box;

    // Visual
    color: #000000;
    background-color: #f0f0f0;
    backgorund-image: linear-gradient(red, blue);

    // Typography
    font: normal 13px "Helvetica Neue", sans-serif;
    font-size: 12px
    line-height: 1.5;
    font-family: sans-serif;
    font-weight: bold;
    font-style: italic;
    text-decoration: underline;
    text-align: center;

    // Display
    display: block;
    float: right;

    // Flex or grid

    // Positioning
    position: absolute;
    z-index: 100;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;

    // Transforms

    // Opacity and visibility
    opacity: .5;
    visibility: visible;

    // Misc
    pointer-events: none;
}

For a complete list of properties and their order, please see the property order for sasslint.

Class names

  • Keep classes lowercase and use dashes (not underscores or camelCase). Dashes serve as natural breaks in related class e.g., .k-button and .k-button-primary.
  • Avoid excessive and arbitrary shorthand notation. .button is useful for button, but .s doesn't mean anything.
  • Keep classes as short and succinct as possible.
  • Use meaningful names; use structural or purposeful names over presentational.
  • Prefix classes based on the closest parent or base class.

It's also useful to apply many of these same rules when creating sass variable names.

Variable names

Prefer dash-case for variable names (e.g. $my-variable) over $camelCase and $snake_case variable names. It is acceptable to prefix variable names with underscore to denote "private" use, e.g. $_my-variable.

Mixins

Mixins should be used to DRY up your code, add clarity, or abstract complexity.

  • mixins that don't have parameters, should be used without parenthesis, e.g., @include displat-flex;.
  • mxins that have parameters should be used with parenthesis, even if they have default value, e.g., @include border-radius();.

Use of !important

Avoid use of !important, unless absolutely necessary, in favor of meaningful selectors, even if that means changes in rendering because CSS rules that use the !important modifier are hard to maintain and very hard to override by customer code.

Exceptions from this rule are acceptable in cases where overrides of a style can break the functionality of the component and are easily overwritten:

  • The Upload component uses font: 200px monochrome on a visually hidden <input type="file" />. Changing this setting will break the Upload functionality and it is very easy for users to add a #my-container input { font-size: 20px; } rule, the use of !importnat handles this issue.
  • The auto-fit functionality of the Grid columns measures text through a table that needs to have table-layout: auto and no column widths.

Document each use of !important in an inline comment and describe why it is needed. Do not forget to disable sasslint rules per-line. Avoid disabling rules per-block.

// Font should not depend on outside styles. Otherwise, the Upload may break.
font: 170px monospace !important; // sass-lint:disable-line no-important

Media query placement

Place media queries as close to their relevant rule sets whenever possible. Bundling rules is acceptable. Placing them at the end of the file is also acceptable.