Руководство по HTML/CSS/JavaScript

    Frontend Guidelines

    Правила и руководства оформления, форматирования HTML, СSS и JavaScript кода. Его цель — повысить качество кода и облегчить совместную работу и поддержку инфраструктуры.

    От переводчика

    Приветствую всех снова, меня зовут Максим Иванов, и сегодня я подготовил перевод, который, возможно, окажется для вас полезным. Бенджамин Де Кук (Benjamin De Cock), разработчик из Бельгии, собрал некоторые указания по оформлению кода, которые позиционируют себя как лучшие практики по написанию HTML, CSS, JS. Конечно, существует множество рекомендаций, например, есть хороший гайдлайн от Google, наверное, есть еще что-то, однако, если следовать хотя бы некоторым из них, то можно надеяться, что ваш код станет лучше. В отдельных случаях следование этим гайдлайнам не полезно, а совсем наоборот. В общем и целом, все зависит от вашего опыта и виденья дела, если вы новичок, то скорее вам будет полезно оценить то, что пишут другие и в обществе считается верным, если вы гуру, то наверное вам и не нужны гайдлайны, которые написаны непонятно кем на ваш взгляд. Итак, приступим.


    HTML


    1. Семантика
    2. Лаконичность
    3. Читабельность
    4. Язык документа
    5. Эффективность


    CSS


    1. Точка с запятой
    2. Блочная модель
    3. Потоки
    4. Позиционирование
    5. Селекторы
    6. Специфичность
    7. Переопределения
    8. Наследование
    9. Лаконичность
    10. Англоязычные обозначения
    11. Вендорные префиксы
    12. Анимация
    13. Единицы измерения
    14. Цветовая модель
    15. Отрисовка
    16. Хаки


    JavaScript


    1. Производительность
    2. Независимость от внешнего состояния
    3. Нативность
    4. Принудительное сравнение
    5. Циклы
    6. Аргументы
    7. Использование метода apply
    8. Использование метода bind
    9. Методы высшего порядка
    10. Композиции
    11. Кэширование
    12. Переменные
    13. Условия
    14. Итератор
    15. Объект как ассоциативный массив
    16. Каррирование
    17. Читабельность
    18. Повторное использование кода
    19. Зависимости


    HTML


    Семантика


    HTML5 предоставляет нам достаточное количество элементов, направленных на точное семантическое описание документа или содержимого. Поэтому, убедитесь в том, что у вас все хорошо с лексикой.

    <!-- плохо -->
    <div id="main">
      <div class="article">
        <div class="header">
          <h1>Blog post</h1>
          <p>Published: <span>21st Feb, 2015</span></p>
        </div>
        <p>…</p>
      </div>
    </div>
    
    <!-- хорошо -->
    <main>
      <article>
        <header>
          <h1>Blog post</h1>
          <p>Published: <time datetime="2015-02-21">21st Feb, 2015</time></p>
        </header>
        <p>…</p>
      </article>
    </main>
    


    Убедитесь, что вы поняли семантику элементов, которые вы используете в своем коде. Очень плохо использовать семантические элементы не по назначению или не в том месте, если бы вы просто оставались нейтральными к этим этим семантическим элементам.

    <!-- плохо -->
    <h1>
      <figure>
        <img alt=Company src=logo.png>
      </figure>
    </h1>
    
    <!-- хорошо -->
    <h1>
      <img alt=Company src=logo.png>
    </h1>
    


    Лаконичность


    Старайтесь кратко писать код. Забудьте о своих старых привычках, перетекающих из XHTML.

    <!-- плохо -->
    <!doctype html>
    <html lang=en>
      <head>
        <meta http-equiv=Content-Type content="text/html; charset=utf-8" />
        <title>Contact</title>
        <link rel=stylesheet href=style.css type=text/css />
      </head>
      <body>
        <h1>Contact me</h1>
        <label>
          Email address:
          <input type=email placeholder=you@email.com required=required />
        </label>
        <script src=main.js type=text/javascript></script>
      </body>
    </html>
    
    <!-- хорошо (но не семантично) -->
    <!doctype html>
    <html lang=en>
      <meta charset=utf-8>
      <title>Contact</title>
      <link rel=stylesheet href=style.css>
    
      <h1>Contact me</h1>
      <label>
        Email address:
        <input type=email placeholder=you@email.com required>
      </label>
      <script src=main.js></script>
    </html>
    


    Читабельность


    Читабельность вашего кода не должна иметь второстепенный характер. Конечно, вы не обязаны быть экспертом по оптимизации (WCAG) для того, чтобы наверняка улучшить свой сайт, однако, уже прямо сейчас вы можете начать немедленно исправлять мелочи, которые в итоге помогут сделать ваш код лучше, например:

    — использовать атрибут alt правильно
    — связывайте имена (links) и элементы (buttons) и называйте их по смыслу (<div class=button> — это зверство)
    — не полагайтесь на название цветов, в качестве информации
    — явно связывайте определенной меткой и элемент формы

    <!-- плохо -->
    <h1><img alt="Logo" src="logo.png"></h1>
    
    <!-- хорошо -->
    <h1><img alt="My Company, Inc." src="logo.png"></h1>
    


    Язык документа


    Определении языка и кодировки символов не является обязательным, однако рекомендуется всегда объявлять их на уровне документа, даже если они указаны в заголовках HTTP. Приоритетной кодировкой символов является UTF-8.

    <!-- плохо -->
    <!doctype html>
    <title>Привет, мир.</title>
    
    <!-- хорошо -->
    <!doctype html>
    <html lang=ru>
      <meta charset=utf-8>
      <title>Привет, мир.</title>
    </html>
    


    Эффективность


    Если нет уважительных причин добавлять загрузку скриптов до контента, старайтесь прописывать скрипты в конце документа, тем самым ваши скрипты не будут блокировать рендеринг страницы. Если у вас очень тяжелые таблицы стилей, старайтесь разбить их на несколько и загружать по отдельности, так чтобы первичный контент был сразу отрисован. Очевидно, чем больше файлов, тем больше HTTP запросов, два запроса, конечно, медленнее, чем один, но в нашем случае, важным фактором будет являться скорость отображения нужного контента.

    <!-- плохо -->
    <!doctype html>
    <meta charset=utf-8>
    <script src=analytics.js></script>
    <title>Hello, world.</title>
    <p>...</p>
    
    <!-- хорошо -->
    <!doctype html>
    <meta charset=utf-8>
    <title>Hello, world.</title>
    <p>...</p>
    <script src=analytics.js></script>
    


    CSS


    Точка с запятой


    В то время как точка с запятой является чисто технически разделителем правил, CSS всегда относится к точке запятой, как к оператору завершения.

    /* плохо */
    div {
      color: red
    }
    
    /* хорошо */
    div {
      color: red;
    }
    


    Box model


    Блочная модель, в идеале, должно быть одинаковой для всего документа. Глобальное правило * { box-sizing: border-box; } это нормально, однако нужно помнить, что вы не можете изменить блочную модель у специфичных элементов.

    /* плохо */
    div {
      width: 100%;
      padding: 10px;
      box-sizing: border-box;
    }
    
    /* хорошо */
    div {
      padding: 10px;
    }
    


    Потоки


    Не меняйте стандартное поведение элемента, если вы можете обойтись без этого. Сохраняйте элементы в их классическом отображении в потоке документа. Например, удаление пробелов под изображением, не должно влиять на его отображение.

    /* плохо */
    img {
      display: block;
    }
    
    /* хорошо */
    img {
      vertical-align: middle;
    }
    


    Аналогично, не вытаскивайте из основного потока элементы, если вы можете обойтись без этого.

    /* плохо */
    div {
      width: 100px;
      position: absolute;
      right: 0;
    }
    
    
    /* хорошо */
    div {
      width: 100px;
      margin-left: auto;
    }
    


    Позиционирование


    Существует множество способов позиционирования элементов в CSS, однако старайтесь ограничивать себя свойствами представленными ниже. В порядке предпочтения:

    display: block;
    display: flex;
    position: relative;
    position: sticky;
    position: absolute;
    position: fixed;
    


    Селекторы


    Минимизируйте сочетания селекторов связанных с DOM. Иногда, лучше добавить лишний класс элементу, который вы хотите найти, чем искать его через три структурных селектора: псевдо-класс, потомок, комбинатор.

    /* плохо */
    div:first-of-type :last-child > p ~ *
    
    /* хорошо */
    div:first-of-type .info
    


    Избегайте перегрузку селекторов.

    /* плохо */
    img[src$=svg], ul > li:first-child {
      opacity: 0;
    }
    
    /* хорошо */
    [src$=svg], ul > :first-child {
      opacity: 0;
    }
    


    Специфичность


    Не используйте значения и селекторы, которые нельзя переопределить. Минимизируйте использование id (идентификаторов) и избегайте правило !important

    /* плохо */
    .bar {
      color: green !important;
    }
    .foo {
      color: red;
    }
    
    /* хорошо */
    .foo {
      color: red;
    }
    .foo.bar {
      color: green;
    }
    


    Переопределения


    Переопределение стилей селекторов затрудняет отладку. Избегайте этого, если можете.

    /* плохо */
    li {
      visibility: hidden;
    }
    li:first-child {
      visibility: visible;
    }
    
    /* хорошо */
    li + li {
      visibility: hidden;
    }
    


    Наследование


    Не дублируйте определения селекторов, стили которых и так могут передаваться по наследству.

    /* плохо */
    div h1, div p {
      text-shadow: 0 1px 0 #fff;
    }
    
    /* хорошо */
    div {
      text-shadow: 0 1px 0 #fff;
    }
    


    Лаконичность


    Пусть ваш код будет немногословным. Старайтесь избегать использование несколько свойств в том месте, где это вовсе не нужно.

    /* плохо */
    div {
      transition: all 1s;
      top: 50%;
      margin-top: -10px;
      padding-top: 5px;
      padding-right: 10px;
      padding-bottom: 20px;
      padding-left: 10px;
    }
    
    /* хорошо */
    div {
      transition: 1s;
      top: calc(50% - 10px);
      padding: 5px 10px 20px;
    }
    


    Англоязычные обозначения


    Предпочтительно использовать английскую математику.

    /* плохо */
    :nth-child(2n + 1) {
      transform: rotate(360deg);
    }
    
    /* хорошо */
    :nth-child(odd) {
      transform: rotate(1turn);
    }
    


    Вендорные префиксы


    Не используйте устаревшие префиксы. Если вам действительно необходимо использовать их, в этом случае, добавляйте их перед стандартными.

    /* плохо */
    div {
      transform: scale(2);
      -webkit-transform: scale(2);
      -moz-transform: scale(2);
      -ms-transform: scale(2);
      transition: 1s;
      -webkit-transition: 1s;
      -moz-transition: 1s;
      -ms-transition: 1s;
    }
    
    /* хорошо */
    div {
      -webkit-transform: scale(2);
      transform: scale(2);
      transition: 1s;
    }
    


    Анимация


    Иногда предпочтительнее использовать переходы (transitions), нежели анимацию (animations). Избегайте анимирование свойств в пользу opacity и transform.

    /* плохо */
    div:hover {
      animation: move 1s forwards;
    }
    @keyframes move {
      100% {
        margin-left: 100px;
      }
    }
    
    /* хорошо */
    div:hover {
      transition: 1s;
      transform: translateX(100px);
    }
    


    Единицы измерения


    Используйте безразмерные значения. Старайтесь использовать rem, если вы рассчитываете все в относительных единицах. Предпочтительно использовать секунды, а не миллисекунды.

    /* плохо */
    div {
      margin: 0px;
      font-size: .9em;
      line-height: 22px;
      transition: 500ms;
    }
    
    /* хорошо */
    div {
      margin: 0;
      font-size: .9rem;
      line-height: 1.5;
      transition: .5s;
    }
    


    Цветовая модель


    Если нужна прозрачность, использовать rgba. В противном случае, всегда используйте шестнадцатеричный формат.

    /* плохо */
    div {
      color: hsl(103, 54%, 43%);
    }
    
    /* хорошо */
    div {
      color: #5a3;
    }
    


    Отрисовка


    Избегайте http-запросов, если ресурс легко воспроизводится с помощью CSS.

    /* плохо */
    div::before {
      content: url(white-circle.svg);
    }
    
    /* хорошо */
    div::before {
      content: "";
      display: block;
      width: 20px;
      height: 20px;
      border-radius: 50%;
      background: #fff;
    }
    


    Хаки


    Не используйте их.

    /* плохо */
    div {
      // position: relative;
      transform: translateZ(0);
    }
    
    /* хорошо */
    div {
      /* position: relative; */
      will-change: transform;
    }
    


    JavaScript


    Производительность


    Легкочитаемый, выразительный и правильный код важнее производительности. На самом деле, JavaScript никогда не будет вашим узким местом в расчете на производительность. Лучше уделять внимание таким вещам, как сжатие изображений, оптимизация http-запросов и доступа к сети, перерасчет DOM-дерева. Если вы запомните хотя бы одну из рекомендаций в данной статье, опирайтесь на нее.

    /* плохо (хотя и намного быстрее) */
    const arr = [1, 2, 3, 4];
    const len = arr.length;
    var i = -1;
    var result = [];
    while (++i < len) {
      var n = arr[i];
      if (n % 2 > 0) continue;
      result.push(n * n); 
    }
    
    /* хорошо */
    const arr = [1, 2, 3, 4];
    const isEven = n => n % 2 == 0; // инициализация анонимной стрелочной функции
    const square = n => n * n; // синтаксис: (param1, param2, …, paramN) => expression
    
    const result = arr.filter(isEven).map(square);
    
    


    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо
    2. Стрелочные функции и перебирающие методы массивов

    Независимость от внешнего состояния


    Старайтесь создавать свободные функции. Все функции и методы в идеале не должны нести никакого побочного характера, зависеть от внешних данных, и в итоге, они должны возвращать новые объекты, а не вносить изменения в существующие.

    /* плохо */
    const merge = (target, ...sources) => Object.assign(target, ...sources);
    merge({ foo: "foo" }, { bar: "bar" }); // => { foo: "foo", bar: "bar" }
    
    /* хорошо */
    const merge = (...sources) => Object.assign({}, ...sources);
    merge({ foo: "foo" }, { bar: "bar" }); // => { foo: "foo", bar: "bar" }
    
    


    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо
    2. Остаточные параметры

    Нативность


    Полагайтесь на стандартные методы, как можно больше.

    /* плохо */
    const toArray = obj => [].slice.call(obj);
    
    /* хорошо */
    const toArray = (() =>
      Array.from ? Array.from : obj => [].slice.call(obj)
    )();
    


    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо
    2. Массивоподобные объекты

    Принудительное сравнение


    Лишние сравнения не имеют смысл, избегайте их.

    /* плохо */
    if (x === undefined || x === null) { /* ... */  }
    
    /* хорошо */
    if (x == undefined) { /* ... */  }
    


    К прочтению:
    1. Сравнение с null и undefined

    Циклы


    Не используйте циклы, так как они заставляют вас использовать изменяемые объекты. Полагайтесь на методы Array.prototype.

    /* плохо */
    const sum = arr => {
      var sum = 0;
      var i = -1;
      for (;arr[++i];) {
        sum += arr[i];
      }
      return sum;
    };
    
    sum([1, 2, 3]); // => 6
    
    /* хорошо */
    const sum = arr => arr.reduce((x, y) => x + y);
    
    sum([1, 2, 3]); // => 6
    


    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо
    2. Суммирование всех значений в массиве

    Если вы не можете использовать методы Array.prototype, используйте рекурсию.

    /* плохо */
    const createDivs = howMany => {
      while (howMany--) {
        document.body.insertAdjacentHTML("beforeend", "<div></div>");
      }
    };
    
    createDivs(5);
    
    /* плохо */
    const createDivs = howMany =>
      [...Array(howMany)].forEach(() =>
        document.body.insertAdjacentHTML("beforeend", "<div></div>")
      );
    
    createDivs(5);
    
    
    /* хорошо */
    const createDivs = howMany => {
      if (!howMany) return;
      document.body.insertAdjacentHTML("beforeend", "<div></div>");
      return createDivs(howMany - 1);
    };
    
    createDivs(5);
    


    Вот общая функция Loop, делающая рекурсию проще в использовании.

    К прочтению:
    1. Babeljs (пример в ES5): плохо (или) vs хорошо
    2. insertAdjacentHTML() работает быстрее, чем манипуляции с innerHTML()

    Аргументы


    Забудьте об arguments как об объекте. Остаточные параметры это всегда лучший вариант, потому что:
    1. Передаваемое имя дает лучшее представление о том, что ожидает функция на входе
    2. Остаточный параметр — это массив и он легок в использовании

    /* плохо */
    const sortNumbers = () =>
      Array.prototype.slice.call(arguments).sort();
    
    /* хорошо */
    const sortNumbers = (...numbers) => numbers.sort();
    


    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо
    2. Доступ к аргументам

    Использование метода apply


    Забудьте метода apply(). Вместо этого используйте оператор распространения (вызова функции).

    const greet = (first, last) => `Hi ${first} ${last}`;
    const person = ["John", "Doe"];
    
    /* плохо */
    greet.apply(null, person);
    
    /* хорошо */
    greet(...person);
    


    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо
    2. Оператор распространения

    Использование метода bind


    Не используйте bind(), когда есть более идиоматические подходы.

    /* плохо */
    ["foo", "bar"].forEach(func.bind(this));
    
    /* хорошо */
    ["foo", "bar"].forEach(func, this);
    


    /* плохо */
    const person = {
      first: "John",
      last: "Doe",
      greet() {
        const full = function() {
          return `${this.first} ${this.last}`;
        }.bind(this);
        return `Hello ${full()}`;
      }
    }
    
    /* хорошо */
    const person = {
      first: "John",
      last: "Doe",
      greet() {
        const full = () => `${this.first} ${this.last}`;
        return `Hello ${full()}`;
      }
    }
    


    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо
    2. bind(), а также итераторы в JavaScript

    Методы высшего порядка


    Избегайте вложенных функций там где это не нужно.

    /* плохо */
    const result = [1, 2, 3].map(num => String(num)); // => ["1", "2", "3"]
    
    /* хорошо */
    const result = [1, 2, 3].map(String);  // Приведение всех элементов к типу string
    


    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо
    2. Отображение массива чисел с использованием функции

    Композиции


    Избегайте несколько вложенных вызовов функций. Используйте вместо них композицию.

    const plus1 = a => a + 1;
    const mult2 = a => a * 2;
    
    /* плохо */
    mult2(plus1(5)); // => 12
    
    /* хорошо */
    const pipeline = (...funcs) => val => funcs.reduce((a, b) => b(a), val);
    const addThenMult = pipeline(plus1, mult2);
    
    addThenMult(5); // => 12
    


    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо

    Кеширование


    Дорогостоящие операции с большими структурами данных непростительны, если вы не кешируете их.

    /* плохо */
    const contains = (arr, value) =>
      Array.prototype.includes
        ? arr.includes(value)
        : arr.some(el => el === value);
    contains(["foo", "bar"], "baz"); // => false
    
    /* хорошо */
    const contains = (() =>
      Array.prototype.includes
        ? (arr, value) => arr.includes(value)
        : (arr, value) => arr.some(el => el === value)
    )();
    contains(["foo", "bar"], "baz"); // => false
    


    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо
    2. Определяем, находится ли одна строка внутри другой, а также делаем проверку значений элементов массива

    Переменные


    Используйте const вместо let и let вместо var.

    /* плохо */
    var me = new Map();
    me.set("name", "Ben").set("country", "Belgium");
    
    /* хорошо */
    const me = new Map();
    me.set("name", "Ben").set("country", "Belgium");
    


    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо
    2. Константы, оператор let, и немного об ассоциативном массиве

    Условия


    Будьте привержены концепции IIFE's (немедленно выполняемый функтор), используйте возвращаемые значения в условиях (if, else if, else и switch).

    /* плохо */
    var grade, result = 50;
    if (result < 50)
      grade = "bad";
    else if (result < 90)
      grade = "good";
    else
      grade = "excellent";
      
    // grade = "good";
    
    /* хорошо */
    let result = 50;
    const grade = (() => {
      if (result < 50)
        return "bad";
      if (result < 90)
        return "good";
      return "excellent";
    })(); // grade = "good";
    


    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо (или)
    2. Немедленно вызываемые функции

    Итераторы


    Избегайте цикл перебора for...in

    const shared = { foo: "foo" };
    const obj = Object.create(shared, {
      bar: {
        value: "bar",
        enumerable: true
      }
    });
    
    /* плохо */
    for (var prop in obj) {
      if (obj.hasOwnProperty(prop))
        console.log(prop); // => bar
    }
    
    /* хорошо */
    Object.keys(obj).forEach(prop => console.log(prop));
    


    Разница между циклом и методом в том, что цикл перечисляет свойства и из цепочки прототипов.

    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо
    2. Использование hasOwnProperty для проверки существования свойства и обход свойств объекта

    Объект как ассоциативный массив


    В то время как объекты можно законно использовать, как правило, ассоциативный массив (Map) лучше и мощнее. Если сомневаетесь, тогда точно используйте Map.

    /* плохо */
    const me = {
      name: "Ben",
      age: 30
    };
    var meSize = Object.keys(me).length;
    meSize; // => 2
    me.country = "Belgium"; // можно 
    meSize++;
    meSize; // => 3
    
    /* хорошо */
    const me = new Map();
    me.set("name", "Ben");
    me.set("age", 30);
    me.size; // => 2
    me.set("country", "Belgium");
    me.size; // => 3
    


    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо
    2. Коллекция для хранения записей вида ключ: значение

    Каррирование


    Каррирование является мощной, но в свою очередь чужеродной парадигмой для многих разработчиков. Не злоупотребляйте.

    /* плохо */
    const sum = a => b => a + b;
    sum(5)(3); // => 8
    
    /* хорошо */
    const sum = (a, b) => a + b;
    sum(5, 3); // => 8
    


    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо
    2. Каррирование и примеры

    Читабельность


    Не скрывайте намерения вашего кода, используя умные трюки.

    /* плохо */
    foo || doSomething();
    
    /* плохо */
    void function() { /* IIFE */ }();
    
    /* плохо */
    const n = ~~3.14;
    
    /* хорошо */
    if (!foo) doSomething();
    
    /* хорошо */
    (function() { /* IIFE */ }());
    
    /* хорошо */
    const n = Math.floor(3.14);
    


    К прочтению:
    1. Об идеальном коде и суровой реальности

    Повторное использование кода


    Не бойтесь создавать много мелких и многоразовых функций, они очень полезны.

    /* плохо */
    let last = arr[arr.length - 1];
    
    /* плохо */
    const product = (a, b) => a * b;
    const triple = n => n * 3;
    
    /* хорошо */
    const first = arr => arr[0]; // => first(arr);
    const last = arr => first(arr.slice(-1)); // => last(arr);
    
    /* хорошо */
    const product = (a, b) => a * b;
    const triple = product.bind(null, 3);
    


    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо

    Зависимости


    Минимизируйте зависимости стороннего кода, если вы не в курсе как он работает. Не нужно загружать всю библиотеку ради нескольких методов, которые легко воспроизводимы:

    /* плохо */
    var _ = require("underscore");
    _.compact(["foo", 0]));
    _.unique(["foo", "foo"]);
    _.union(["foo"], ["bar"], ["foo"]);
    
    /* хорошо */
    const compact = arr => arr.filter(el => el);
    const unique = arr => [...Set(arr)];
    const union = (...arr) => unique([].concat(...arr));
    
    compact(["foo", 0]);
    unique(["foo", "foo"]);
    union(["foo"], ["bar"], ["foo"]);
    


    К прочтению:
    1. Babeljs (пример в ES5): плохо vs хорошо
    2. Путь JavaScript модуля и документация по библиотеке Underscore
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 38

      +13
      Тэги head и body уже отменили, я что-то пропустил?
      habrahabr.ru/post/275729/#two
        +6
        Стандарт HTML5
        По нему теги body и head могут не использоваться.
        Но мне лично они помогают ориентироваться в разметке и использовать для структурирования кода документа.
        • UFO just landed and posted this here
            0
            А смысл?
            • UFO just landed and posted this here
                +2
                Ну то есть в переводе на русский: эти тэги допустимо опускать, и ничего не должно ломаться. Своеобразная защита от дурака (что несомненно полезно), но нет никаких разумных аргументов, что так нужно делать.

                PS Из статьи по ссылке узнал о единице ch
                • UFO just landed and posted this here
          +7
          На самом деле, JavaScript никогда не будет вашим узким местом в расчете на производительность.

          Ага. Кроме всего кода, который вызывается из колбека window.requestAnimationFrame. Или если вам нужно читать много данных из WebSocket. С этого момента микрооптимизации ваш лучший друг. Никаких forEach. Никакого кода, который плохо переваривается оптимизатором. И обращайте внимание на то, что именно идёт в прототип, а что в сам объект. Кроме того старайтесь не использовать классы.

          Ах, да. Если вы решили использовать какие либо соглашения, то запишите это на видном месте. Например в README проекта. Но при этом старайтесь не раздувать подобные документы до огромных размеров.
            +6
            /* хорошо */
            .foo.bar {
            color: green;
            }
            .foo {
            color: red;
            }

            Вот как раз в этом месте сначала логичнее указать .foo, а ниже уже .foo.bar

            /* плохо */
            if (x === undefined || x === null) { /*… */ }

            /* хорошо */
            if (x == undefined) { /*… */ }

            Опять же, иногда нужно явное сравнение с undefined. Это же JS! Вообще == и === нужно использовать только там, где это нужно. Хотите показать, что вы именно с undefined сравниваете, используйте ===, это не будет плохим кодом.

            Очень странно написано про каррирование. Из текста кажется, что это просто антипаттерн для всего.

            Понимаю, что перевод, но многие рекомендации из статьи обсуждаемы все же.
              +7
              Ещё, очень заинтересовало «всегда используйте рекурсию вместо циклов» с «отличным» примером.

              Теперь представим что данная фиговина добавляет 40 чего нибудь (не знаю, фотографий с обрамлением) на страничку. Глубина рекурсии получится 40 (Сорок, Карл!).

              «Оптимальней», ну да ну да :/
                0
                А js не умеет оптимизировать хвостовую рекурсию в цикл?
                  +1
                  По стандарту ES6 должет уметь. На данный момент реализовано в Babel; в node.js и браузерах ещё нет: kangax.github.io/compat-table/es6
                +8
                Я начал перечислять фактические ошибки и плохие советы, но быстро сломался.
                В итоге вывод простой: не следуйте советам из этой статьи. Вообще.

                P.S. Но вот это просто убило
                <!-- хорошо -->
                <!doctype html>
                <html lang=ru>
                  <meta charset=utf-8>
                  <title>Hello, world.</title>
                </html>

                Давно ль ‘Hello, world’ вошло в русский язык?…
                  +4
                  Не, ну некоторые советы вполне разумны.
                  Но, конечно, и много спорного, а местами и просто чуши.
                    +2
                    Ну да, совет в alt писать что-то осмысленное — норм.
                    Остальное — местами вкусовщина, местами непонимание, местами откровенно вредные советы.
                      +1
                      Вообще, весь второй раздел можно заменить на одну фразу «используйте CSS-препроцессоры, такие как LESS, SASS, Stylus» ну или что сейчас самое модное.
                        +1
                        ну или что сейчас самое модное

                        Говорят, что PostCSS.
                          +3
                          we-have-15-competing-standards.jpg
                          +1
                          Да не, там немало вопросов, которые не касаются технологии, но касаются логики построения стилей. Например, с пунктом 2.7 я согласен. И совершенно неважно, будет ли это делаться на голом CSS или на самом модном турбопрепостпроцессоре.
                            –1
                            А я нет. В таком примере, как у автора приведён — да, так не надо делать. Но легко можно представить кучу ситуаций, когда так делать надо. Например, первую букву слова выделить другим цветом.
                              +1
                              При чем тут первая буква?
                              Автор имеет в виду другое — нужно избегать схемы «указать свойство всем, а потом переопределить исключения».
                              Намного лучше выделить именно нужные элементы и стилизовать именно их (по возможности).
                                0
                                Ну да. Указал цвет для текста, а потом переопределил исключение (первую букву). Что не так?
                                Ну и вообще, показанный пример (li + li вместо li:first-child) конфликтует с первым же правилом «явное лучше неявного».
                                  0
                                  Под исключением тут подразумевается откат к предыдущим стилям, отмена только что написанного. Первая буква — не тот случай.
                      +2
                      Мдя. Удаление head и body это, конечно, ну оооочень семантично и просто замечательно повышает читабельность…

                      Легкочитаемый, выразительный и правильный код важнее производительности.

                      И следом вообще офигительный пример, со стрелочными функциями, который понять не-автору, если он будет хоть на пару строк длиннее — вообще задница. Потому что алгоритм становится совершенно неявным. Человек — не машина. Понять, что и в какой последовательности будет происходить в этом примере — ни разу не просто. А уже попробовать разобраться дебагом в пошаговом режиме и вовсе невозможно.

                      Отдельное объявление функций используемых только в одном месте — и вовсе архиглупость, т.к. заставляет «листать» выше-ниже, использование Inline записи в данном случае и лаконичнее и понятнее — т.к. сразу видно что и где происходит.

                      [12, 5, 8, 130, 44].filter(function (val) { return val >= 10; }).map(function(val){return val * val});
                      


                      Если вы не можете использовать методы Array.prototype, используйте рекурсию.

                      Омг… Супер-совет, для 10к элементов, например вообще отлично.

                      В общем, мне кажется переводчик чё-то попутал, и это был сборник советов как не надо делать.

                      Нет, конечно изучить и обдумать приведенные советы нужно. Но тут столько спорных моментов, что для новичков эта статья вообще крайне вредна (учитывая ее название «Руководство».
                      Да еще и массовое использование ES5 и CSS3, тоже штука хорошая — но только с оговорками и полифилами.

                      P.S. — на мой взгляд, спорными и обсуждаемыми тут являются почти все советы. Просто если на каждый поинт писать возражения — это будет уже статья, а не коммент…
                      • UFO just landed and posted this here
                          0
                          Семантическая вёрстка, или семантический HTML-код, — это подход к созданию веб-страниц на языке HTML, основанный на использовании HTML-тегов в соответствии с их семантикой (предназначением)[1], а также предполагающий логичную и последовательную иерархию страницы
                          © Википедия

                          Ну вот как-бы иерархию-то тут и ломают… Это если чисто формально подходить.

                          А если подойти не с формальной точки зрения, а по сути и смыслу семантической верстки — то всё еще хуже.

                          Ведь для чего вообще в html5 ввели новые тэги? Да как раз таки для создания структуры и иерархии контента! Всё, другого назначения у всяких «article» и «head» нету. С технической точки зрения их функции прекрасно выполняют div'ы

                          И разрушение структуры путем удаления «head» есть прямое нарушение принципов семантической верстки.
                          • UFO just landed and posted this here
                            • UFO just landed and posted this here
                        +1
                        Пожалуйста, расскажите подробней про кеширование. Немного не понял разницу двух примеров. Спасибо.
                          0
                          *кэширование
                          +1
                          Улыбнуло слово «ежели», а так ничего вроде
                          • UFO just landed and posted this here
                            –3
                            Мда. Название «Вредные советы» статье подошло бы лучше.
                            Кто не прыгал из окошка
                            Вместе с маминым зонтом,
                            Тот лихим парашютистом
                            Не считается пока.
                            Не лететь ему, как птице,
                            Над взволнованной толпой,
                            Не лежать ему в больнице
                            С забинтованной ногой.
                            ©Григорий Остер
                              –3
                              Если вы по коридору
                              Мчитесь на велосипеде,
                              А навстречу вам из ванной
                              Вышел папа погулять,
                              Не сворачивайте в кухню,
                              В кухне — твердый холодильник.
                              Тормозите лучше в папу.
                              Папа мягкий. Он простит.
                              0
                              комментарии сплошь отрицательные, а статья в огромном плюсе. странно сие
                                –1
                                Кто-нибудь может объяснить, почему первый пример к Который этому правилу помечен как «плохо»?!
                                  +1
                                  Меня умиляет манера изложения: «это — хорошо, это — плохо. dixi». Объяснить, аргументировать, почему так, а не так — не, зачем.
                                    0
                                    Определении языка и кодировки символов не является обязательным, однако рекомендуется всегда объявлять их на уровне документа, даже если они указаны в заголовках HTTP.

                                    Ну да, конечно.
                                    Допустим, в HTTP-заголовке идёт одна кодировка, в документе указана другая — такое бывает, видел много раз. Внимание, вопрос: в какой кодировке клиент увидит страницу?

                                    Мне кажется, указывать кодировку достаточно один раз — в HTTP-заголовке.

                                    Only users with full accounts can post comments. Log in, please.