Repozytorium Web Developera

Archiwum z lat 2013-2018, treści mogą być nieaktualne.

Organizacja styli CSS i skryptów JS

I’m sure I’ve said it before but the hardest thing about scaling a website is the CSS. JavaScript is easy, but with CSS you pay for your sins — once you’ve started a mess, it’s not easy to back out of.

Przydatne linki

Narzędzia i automatyzacja

Guidelines - wytyczne

Architectures - architektury

BEM - Block, Element, Modifier

Bardzo ważnym jest aby bloki były od siebie niezależne nawet do tego stopnia, że swobodnie można zagnieżdżać jeden w drugim lub wyciągać jeden zagnieżdżony w innym bloku i przenieść w zupełnie inne miejsce strony.

Zasady CSS:

  • Każdemu blokowi i/lub elementowi musimy nadać unikalną nazwę (w tym wypadku chodzi o klasę CSS), np. contact, contact__input lub contact__input--important
  • Nie używamy selektorów elementu HTML, jak np. div, input
  • Nie używamy selektorów id, jak np, #contact-form
  • Wystrzegamy się stosowania selektorów opartych o zasadę kaskadowości (selektory potomka), jak np. .contact__input label, lepiej np. .contact__input-label lub .contact__label

Organizacja styli

Struktura folderów

The 7-1 Pattern

  • base/ – contains global styles, such as resets, typography, colors, etc.
  • components/ – contains each self-contained component in its own .scss partial
  • layout/ – contains styling for larger layout components; e.g. nav, header, footer, etc.
  • pages/ – contains page-specific styling, if necessary
  • themes/ – contains styling for different themes
  • utils/ – contains global mixins, functions, helper selectors, etc.
  • vendors/ – contains 3rd-party styles, mixins, etc.
  • main.scss – output file that brings together all of the above parts

Each folder should have a single .scss partial file that collects the other files in the same directory – such as _module.scss (my preference) or _glob.scss. Then, you can reference each of these in the main.scss file:


// main.scss
@import 'base/module';
@import 'components/module';
@import 'layout/module';
@import 'pages/module';
@import 'themes/module';
@import 'utils/module';
@import 'vendors/module';

Palety kolorów

Mapowanie kolorów

Kolory powinny zostać zmapowane, a ich nazwy odzwierciedlać ich znaczenie - jeśli używamy Sass:


$app-colors: (
  'primary': #8e3329,
  'accent': #d98328,
  'secondary': #5a1321,
  'foreground': #191919,
  'background': #e9e9e9
);

Odwołujemy się do nich za pomocą funkcji:


@function app-color($key: 'primary') {
  @return map-get($app-colors, $key);
}

// Example:
$button-color: app-color('primary'); // #8e3329

Funkcja rozjaśniająca/przyciemniająca

Kolorów w palecie nie powinno być za wiele (około 4-7), do pozyskiwania większej ilości odcieni możemy skorzystać z funkcji rozjaśniającej/przyciemniającej dany kolor:


$color-interval: 10% !global;

@function app-color-level($color-name: 'primary', $level: 0) {
  $color: app-color($color-name);
  $color-base: if($level < 0, black, white);

  @return mix($color-base, $color, $level * $color-interval);
}

// Example:
.panel {
  background-color: app-color-level('primary', 2);
}

Funkcja ustalania przezroczystości

Do ustalania przezroczystości koloru używamy przykładowej funkcji:


$app-opacity: (
  'light': 0.8, // opacity used with lighter colors
  'dark': 0.4   // opacity used with darker colors
  // ... etc.
);

@function app-color-alpha($name: 'primary', $opacity: 0) {
  $color: app-color($name);

  // Get the named opacity level, if it exists
  @if map-key-exists($app-opacity, $opacity) {
    $opacity: map-get($app-opacity, $opacity);
  }

  // Use rgba() to manipulate the color's alpha level
  @return rgba($color, $opacity);
}

// Example usage:
$button-transparent-color: app-color-alpha('primary', 'light');
// => rgba(#8e3329, 0.8)

Typografia

Rozmiar

Podobnie jak w przypadku kolorów, mapujemy rozmiary fontów:


$type-scale: (
  -1: 0.75rem,  // small text
  0: 1rem,      // body text
  1: 1.333rem,  // large text
  2: 1.777rem   // main heading
);

@function type-scale($level) {
  @return map-get($type-scale, $level);
}

Wysokość linii

Mapujemy również wysokości poszczególnych linii:


$base-font-size: 1rem;
$base-line-height: $base-font-size * 1.25;

$line-heights: (
  -1: $base-line-height,
  0: $base-line-height,
  1: $base-line-height * 2,
  2: $base-line-height * 2
);

// Again, we can make a helper function:
@function line-height($level) {
  @return map-get($line-heights, $level);
}

Użycie

W celu użycia zdefiniowanych powyżej właściwości korzystamy z mixina:


@mixin type-setting($level: 0) {
  font-size: type-scale($level);
  line-height: line-height($level);
}

// The main heading
.heading-1 { @include type-setting(2); }

// The smaller top heading
.heading-2 { @include type-setting(-1); }

.paragraph { @include type-setting(0); }

.recipe-value { @include type-setting(1); }

.recipe-text { @include type-setting(-1); }

.recipe-button { @include type-setting(-1); }