├── CSS
└── README.md
├── Environment
├── README.md
├── branches-and-requests.md
├── conventional-commits.md
├── husky.md
└── lint-staged.md
├── HTML
└── README.md
├── Initiation.md
├── JS
└── README.md
├── README.md
└── React
├── Optimization.md
└── README.md
/CSS/README.md:
--------------------------------------------------------------------------------
1 | # CSS
2 |
3 | 1. [Общие требования](#1)
4 | 2. [Правила](#2)
5 | 3. [Шрифты](#3)
6 | 4. [БЭМ](#4)
7 | 5. [Возможные ошибки](#5)
8 |
9 |
10 |
11 | ## Общие требования
12 |
13 |
14 |
15 | - [1.1](#1.1) Главное! Используем [pixel-perfect](https://chrome.google.com/webstore/detail/perfectpixel-by-welldonec/dkaagdgjmgdmbnecmcefdhjekcoceebi?hl=ru), если заказчик предоставил макет.
16 |
17 |
18 |
19 | - [1.2](#1.2) Не подключать стили с удаленных источников — только с наших серверов.
20 |
21 |
22 |
23 | - [1.3](#1.3) CSS — опасная сила.
24 |
25 | Все стили, подключаемые к странице, являются глобальными, и, если этим злоупотреблять, то можно легко довести проект до состояния крайне болезненного внедрения любого нового элемента или изменения старого. Это чаще всего происходит, когда создаются "общие" классы, потом крепятся к разным элементам на странице (банальный пример — шапка, у которой внутри форма поиска, которая есть на всех страницах с одинаковыми классами) и в итоге, когда по дизайну на разных страницах появляются небольшие отличия в шапке, плодятся классы, переписывающие свойства. И так почти для всех элементов каждой страницы. В итоге, меняя крайнюю правую ссылку в сайдбаре на странице новостей, вы можете поломать верстку всего сайдбара на какой-нибудь другой странице, например, на странице личного кабинета.
26 |
27 | Для того чтобы такого не происходило, существуют разные методологии, например, `БЭМ` (прочитать про него обязательно хотя бы в общих чертах) или, например, [rscss](https://ricostacruz.com/rscss/index.html). Для начала можете изучить [небольшой подход](https://isobar-us.github.io/code-standards/), который используют ребята из `Isobar` — он описан в рамках их стандарта и состоит из 7 небольших абзацев.
28 |
29 | Для решения проблемы уникальности имён классов на программном уровне, мы используем [CSS Modules](https://github.com/css-modules/css-modules). Некоторые разработчики предпочитают [styled-components](https://styled-components.com/) или [tailwindcss](https://tailwindcss.com/).
30 |
31 |
32 |
33 |
34 | - [1.4](#1.4) Отступы делать пробелами, один уровень — 2 пробела.
35 |
36 |
37 |
38 | - [1.5](#1.5) Использовать одинарные кавычки.
39 |
40 |
41 |
42 | - [1.6](#1.6) Перед началом работы обязательно четко знать все приоритеты селекторов и все 4 вида возможных отношений.
43 |
44 | Отношения элементов между собой могут быть:
45 |
46 | - `div p` – элементы p, являющиеся потомками div
47 | - `div > p` – только непосредственные потомки
48 | - `div ~ p` – правые соседи: все p на том же уровне вложенности, которые идут после div
49 | - `div + p` – первый правый сосед: p на том же уровне вложенности, который идёт сразу после div (если есть)
50 |
51 | А про приоритеты можно почитать [здесь](https://habrahabr.ru/post/137588/) и во многих других местах.
52 |
53 |
54 |
55 | - [1.7](#1.7) Не использовать `@import` внутри файлов.
56 |
57 | Имеется в виду, что в конечном `css` файле, который получает клиент, не должно быть этих конструкций. Но если настроен `WebPack` и `css-loader`, который как раз этот случай обрабатывает, либо используются компилируемые аналоги, которые умеют вместо импортов подставлять непосредственное содержимое файлов, то импорты возможны, так как браузер все равно их не увидит и не получит никогда в реальной работе.
58 |
59 | Можно выделить пару причин, почему не стоит использовать `@import`:
60 |
61 | - Некоторые старые браузеры не поддерживают использование правила `@import`, и стили, которые мы подгружаем через это правило, будут потеряны
62 | - `@import` блокирует параллельную загрузку стилей, а это означает, что браузер будет ожидать завершения загрузки импортированного файла, прежде чем начнёт обрабатывать остальную часть содержимого.
63 | - Более подробно можно почитать [здесь](http://www.stevesouders.com/blog/2009/04/09/dont-use-import/).
64 |
65 |
66 |
67 | - [1.8](#1.8) Все правила должны быть разбиты на разные файлы по страницам и блокам, каждый файл должен быть не длиннее, чем 1000 строк.
68 |
69 |
70 |
71 | - [1.9](#1.9) Каждое CSS-правило должно быть на отдельной строке.
72 |
73 | Это очень поможет как минимум при просмотре diff-ов в системе контроля версий. Плюс это позволит избежать горизонтальной прокрутки.
74 |
75 |
76 |
77 | - [1.10](#1.10) Для всех интерактивных элементов (ссылки, кнопки, дропдауны, инпуты, селекты) дизайнер может прорисовать отдельные состояния и спрятать в ближайшем слое — всегда проверять для каждого элемента, есть ли отрисованное состояние.
78 |
79 |
80 |
81 | - [1.11](#1.11) Дизайнеры могут ошибаться — иногда надо делать запросы на изменение макета, если они нарисовали что-то переусложненное.
82 |
83 | Например, в макете может быть отцентрированная по вертикали относительно текста полоска:
84 |
85 | |  |
86 | | :-------------------------------------------------------------------------------------------------------------: |
87 | | _эта картинка просто пример, не факт, что тут как раз такая ошибка_ |
88 |
89 | Дизайнер может просто на глаз положить эту полоску на среднем уровне нижних букв текста, однако вы как верстальщики просто примените vertical-align: middle и увидите, что полоска выше/ниже уровня, который показал дизайн, и Pixel Perfect явно это подсвечивает. Чаще всего не надо хардкодить какой-нибудь неочевидный отступ, просто чтобы идеально соответствовать макету — лучше сказать дизайнеру, что автоматом полоска ставится на другое место и её лучше там и оставить. А дизайнеру подучить типографику.
90 |
91 |
92 |
93 | - [1.12](#1.12) Пытаться по максимуму делать сайт резиновым (ставьте ширину в процентах и выставляйте max-width, min-width) — прибегайте к фиксированной ширине элемента, только если по макету от этого никак не уйти.
94 |
95 | Если все-таки сайт должен быть с фиксированный шириной, обязательно проверяйте правую сторону каждой страницы на маленьких экранах. Очень частая ошибка новичков не все элементы делать с min-width, и при горизонтально прокрутке получается такая штука:
96 |
97 | 
98 |
99 |
100 |
101 | - [1.13](#1.13) При сборке проекта при отсутствии дизайна (на CSS-фреймворках, например) избегать "лепки".
102 |
103 | Если вы разрабатываете проект, у которого нет дизайна (при помощи CSS-фреймворков, например), то старайтесь избегать лепки.
104 |
105 | Правила те же, что и при написании программных модулей: старайтесь придать пространства между компонентами, ограничить их друг от друга визуально (осуществляется слабое зацепление), но вместе с этим, сами компоненты должны выглядеть самодостаточно, т.е. обладать всем необходимым, но без избыточности, функционалом, чтобы это можно было назвать полноценной компонентой (осуществляется сильная связанность).
106 |
107 | Хорошим детектором является тут БЭМ: старайтесь делать отступы между блоками минимум в два раза больше, чем внутри блока между элементами.
108 |
109 |
110 |
111 | - [1.14](#1.14) Все стили одного блока должны быть в одном месте и отсортированы по порядку их расположения на странице.
112 |
113 | То есть, если есть шапка, а внутри нее поисковая форма, то в .css файлах нельзя сначала определить стили шапки, потом кучу стилей тела страницы и потом стили поисковой формы шапки. Должны идти стили самой шапки и сразу под ней стили формы.
114 |
115 | При этом стили сайдбара не могут идти раньше стилей шапки, а стили футера идти раньше стилей сайдбара. Лучше вообще эти стили разнести по разным файлам.
116 |
117 |
118 |
119 | - [1.15](#1.15) Футер страницы должен быть всегда прижат к низу страницы, даже если на странице мало контента ([5 методов, как сделать это](http://dimox.name/press_footer_bottom_with_css/)).
120 |
121 |
122 |
123 | - [1.16](#1.16) Имена.
124 |
125 | Использовать `lower-case-hyphenated` (то есть не `mySuperAwesomeElement` и не `my_super_awesome_element`)
126 |
127 | Имена должны отражать смысл, а не описание стилей (`"loading"`, а не `"big-yellow-spinny-thing"`)
128 |
129 |
130 |
131 | ## Правила
132 |
133 |
134 |
135 | - [2.1](#2.1) Не использовать `!important`.
136 |
137 | В 99% случаях проблему можно решить, грамотно используя `БЭМ` или `CSS modules`. В сложных редких случаях лучше увеличивать приоритет селекторов (например, когда надо стили библиотеки переопределить).
138 |
139 |
140 |
141 | - [2.2](#2.2) Не использовать `position: absolute` для стилизации, где это можно заменить другими подходами.
142 |
143 |
144 |
145 | - [2.3](#2.3) Не двигать элемент при помощи `top`, `left`, `right` или `bottom` при `position: relative`, где это можно заменить другими подходами.
146 |
147 | Можно использовать сам `position: relative` (без свойств `top`, `left`, `right` или `bottom`) для `z-index` и для того, чтобы указать потомкам элемента ориентир.
148 |
149 |
150 |
151 | - [2.4](#2.4) Не использовать отрицательные margin.
152 |
153 | На самом деле, отрицательные `margin` — это валидные правила, они поддерживаются спецификацией `CSS`, и их даже используют такие гиганты, как Bootstrap (посмотрите стили для `.row`).
154 |
155 | Но это очень неочевидные правила, их тяжело обнаружить, и их почти всегда можно заменить более легкими и предсказуемыми свойствами.
156 |
157 |
158 |
159 | - [2.5](#2.5) Избегать фиксирования высоты.
160 |
161 | Почти всегда использование фиксированного в пикселях, процентах и других единицах `height` является признаком неправильного кода. Это делает очень неочевидным поведение элементов, которые следуют за зафиксированным по высоте, может произойти обрезание контента или его наложение на следующие элементы.
162 |
163 | Когда это все-таки может быть нужно:
164 |
165 | - У элемента надо ручками подстроиться под высоту потомков, которых "убрали" из общего потока. "Убрать" из потока можно через `position: absolute`, например. Это может быть слайдер, у которого потомки крутятся как раз через позиционирование, а не смещение `margin`-ом
166 |
167 | - По дизайну надо подстроить все элементы под определенную высоту, а контент, вылезающий за пределы, обрезать.
168 |
169 |
170 |
171 | - [2.6](#2.6) Избегать фиксированных выравниваний.
172 |
173 | Если блок должен быть отцентрирован (хоть по горизонтали, хоть по вертикали), то центрировать его динамически, а не фиксированным `margin-top`.
174 |
175 | Например:
176 |
177 | 
178 |
179 | Здесь картинку, текст и полоску надо центрировать через `vertical-align`, а не `top: 55px` у полоски.
180 |
181 | Часто будут попадаться случаи более сложного центрирования — почти для каждого есть свой метод, надо их отдельно изучать.
182 |
183 | [Статья про vertical-align](http://web-standards.ru/articles/vertical-align/)
184 |
185 | Что нужно сделать, чтобы центрировать по высоте _элемент1_ внутри _элемента2_:
186 |
187 | - Оба элемента должны быть любыми inline элементами
188 |
189 | - У _элемента2_ должен быть указан font-size или line-height. _Элемент2_ отцентрируется только в зависимости от font-size или line-height и не обратит внимания на height.
190 |
191 |
192 |
193 | - [2.7](#2.7) Прописывать дефолтный цвет фона, цвет шрифта, `font-size` и семейство шрифта у `html`.
194 |
195 | Далее размер шрифта будет ориентиром для всех элементов, у которых используется rem для единиц измерения кегля.
196 |
197 |
198 |
199 | - [2.8](#2.8) При тестировании обязательно посмотреть цвет `:visited` ссылки.
200 |
201 | Браузер по умолчанию такие ссылки фиолетовыми делает, что чаще всего недопустимо в дизайне.
202 |
203 |
204 |
205 | - [2.9](#2.9) Добавлять элементу `cursor: pointer`, если он кликабелен и по умолчанию этого не поддерживает.
206 |
207 |
208 |
209 | - [2.10](#2.10) Удалять все неиспользуемые правила и правила, которые никак не влияют на отображение (например, дублирующие свойства по умолчанию или нулевые `margin`, если они и так не выставлены) — они могут в дальнейшем при правках внести неочевидное поведение и из-за них тяжело разбираться в проекте.
210 |
211 |
212 |
213 | - [2.11](#2.11) Слова, целиком состоящие из верхнего регистра, предпочтительно делать через стиль `text-transform: uppercase`, а не реальным вводом текста заглавными буквами.
214 |
215 |
216 |
217 | - [2.12](#2.12) При установке элементу `outline: none` обязательно выставить стили для `:focus` этому элементу.
218 |
219 | `outline` очень полезен, когда юзер заполняет форму, используя клавишу `tab` для переключения между инпутами и кнопками. Если `outline` убрать, станет менее заметно (или незаметно вовсе для кнопок), какой элемент сейчас выбран.
220 |
221 |
222 |
223 | - [2.13](#2.13) Все использования `@media` должны идти сразу после основных правил элемента, для того чтобы можно было увидеть все правила и все возможные состояния элемента в одном экране без прокручивания.
224 |
225 |
226 |
227 | - [2.14](#2.14) Вендорные префиксы должны идти перед общим стилем.
228 |
229 | Стандартное правило всегда должно быть под специфичными правилами для каждого движка.
230 |
231 | Пример:
232 |
233 | ```css
234 | .thing {
235 | -webkit-transition: all 100ms;
236 | -moz-transition: all 100ms;
237 | -o-transition: all 100ms;
238 | transition: all 100ms;
239 | }
240 | ```
241 |
242 |
243 |
244 | ## Шрифты
245 |
246 |
247 |
248 | - [3.1](#3.1) Если клиент предоставил макеты с кастомными шрифтами, проверить, свободные ли они и, если нет, то запросить купленные файлы шрифтов.
249 |
250 |
251 |
252 | - [3.2](#3.2) Если не требуется поддержка старых браузеров, шрифты должны быть в форматах `.woff2`, `.woff`. Сначала подключать `.woff2` шрифты, затем — `.woff` (пример ниже).
253 |
254 |
255 |
256 | - [3.3](#3.3) Если в проекте должна быть поддержка нелатинских символов (например, русских), проверьте, что в файле шрифта эти символы есть.
257 |
258 |
259 |
260 | - [3.4](#3.4) Разные начертания одного и того же шрифта подключайте под одним именем, но для разных `font-weight` и `font-style`.
261 |
262 | ```css
263 | @font-face {
264 | font-family: "Lato";
265 | src: url("../fonts/lato-regular.woff2"), url("../fonts/lato-regular.woff");
266 | font-weight: 400;
267 | font-style: normal;
268 | }
269 | @font-face {
270 | font-family: "Lato";
271 | src: url("../fonts/lato-italic.woff2"), url("../fonts/lato-italic.woff");
272 | font-weight: 400;
273 | font-style: italic;
274 | }
275 | @font-face {
276 | font-family: "Lato";
277 | src: url("../fonts/lato-light.woff2"), url("../fonts/lato-light.woff");
278 | font-weight: 300;
279 | font-style: normal;
280 | }
281 | @font-face {
282 | font-family: "Lato";
283 | src: url("../fonts/lato-lightitalic.woff2"),
284 | url("../fonts/lato-lightitalic.woff");
285 | font-weight: 300;
286 | font-style: italic;
287 | }
288 | ```
289 |
290 |
291 |
292 | - [3.5](#3.5) Всегда использовать как минимум один запасной шрифт и одно запасное семейство.
293 |
294 | Их перечисляют через запятую в `font-family`, так что каждое использование `font-family` должно происходить по схеме:
295 |
296 | ```css
297 | block {
298 | font-family: Helvetica, Arial, sans-serif;
299 | }
300 | ```
301 |
302 | Здесь `Helvetica` — нестандартный подключаемый шрифт.
303 |
304 | `Arial` — стандартный шрифт, который используется почти на всех клиентах, он будет использоваться, если не удалось подключить `Helvetica`.
305 |
306 | `sans-serif` — это семейство всех шрифтов без засечек (каковыми являются и `Helvetica`, и `Arial`). Если даже `Arial-а` на компе нет, то поставится какой-то системный дефолтный шрифт без засечек. Выбор здесь надо делать из `"serif,"` `"sans-serif,"` или `"monospace"`. Для шрифтов без засечек использовать по умолчанию `Arial`, для шрифтов с засечками — `Georgia` (а не `Times New Roman`), а для моноширинных — `"Courier New"`
307 |
308 |
309 |
310 | - [3.6](#3.6) Названия шрифтов, содержащие пробелы, цифры или знаки пунктуации, кроме дефисов, заключать в кавычки.
311 |
312 | Пример:
313 |
314 | ```css
315 | block {
316 | font-family: 'Times New Roman', serif;
317 | }
318 | ```
319 |
320 |
321 |
322 | ## БЭМ
323 |
324 |
325 |
326 | - [4.1](#4.1) Именование БЭМ-сущностей должно следовать следующим ограничениям:
327 |
328 | Блок, элемент — всегда имя существительное (noun)
329 |
330 | Модификатор — должен удовлетворять свойствам [модификатора из английского языка](https://en.wikipedia.org/wiki/Grammatical_modifier). Всегда `adjective` или `adjectival phrase`.
331 |
332 | Таким образом, фразы на английском языке `"$BLOCK_NAME [is] $MODIFIER_NAME"`, `"$ELEMENT_NAME [is] $MODIFIER_NAME"` или `"$MODIFIER_NAME $BLOCK_NAME"`, `"$MODIFIER_NAME $ELEMENT_NAME"`, `"$ELEMENT_NAME WITH $MODIFIER_NAME $MODIFIER_KEY"` должны быть синтаксически корректными словосочетаниями.
333 |
334 | Примеры _корректных имён_:
335 |
336 | - `input_selected` — `selected input` — выделенный инпут или `input is selected` — инпут выделен
337 | - `header_size_large` — `header with large size` — заголовок с большим размером.
338 |
339 | Примеры _**НЕ**корректных имён_:
340 |
341 | - `form__`**_save_**`_small`, для элемента save (который, например, вешается на кнопку) — `small save` — маленький сохранить, `save small` — сохранить маленький. Правильно будет употребить noun вместо `verb` и переименовать элемент в **_`save-button;`_** `small save-button` — маленькая кнопка сохранения
342 |
343 | - `input_`**_focus_** — `input focus` — инпут сфокусировать или `input is focus` — инпут это фокус. Правильно будет употребить `adjective` вместо `noun/verb` и переименовать модификатор в `focused; input_`**_focused_** — `focused input` — сфокусированный инпут
344 |
345 | - `row_`**_error_** — `row error` — ошибка строки или `row is error` — строка это ошибка. Правильно будет употребить `adjectival phrase` вместо `noun` и переименовать модификатор в `with-error`. `row_`**_with_**`-error` — `row with error` — строка с ошибкой.
346 |
347 | Обоснование: мы сможем всегда однозначно и без лишних затрат энергии истолковать сущность элемента вёрстки и накладываемые на него свойства.
348 |
349 |
350 |
351 | - [4.2](#4.2) Верстаем всегда по БЭМу, архитектура верстки должна быть компонентной.
352 |
353 | Каждый блок должен лежать в своей папке.
354 |
355 | Папки блоков нельзя вкладывать друг в друга.
356 |
357 |
358 |
359 | - [4.3](#4.3) Каждый компонент — отдельный блок из методологии БЭМ.
360 |
361 |
362 |
363 | - [4.4](#4.4) Каждый компонент должен иметь только явные зависимости, быть самодостаточным.
364 |
365 | Все зависимости делать явно, импортируя в начале компонента и вставляя в нужное место верстки.
366 |
367 | Самодостаточность говорит о том, что каждый компонент должен внутри себя содержать все необходимое — всю верстку, все стили и все js-скрипты.
368 |
369 | Ничего лишнего в компоненте быть не должно:
370 |
371 | - Не должно быть определения других блоков внутри этого блока
372 | - Не должно быть стилей, которые бы влияли на другие блоки любым способом
373 | - Не должно быть глобальных стилей (например, на все теги `span`)
374 | - Компонент не должен влиять на `DOM` другого компонента (менять верстку крайне запрещено)
375 |
376 |
377 |
378 | - [4.5](#4.5) Кастомизировать компоненты только через модификаторы, никаких примесей.
379 |
380 | Почти в любом проекте возникает необходимость кастомизировать блоки. Например, есть вёрстка из 20 страниц. На 15 из этих страниц встречается хэдер, причём у 10 из них хэдер синего цвета, на трёх — серый, и на двух — прозрачный. Это значит, что компонент хэдер должен быть кастомизируемым, и осуществляются подобного рода кастомизации через добавление модификаторов к блоку, а не путём передачи отдельных классов со стилями.
381 |
382 | Предположим, что на фоне у промо страницы есть видео, и по дизайну нам нужно сделать прозрачный хэдер со светлым шрифтом (по умолчанию — тёмный).
383 |
384 | Плохо:
385 |
386 | ```pug
387 | .promo-page
388 | +header({ classname: 'promo-page__header' })
389 | ```
390 |
391 | Хорошо:
392 |
393 | ```pug
394 | .promo-page
395 | +header({ theme: 'transparent', font: 'light' })
396 | ```
397 |
398 | При правильном подходе, естественно, надо будет научиться принимать эти два параметра, добавлять самому модификаторы к нужным классам и в CSS компонента прописывать правила для этих модификаторов.
399 |
400 | Это правило внедрено после болезненного опыта поддержки проекта средней сложности, и вот какие шишки набиты с использованием примесей:
401 |
402 | - Нарушается инкапсуляции — использование внешних стилей внутри компоненты ведёт к проблемам в сопровождении в дальнейшем. Дело в том, что стили компоненты являются её составной частью и не должны влиять на то, что её окружает. Также справедливо обратное — внешние стили не должны влиять на компоненту. Иными словами, компонента должна быть самодостаточна. Прибегая к использованию внешних стилей, мы создаём зависимость между двумя стилями — внешним и внутренним. Каждому из стилей нужно знать, из чего состоит другой, чтобы глобальный стиль не поломал стиль компоненты. Это и есть нарушение инкапсуляции
403 |
404 | - Если компонента используется на 20 разных страницах, то после изменения одного свойства в самом компоненте придется пройти по всем 20 страницам вручную и проверить, что ничего не сломалось, потому что неизвестно, какие могут быть стили навешаны в местах использования через кастомные классы, и надо самому проверить все комбинации
405 |
406 | - Примесь обычно вешается только на верхний уровень компонента, но иногда надо кастомизировать что-нибудь внутреннее, тогда получается, надо уже две примеси передавать и принимать в компоненте, одна примесь — для свойств всего блока, вторая — для какого-то элемента, а когда понадобится еще другой элемент кастомизировать, придется добавить третью примесь :)
407 |
408 | - Не получится четко составить список всех возможных состояний компоненты, а при подходе с модификаторами мы явно видим все возможные параметры на входе, и когда их число будет зашкаливать, можем пнуть дизайнера, что он слишком расфантазировался и пора бы переходить к единому стайлгайду
409 |
410 |
411 |
412 | - [4.6](#4.6) Для позиционирования блока в родительском контейнере тоже не надо использовать миксы — решается данная проблема путем добавления специальных контейнеров.
413 |
414 | Допустим, есть родительский блок, в нем — дочерний блок, который нам и необходимо спозиционировать. Для позиционирования внутреннего блока создаем в родительском элемент-обертку и просто задаем свойства (_margin, padding, position_ etc) этому контейнеру. Таким образом, позиционирование блока у нас находится в файле родительского блока и никак не влияет на стили самого блока.
415 |
416 | Данный способ позволяет, не используя миксы, спозиционировать дочерний блок.
417 |
418 | Например, в хэдере у нас находится обычная голубая кнопка, но именно тут, в шапке, она должна иметь отступ с левой стороны, для этого мы добавим `div.header__button`:
419 |
420 | ```pug
421 | div.header
422 | div.header__button
423 | +button({ color:blue })
424 | ```
425 |
426 | А в стили хэдера просто добавим:
427 |
428 | ```css
429 | .header__button {
430 | margin-left: 3rem;
431 | }
432 | ```
433 |
434 |
435 |
436 | ## Возможные ошибки
437 |
438 | > В css есть несколько очень неочевидных правил, лучше изучить их на теории заранее, чем ломать голову часами, почему верстка едет
439 |
440 |
441 |
442 | - [5.1](#5.1) Верхний margin первого элемента смещает за собой всех родителей вниз.
443 |
444 | Допустим, желаемый вид должен быть таким:
445 |
446 | 
447 |
448 | Чтобы заголовок имел отступ от верхней границы, мы добавляем ему margin: 20px 0 0; однако получаем такое поведение:
449 |
450 | 
451 |
452 | Несмотря на то, что маржин был поставлен только заголовку, все его родители тоже съехали вниз:
453 |
454 | 
455 |
456 |
457 |
458 | - [5.2](#5.2) Родители игнорируют всех детей, у которых установлены `float: left` или `float: right`
459 |
460 |
461 |
462 | - [5.3](#5.3) `z-index` свойство работает только для элементов, у которых значение position задано как `absolute`, `fixed` или `relative`.
463 |
464 |
465 |
466 | - [5.4](#5.4) А еще на `z-index` может повлиять `opacity` Почитать про это можно [тут](https://habrahabr.ru/post/166435/).
467 |
468 |
469 |
470 | - [5.5](#5.5) `height` в процентах не работает, если высота родителя формируется от контента.
471 |
472 | На `learn.javascript.ru` даже [статья](https://learn.javascript.ru/height-percent) есть.
473 |
474 |
475 |
476 | - [5.6](#5.6) Все `:hover` эффекты проверять на мобильных устройствах внимательно в отдельном порядке, если проект поддерживает отображения на мобилах.
477 |
478 | В разных браузерах ховеры ведут себя по-разному и это надо согласовывать с дизайнерами отдельно — иногда, чтобы он заработал, надо, например, отдельный тап по элементу делать. Соответственно, чтобы сработал клик, надо тапнуть два раза, что тоже для некоторых элементов будет очень странно.
479 |
480 |
481 |
482 | - [5.7](#5.7) Псевдоэлементы (`::after/before`) [не работают](https://stackoverflow.com/questions/14585070/css-after-pseudo-element-not-showing-up-on-img/14586588#14586588) с `self-closing tags` (``, ``, etc.).
483 |
484 |
485 |
486 | - [5.8](#5.8) Не использовать простой :hover для отображения новых элементов, которые нелегко достигнуть мышкой.
487 |
488 | Очень часто встречаются неудачные случаи с выпадающим меню, которое реализовано через псевдо-класс `:hover`, мало того, что это меню практически неработоспособно на мобильном устройстве, оно еще и доставляет немало головной боли пользователям десктопов. Решением в данном случае будет использование JavaScript.
489 |
490 | 
491 |
492 |
493 |
494 | - [5.9](#5.9) В ряде браузеров (Chrome, Opera, Edge, Firefox 62-, Safari 10-) теги форм, такие как `button`, `fieldset` и `legend`, не могут стать flex-контейнерами.
495 |
496 | Возможное решение — использовать элемент-обертку внутри тега (например, `span class="button__text"` внутри кнопки), и уже для него указать свойство `display: flex`:
497 |
498 | ```html
499 |
502 | ```
503 |
504 | ```css
505 | .button__text {
506 | display: flex;
507 | ...;
508 | }
509 | ```
510 |
511 | Подробнее об этом и других багах, возникающих при работе с флексами, можно прочитать на [Flexbugs](https://github.com/philipwalton/flexbugs), перевод материала на русский [здесь](https://css-live.ru/articles/brauzernye-bagi-flexbox.html).
512 |
513 | Для решения проблем с флексами можно воспользоваться неплохим [postcss-плагином](https://github.com/luisrudge/postcss-flexbugs-fixes), который автоматически фиксит некоторые баги в написании стилей для флексов.
514 |
--------------------------------------------------------------------------------
/Environment/README.md:
--------------------------------------------------------------------------------
1 | # Окружение
2 |
3 | Помимо написания кода и реализации функционала, нам, программистам, необходимо думать и о других вещах. О качестве и читаемости написанного кода, о написании кода в едином стиле, о создании качественной git истории и о многом другом.
4 |
5 | К счастью для нас, есть множество инструментов, которые нам в этом помогают. Именно о таких инструментах пойдёт речь в этом разделе.
6 |
7 | 1. [Git hooks with husky](./husky.md)
8 | 2. [Lint-staged](./lint-staged.md)
9 | 3. [Conventional Commits](./conventional-commits.md)
10 | 4. [Branches & Pull Requests](./branches-and-requests.md)
--------------------------------------------------------------------------------
/Environment/branches-and-requests.md:
--------------------------------------------------------------------------------
1 | # Branches и Pull Requests
2 |
3 | Здесь можно найти небольшой свод правил и возможностей по именованию веток и ведению Pull Requests (или Merge Requests в GitLab).
4 |
5 | ## Branches
6 |
7 | Существует [множество](https://byurrer.ru/git-workflow) подходов к именованию и организации веток - GitFlow, GitHub flow, GitLab flow и др. Выберете вы один из этих или будете использовать свой, зависит от требований вашего проекта и от того, как вы договоритесь с командой.
8 |
9 | Вот простой вариант который можно использовать на проекте:
10 |
11 | - `main` (или `master`) - в этой ветке содержится самая стабильная версия вашего проекта, которая как правило используется для деплоя в production (хотя для этого может быть отдельная ветка `prod`).
12 | - `dev` - ветка разработки. В ней содержатся последние готовые фичи, добавленные в ваш проект. Ветка может быть развёрнута на стейдж для полной проверки функционала перед слиянием в `main` и деплоем в production.
13 | - Ветки с новым функционалом или любой другой задачей из инструмента по трекингу задач ответвляются от `dev` и именуются `issueNumber-short-task-description`.
14 |
15 | **Минимальная рекомендация** - если у вас на проекте есть трекинг задач (GitHub/GitLab issues, Jira и др), ветка должна именоваться в формате `label-issueNumber-short-task-description`, например: `feature-234-add-product-card`. Вы можете использовать лейблы из вашей системы трекинга задач. Если таковых не имеется, вот примеры для `label`: `feature, fix, docs, refactor, test, build, perf`. Если у вас на проекте нет трекинга задач, название ветки должно отражать суть ваших изменений. Название должно быть коротким и в тоже время понятным.
16 |
17 | ## Pull Requests
18 |
19 | Вы можете связать ваш Pull Request с одним или несколькими issues, которых он касается, используя синтаксис `#issueNumber` в описании Pull Request, например: `#234 #235`.
20 |
21 | Вы также можете сделать так, что бы issue автоматически закрылся после слияния ветки, добавив в описание Pull Request слово `closes` перед номером issue, например: `closes #234, closes #235`.
22 |
23 | Вы можете упомянуть какого-то человека в описании или комментариях Pull Request, используя синтаксис `@username`.
24 |
25 | Если ваш Pull Request содержит незаконченную задачу и не готов к слиянию, вы можете пометить его как `Draft` во время или после создания Pull Request. Интерфейс будет зависеть от того, где вы работаете, в GitHub или GitLab. Pull Request нельзя слить пока активна метка `Draft`.
--------------------------------------------------------------------------------
/Environment/conventional-commits.md:
--------------------------------------------------------------------------------
1 | # Соглашение о коммитах
2 |
3 | Мы пишем коммиты в соответствии с [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) ([RU](https://www.conventionalcommits.org/ru/v1.0.0/)). В этом топике будет гайд о том, как использовать `Conventional Commits` в вашем проекте.
4 |
5 | Помимо Conventional Commits в сообществе есть несколько устоявшихся правил, которых мы придерживаемся:
6 |
7 | - Не использовать прошедшее время. То есть вместо `added` будет `add`, вместо `updated` будет `update` и так далее.
8 | - Текст коммитов писать в `lower case`. Например: `feat: add transaction component`, `fix: translation`.
9 |
10 |
Содержание
12 |
13 | - [Зачем использовать соглашение о коммитах?](#зачем-использовать-соглашение-о-коммитах)
14 | - [Prerequisites](#prerequisites)
15 | - [Установка](#установка)
16 | - [Использование](#использование)
17 | - [Конфигурация](#конфигурация)
18 | - [[Опционально] Commitizen](#commitizen)
19 |
20 |