Skip to content
Back to skills

Less Best Practices

ASecurity

Less CSS best practices and coding guidelines for maintainable, modular stylesheets

  • 248 stars
  • 0 votes
  • 0 copies
  • 8 views
  • Added February 10, 2026
developmentgoperformance

Works with

  • cursor
  • cli

Security analysis

A100/100

Scanned February 12, 2026

npx -y skills add Mindrally/skills --skill less-best-practices --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Less Best Practices?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Less Best Practices
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mindrally-less-best-practices/badge)](https://www.skillsdirectory.com/skills/mindrally-less-best-practices)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: less-best-practices
description: Less CSS best practices and coding guidelines for maintainable, modular stylesheets
---

# Less CSS Best Practices

You are an expert in Less (Leaner Style Sheets), CSS architecture, and maintainable stylesheet development.

## Key Principles

- Write modular, reusable Less that leverages variables, mixins, and functions
- Follow consistent naming conventions and file organization
- Keep specificity low and avoid overly complex selectors
- Prioritize readability and maintainability

## File Organization

### Project Structure
```
less/
├── abstracts/
│   ├── variables.less      # Global variables
│   ├── mixins.less         # Reusable mixins
│   └── functions.less      # Less functions
├── base/
│   ├── reset.less          # CSS reset/normalize
│   ├── typography.less     # Typography rules
│   └── base.less           # Base element styles
├── components/
│   ├── buttons.less        # Button components
│   ├── cards.less          # Card components
│   └── forms.less          # Form components
├── layout/
│   ├── header.less         # Header layout
│   ├── footer.less         # Footer layout
│   ├── grid.less           # Grid system
│   └── navigation.less     # Navigation layout
├── pages/
│   ├── home.less           # Home page specific
│   └── contact.less        # Contact page specific
├── themes/
│   └── default.less        # Default theme
├── vendors/
│   └── normalize.less      # Third-party styles
└── main.less               # Main manifest file
```

### Main Manifest
```less
// main.less

// Abstracts
@import "abstracts/variables";
@import "abstracts/mixins";
@import "abstracts/functions";

// Vendors
@import "vendors/normalize";

// Base
@import "base/reset";
@import "base/typography";
@import "base/base";

// Layout
@import "layout/grid";
@import "layout/header";
@import "layout/navigation";
@import "layout/footer";

// Components
@import "components/buttons";
@import "components/cards";
@import "components/forms";

// Pages
@import "pages/home";

// Themes
@import "themes/default";
```

## Variables

### Naming Convention
```less
// variables.less

// Colors - use semantic names
@color-primary: #3498db;
@color-primary-light: lighten(@color-primary, 15%);
@color-primary-dark: darken(@color-primary, 15%);
@color-secondary: #2ecc71;
@color-text: #333333;
@color-text-muted: #666666;
@color-background: #ffffff;
@color-border: #e0e0e0;
@color-error: #e74c3c;
@color-success: #27ae60;
@color-warning: #f39c12;
@color-info: #17a2b8;

// Typography
@font-family-base: 'Helvetica Neue', Arial, sans-serif;
@font-family-heading: 'Georgia', serif;
@font-family-mono: 'Consolas', monospace;
@font-size-base: 1rem;
@font-size-small: 0.875rem;
@font-size-large: 1.25rem;
@font-size-h1: 2.5rem;
@font-size-h2: 2rem;
@font-size-h3: 1.75rem;
@font-weight-normal: 400;
@font-weight-medium: 500;
@font-weight-bold: 700;
@line-height-base: 1.5;
@line-height-heading: 1.2;

// Spacing Scale
@spacing-unit: 8px;
@spacing-xs: (@spacing-unit * 0.5);   // 4px
@spacing-sm: @spacing-unit;            // 8px
@spacing-md: (@spacing-unit * 2);      // 16px
@spacing-lg: (@spacing-unit * 3);      // 24px
@spacing-xl: (@spacing-unit * 4);      // 32px
@spacing-xxl: (@spacing-unit * 6);     // 48px

// Breakpoints
@breakpoint-sm: 576px;
@breakpoint-md: 768px;
@breakpoint-lg: 992px;
@breakpoint-xl: 1200px;
@breakpoint-xxl: 1400px;

// Z-index Scale
@z-index-dropdown: 1000;
@z-index-sticky: 1020;
@z-index-fixed: 1030;
@z-index-modal-backdrop: 1040;
@z-index-modal: 1050;
@z-index-popover: 1060;
@z-index-tooltip: 1070;

// Transitions
@transition-base: 0.3s ease;
@transition-fast: 0.15s ease;
@transition-slow: 0.5s ease;

// Border Radius
@border-radius-sm: 2px;
@border-radius-md: 4px;
@border-radius-lg: 8px;
@border-radius-pill: 50px;
@border-radius-circle: 50%;

// Shadows
@shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
@shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
@shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
@shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.15);

// Container widths
@container-sm: 540px;
@container-md: 720px;
@container-lg: 960px;
@container-xl: 1140px;
```

### Variable Interpolation
```less
// Use interpolation for dynamic property names
@property: margin;
@position: top;

.element {
  @{property}-@{position}: @spacing-md;
}

// Output: margin-top: 16px;
```

## Mixins

### Basic Mixins
```less
// mixins.less

// Clearfix
.clearfix() {
  &::after {
    content: '';
    display: table;
    clear: both;
  }
}

// Flexbox utilities
.flex-center() {
  display: flex;
  align-items: center;
  justify-content: center;
}

.flex-between() {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.flex-column() {
  display: flex;
  flex-direction: column;
}

// Usage
.container {
  .flex-center();
  min-height: 100vh;
}
```

### Parametric Mixins
```less
// Mixins with parameters
.button-variant(@bg-color, @text-color: white) {
  background-color: @bg-color;
  color: @text-color;
  border: none;

  &:hover {
    background-color: darken(@bg-color, 10%);
  }

  &:active {
    background-color: darken(@bg-color, 15%);
  }

  &:disabled {
    background-color: lighten(@bg-color, 20%);
    cursor: not-allowed;
  }
}

// Usage
.btn-primary {
  .button-variant(@color-primary);
}

.btn-secondary {
  .button-variant(@color-secondary);
}

.btn-danger {
  .button-variant(@color-error);
}
```

### Responsive Mixins
```less
// Media query mixins
.respond-to(@breakpoint, @rules) {
  @media (min-width: @breakpoint) {
    @rules();
  }
}

.respond-below(@breakpoint, @rules) {
  @media (max-width: (@breakpoint - 1px)) {
    @rules();
  }
}

.respond-between(@min, @max, @rules) {
  @media (min-width: @min) and (max-width: (@max - 1px)) {
    @rules();
  }
}

// Usage
.element {
  width: 100%;

  .respond-to(@breakpoint-md, {
    width: 50%;
  });

  .respond-to(@breakpoint-lg, {
    width: 33.333%;
  });
}
```

### Typography Mixins
```less
.font-size(@size, @line-height: @line-height-base) {
  font-size: @size;
  line-height: @line-height;
}

.truncate(@lines: 1) when (@lines = 1) {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.truncate(@lines) when (@lines > 1) {
  display: -webkit-box;
  -webkit-line-clamp: @lines;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

// Heading styles
.heading(@size) {
  font-family: @font-family-heading;
  font-size: @size;
  font-weight: @font-weight-bold;
  line-height: @line-height-heading;
  margin-bottom: @spacing-md;
}

// Usage
h1 {
  .heading(@font-size-h1);
}

.card-title {
  .truncate(2);
}
```

### Accessibility Mixins
```less
.visually-hidden() {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.focus-visible() {
  &:focus-visible {
    outline: 2px solid @color-primary;
    outline-offset: 2px;
  }
}

// Usage
.sr-only {
  .visually-hidden();
}

.interactive-element {
  .focus-visible();
}
```

## BEM Naming Convention

```less
// Block Element Modifier pattern
.card {
  // Block styles
  background: @color-background;
  border-radius: @border-radius-md;
  box-shadow: @shadow-md;
  overflow: hidden;

  // Element: child of block
  &__header {
    padding: @spacing-md;
    border-bottom: 1px solid @color-border;
  }

  &__title {
    margin: 0;
    font-size: @font-size-large;
    font-weight: @font-weight-bold;
  }

  &__image {
    width: 100%;
    height: auto;
    display: block;
  }

  &__body {
    padding: @spacing-md;
  }

  &__footer {
    padding: @spacing-md;
    border-top: 1px solid @color-border;
    background: lighten(@color-border, 5%);
  }

  // Modifier: variant of block
  &--featured {
    border: 2px solid @color-primary;
  }

  &--horizontal {
    display: flex;

    .card__image {
      width: 200px;
      flex-shrink: 0;
    }
  }

  &--compact {
    .card__header,
    .card__body,
    .card__footer {
      padding: @spacing-sm;
    }
  }
}
```

## Nesting Rules

### Keep Nesting Shallow
```less
// BAD: Too deep nesting
.nav {
  .nav-list {
    .nav-item {
      .nav-link {
        .nav-icon {
          // 5 levels - creates high specificity
        }
      }
    }
  }
}

// GOOD: Flat BEM structure with shallow nesting
.nav {
  display: flex;
  align-items: center;
}

.nav__list {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
}

.nav__item {
  margin: 0 @spacing-sm;
}

.nav__link {
  color: @color-text;
  text-decoration: none;
  transition: color @transition-base;

  // Acceptable: state nesting
  &:hover,
  &:focus {
    color: @color-primary;
  }

  // Acceptable: modifier nesting
  &--active {
    color: @color-primary;
    font-weight: @font-weight-bold;
  }
}
```

### Acceptable Nesting Patterns
```less
.component {
  // Pseudo-elements
  &::before,
  &::after {
    content: '';
    position: absolute;
  }

  // State pseudo-classes
  &:hover,
  &:focus,
  &:active {
    // State styles
  }

  // BEM modifiers
  &--variant {
    // Modifier styles
  }

  // Media queries
  .respond-to(@breakpoint-md, {
    // Responsive styles
  });
}
```

## Functions

### Built-in Functions
```less
// Color functions
.element {
  // Lighten/darken
  background: lighten(@color-primary, 20%);
  border-color: darken(@color-primary, 10%);

  // Saturation
  color: saturate(@color-primary, 20%);

  // Mix colors
  background: mix(@color-primary, @color-secondary, 50%);

  // Fade (opacity)
  background: fade(@color-primary, 50%);

  // Color extraction
  @hue: hue(@color-primary);
  @saturation: saturation(@color-primary);
  @lightness: lightness(@color-primary);
}

// Math functions
.element {
  width: percentage(1/3);        // 33.33333%
  height: round(10.5px);         // 11px
  margin: ceil(4.2px);           // 5px
  padding: floor(4.8px);         // 4px
  font-size: abs(-10px);         // 10px
  z-index: min(5, 10, 3);        // 3
  z-index: max(5, 10, 3);        // 10
}

// String functions
@selector: e(".my-class");      // Escape
@path: %("url(%s)", "image.png"); // Format
```

### Custom Functions (Using Mixins)
```less
// Less doesn't have true functions, use mixins with output
.spacing(@multiplier) {
  @result: (@spacing-unit * @multiplier);
}

// Usage with variable scope
.element {
  .spacing(3);
  padding: @result; // 24px
}

// Alternative: use variables directly
.padding(@multiplier) {
  padding: (@spacing-unit * @multiplier);
}

.margin(@multiplier) {
  margin: (@spacing-unit * @multiplier);
}

.element {
  .padding(2);
  .margin(1);
}
```

## Loops

### Generating Classes
```less
// Generate column classes
.generate-columns(@n, @i: 1) when (@i =< @n) {
  .col-@{i} {
    width: percentage(@i / @n);
  }
  .generate-columns(@n, (@i + 1));
}

// Usage: generates .col-1 through .col-12
.generate-columns(12);

// Generate spacing utilities
.generate-spacing(@i: 0) when (@i =< 8) {
  .m-@{i} {
    margin: (@spacing-unit * @i);
  }
  .mt-@{i} {
    margin-top: (@spacing-unit * @i);
  }
  .mb-@{i} {
    margin-bottom: (@spacing-unit * @i);
  }
  .p-@{i} {
    padding: (@spacing-unit * @i);
  }
  .pt-@{i} {
    padding-top: (@spacing-unit * @i);
  }
  .pb-@{i} {
    padding-bottom: (@spacing-unit * @i);
  }
  .generate-spacing((@i + 1));
}

.generate-spacing();
```

### Loop Over Lists
```less
// Define color list
@color-names: primary, secondary, success, danger, warning, info;
@color-values: @color-primary, @color-secondary, @color-success, @color-error, @color-warning, @color-info;

// Generate color utilities
.generate-colors(@names, @values, @i: 1) when (@i =< length(@names)) {
  @name: extract(@names, @i);
  @value: extract(@values, @i);

  .text-@{name} {
    color: @value;
  }
  .bg-@{name} {
    background-color: @value;
  }
  .border-@{name} {
    border-color: @value;
  }

  .generate-colors(@names, @values, (@i + 1));
}

.generate-colors(@color-names, @color-values);
```

## Guards (Conditionals)

```less
// Mixin with guards
.button-size(@size) when (@size = small) {
  padding: @spacing-xs @spacing-sm;
  font-size: @font-size-small;
}

.button-size(@size) when (@size = medium) {
  padding: @spacing-sm @spacing-md;
  font-size: @font-size-base;
}

.button-size(@size) when (@size = large) {
  padding: @spacing-md @spacing-lg;
  font-size: @font-size-large;
}

// Usage
.btn-sm {
  .button-size(small);
}

.btn-md {
  .button-size(medium);
}

.btn-lg {
  .button-size(large);
}

// Guards with comparison operators
.set-color(@lightness) when (@lightness > 50%) {
  color: black;
}

.set-color(@lightness) when (@lightness =< 50%) {
  color: white;
}
```

## Namespacing

```less
// Group related mixins
#utils {
  .clearfix() {
    &::after {
      content: '';
      display: table;
      clear: both;
    }
  }

  .visually-hidden() {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
  }
}

#buttons {
  .base() {
    display: inline-flex;
    align-items: center;
    border: none;
    cursor: pointer;
    transition: all @transition-base;
  }

  .primary() {
    #buttons.base();
    background: @color-primary;
    color: white;
  }
}

// Usage
.container {
  #utils.clearfix();
}

.btn-primary {
  #buttons.primary();
}
```

## Performance Best Practices

- Avoid deeply nested selectors (max 3 levels)
- Keep specificity low - prefer single class selectors
- Never use `!important` except for utility overrides
- Use mixins for vendor prefixes (or autoprefixer)
- Minimize use of `extend` as it can increase file size
- Compile to compressed CSS in production
- Enable source maps in development only

## Code Style Guidelines

- Use 2 spaces for indentation
- Use single quotes for strings
- Add a space after colons in declarations
- Add a space before opening braces
- Put closing braces on new lines
- Separate rule sets with blank lines
- Comment complex logic
- Order properties consistently

## Property Order

```less
.element {
  // Positioning
  position: relative;
  top: 0;
  right: 0;
  z-index: @z-index-dropdown;

  // Display & Box Model
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: @container-md;
  padding: @spacing-md;
  margin: @spacing-sm auto;

  // Typography
  font-family: @font-family-base;
  font-size: @font-size-base;
  font-weight: @font-weight-normal;
  line-height: @line-height-base;
  color: @color-text;
  text-align: left;

  // Visual
  background-color: @color-background;
  border: 1px solid @color-border;
  border-radius: @border-radius-md;
  box-shadow: @shadow-sm;

  // Animation
  transition: all @transition-base;

  // Misc
  cursor: pointer;
  overflow: hidden;
}
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.