CSS Style Guide
January 14, 2026 · View on GitHub
This guide covers CSS conventions, SASS usage, and styling best practices for Countly development.
CSS Preprocessor
Countly uses SASS as the CSS preprocessor with Dart Sass implementation and SCSS syntax.
Key Resources
Important SASS Topics
- Partials - Files prefixed with
_that are imported - Private members - Variables/mixins not exported
- @use rule - Modern import syntax
Compiling SASS
Build Commands
# Compile all resources (recommended)
npx grunt dist-all
# Compile only SASS files
npx grunt sass
# Watch for SASS changes
npx grunt watch
Manual Compilation
sass /path/to/input.scss /path/to/output.css --style compressed --no-source-map
Add --watch flag for development auto-compilation.
Note: Remove source maps from final merged code.
Directory Structure
Core CSS Directory
frontend/express/public/stylesheets/styles/
├── base/
│ ├── _base.scss # Base DOM elements (p, h1, etc.)
│ ├── _colors.scss # Global color variables
│ ├── _element-variables.scss # Element UI CSS variables
│ ├── _mixins.scss # Global mixins
│ ├── _typography-variables.scss
│ └── _variables.scss # All other global variables
├── blocks/ # BEM block files
├── overrides/ # Third-party lib overrides
│ ├── _element-overrides.scss
│ └── _bulma-overrides.scss
├── states/
│ └── _state.scss # Global state classes
├── coreplugins/ # Core plugin CSS
│ └── _[plugin-name].scss
├── manifest.scss # Loads all partials
└── manifest.css # Compiled output
Plugin CSS Structure
plugins/<name>/frontend/public/stylesheets/
├── main.scss # Entry point, loads partials
├── main.css # Compiled output
├── _component1.scss # Partial files (prefixed with _)
└── _component2.scss
Using Core Variables in Plugins
// main.scss
@use "../../../../../../frontend/express/public/stylesheets/styles/base/colors" as c;
.text {
color: c.$text-color;
}
BEM Naming Convention
We use BEM (Block Element Modifier) with the two dashes style naming convention.
Structure
- Block: Independent entity (
.cly-vue-section) - Element: Part of a block (
.cly-vue-section__content) - Modifier: Variation/state (
.cly-vue-section--white)
Naming Rules
- Prefix all blocks with
cly-vue-to avoid collisions with legacy code - Use class selectors only (no tag or ID selectors)
- Don't combine tags and classes (e.g., avoid
button.button) - Don't use combined selectors
Example
// _section.scss
@use "../base/variables" as v;
@use "../base/colors" as c;
.cly-vue-section {
padding: 2px;
&__content {
border-top: v.$border-base;
border-bottom: v.$border-base;
}
&--white {
background-color: c.$color-white;
}
}
<div class="cly-vue-section">
<h4>Title</h4>
<div class="cly-vue-section__content cly-vue-section--white">
Content here
</div>
</div>
Bulma CSS Framework
We include Bulma for grid layouts and responsiveness.
Namespace
All Bulma classes are prefixed with bu- to avoid collisions:
columns→bu-columnsis-full→bu-is-full
Available Components
Example with Bulma Grid
<div class="cly-vue-section bu-columns">
<div class="bu-column bu-is-full">
<div class="bu-level">
<div class="bu-level-left">
<div class="bu-level-item">
<h4>{{title}}</h4>
</div>
</div>
</div>
</div>
<div class="bu-column bu-is-full cly-vue-section__content">
<slot></slot>
</div>
</div>
Key Rules
DO
- Use
@userule to load partials (not@import) - Create partials (files starting with
_) for organization - Use BEM naming with
cly-vue-prefix - Use Bulma classes (
bu-*) for grid and layout - Move likely-to-change CSS properties to modifiers
- Use state classes from
_states.scsspartial
DON'T
- Don't use
@importin SASS files - Don't load
element-variables.scssin your SCSS files - Don't use
!important- increase specificity instead - Don't combine tag and class selectors
- Don't use ID selectors for styling
- Don't add CSS to deprecated directories:
frontend/express/public/stylesheets/main.cssfrontend/express/public/stylesheets/vue/*
Third-Party Libraries
Add third-party CSS libraries to:
frontend/express/public/stylesheets/<library-name>/
Element UI Customization
To modify Element UI components:
- Clone from: https://github.com/Countly/element
- Make changes to the cloned repo
- Requirements: Node.js 14.x.x, Python 2.7
- Build:
npm run dist --unsafe-perm - Copy
lib/index.jstofrontend/express/public/javascripts/utils/vue/element-ui.js - Copy CSS from
lib/theme-chalk/tofrontend/express/public/stylesheets/vue/element-ui.css - Push changes to both repos to avoid override conflicts