├── .gitignore ├── README.md ├── algorithm └── atm.md ├── arch ├── di.md ├── mvc.md └── mvc │ ├── mvc-model-types.png │ └── mvc-model-types.svg ├── cs └── strings.md ├── db ├── comments.md ├── databases.md ├── normalization.md ├── patterns-oop.md └── trees.md ├── forms.md ├── good-code.md ├── html ├── float-margins.md ├── float-margins │ └── margins-on-float.png ├── html.md ├── markup-for-ie.md ├── position-absolute.png ├── position-absolute.svg ├── position-block-example.png ├── position-block-example.svg ├── position-flex.png ├── position-flex.svg ├── position-float.png ├── position-float.svg ├── position-inline-block.png ├── position-inline-block.svg ├── position-inline-example.png ├── position-inline-example.svg ├── position-inline.png ├── position-inline.svg ├── position-relative.png ├── position-relative.svg ├── position-table.png ├── position-table.svg ├── positioning-block.png ├── positioning-block.svg ├── positioning.md └── shrink-to-fit.md ├── interview-tasks.md ├── js ├── ajax.md ├── js-spa.png ├── js-spa.svg ├── minesweeper-mvc.md ├── pass-values.md └── spa.md ├── network ├── http.md └── urls.md ├── php ├── autoload.md ├── collation.md ├── datetime.md ├── encapsulation.md ├── exceptions.md ├── interfaces.md ├── strings-utf8.md └── templates.md ├── security ├── files-upload.md ├── password-hashing.md ├── sql-injection.md ├── xsrf.md └── xss.md ├── soft ├── apache-install.md ├── cli.md ├── php-install.md ├── switch-multiple-php-versions.sh └── web-server.md ├── student-list.md └── util ├── README.md.template ├── cleanup-svgs.php ├── create-readme.php └── export-svg.php /.gitignore: -------------------------------------------------------------------------------- 1 | *.tmp 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Здесь содержатся черновики уроков и некоторые задания. Оглавление: 2 | 3 | ### Основное 4 | 5 | - [Алгоритм обработки данных форм](forms.md) 6 | - [Что такое хороший код](good-code.md) 7 | - [Задачи с собеседований](interview-tasks.md) 8 | - [Задача про список студентов](student-list.md) 9 | 10 | ### algorithm/ 11 | 12 | - [Разбор задачи про банкомат](algorithm/atm.md) 13 | 14 | ### arch/ 15 | 16 | - [Зачем нужно Dependency Injection (и что это?)](arch/di.md) 17 | - [Архитектура MVC](arch/mvc.md) 18 | 19 | ### cs/ 20 | 21 | - [Представление строк в памяти компьютера и кодировки](cs/strings.md) 22 | 23 | ### db/ 24 | 25 | - [Добавление комментариев в схему базы данных](db/comments.md) 26 | - [Базы данных и SQL](db/databases.md) 27 | - [Нормализация баз данных](db/normalization.md) 28 | - [Паттерны работы с базой данных](db/patterns-oop.md) 29 | - [Как хранить в БД древовидные структуры](db/trees.md) 30 | 31 | ### html/ 32 | 33 | - [Особенности свойства margin на элементах с float](html/float-margins.md) 34 | - [Путь HTML/CSS](html/html.md) 35 | - [Тестирование и отладка верстки под ИЕ](html/markup-for-ie.md) 36 | - [Способы позиционирования элементов в CSS](html/positioning.md) 37 | - [Алгоритм автоматического определения ширины shrink-to-fit в CSS](html/shrink-to-fit.md) 38 | 39 | ### js/ 40 | 41 | - [Работа с аякс-запросами](js/ajax.md) 42 | - [Изучаем MVC на примере игры «Сапер»](js/minesweeper-mvc.md) 43 | - [Как правильно подставлять значения в JS код](js/pass-values.md) 44 | - [Задачка на создание SPA приложения](js/spa.md) 45 | 46 | ### network/ 47 | 48 | - [Протокол HTTP (черновик)](network/http.md) 49 | - [Структура URL, абсолютные и относительные ссылки](network/urls.md) 50 | 51 | ### php/ 52 | 53 | - [Автозагрузка, неймспейсы и PSR-4](php/autoload.md) 54 | - [Сравнение и сортировка строк в PHP](php/collation.md) 55 | - [Работа с датой и временем в PHP](php/datetime.md) 56 | - [Инкапсуляция в ООП](php/encapsulation.md) 57 | - [Как использовать исключения в PHP](php/exceptions.md) 58 | - [Интерфейсы в ООП](php/interfaces.md) 59 | - [Функции работы с UTF-8 строками в PHP](php/strings-utf8.md) 60 | - [Шаблоны в PHP](php/templates.md) 61 | 62 | ### security/ 63 | 64 | - [Как безопасно загружать файлы пользователей на сервер](security/files-upload.md) 65 | - [Как безопасно хранить пароли](security/password-hashing.md) 66 | - [SQL-инъекция (внедрение SQL кода) и способы борьбы с ней](security/sql-injection.md) 67 | - [Уязвимость XSRF](security/xsrf.md) 68 | - [Уязвимость XSS в PHP-скриптах и как ее избежать](security/xss.md) 69 | 70 | ### soft/ 71 | 72 | - [Установка Апача с PHP](soft/apache-install.md) 73 | - [Как начать пользоваться командной строкой](soft/cli.md) 74 | - [Установка и настройка PHP](soft/php-install.md) 75 | - [Настраиваем веб-сервер для работы с PHP из браузера](soft/web-server.md) 76 | 77 | 78 | 79 | ### Дополнительно 80 | 81 | - [Как устроены компьютерные сети, что такое NAT](https://gist.github.com/codedokode/1af26d3a64748f05ba8b870b273edfc6) 82 | - [Как работают транзакции в MySQL, что такое MVCC](https://gist.github.com/codedokode/45f2961e7d68f7a2c501f4f893a45e17) 83 | - [Варианты архитектуры программ-серверов (много процессов, много потоков, асинхронный код)](https://gist.github.com/codedokode/ffd520440a970c07c1c6) 84 | - [Автоматизированное тестирование](https://gist.github.com/codedokode/a455bde7d0748c0a351a) 85 | - [Задачи, помогающие проверить и закрепить знание Яваскрипта на нужном для разработки сайтов уровне](https://gist.github.com/codedokode/ce30e7a036f18f416ae0) 86 | - [Как установить и настроить Sphinx, как подключиться к нему из php-кода](https://gist.github.com/codedokode/10539366) 87 | - [Задача на написание клона игры Арканоид для браузера на JS, с подробными комментариями](https://gist.github.com/codedokode/9933897). Эта задача научит использовать канвас, а также даст представление об устройстве простых игр. 88 | - [Задача написать файлообменник](https://gist.github.com/codedokode/9424217). Как всегда, с подробными комментариями, почти что урок по написанию файлообменников, по безопасной загрузке файлов, по получению информации об аудио- и видео-файлах и их конвертированию. 89 | - [Как автоматически отформатировать PHP код с помощью IDE или сайта](https://gist.github.com/codedokode/8759492) 90 | - [Задача сделать сайт для проведения тестов знаний Testhub](https://gist.github.com/codedokode/8733007). Эта задача не для совсем начинающих, а для тех, кто уже делал более простые задачи вроде студентов или файлообменника. Она позволит освоить какой-нибудь серьезный фреймворк (например, Symfony), ORM, делать сложные формы, использовать автоматические тесты. Она содержит подробные комментарии и по сложности близка к реальным задачам. 91 | - [Задача сделать калькулятор для вычисления выражений с приоритетом операторов и скобками](https://gist.github.com/codedokode/7005985). Эта задача с комментариями позволит узнать про лексический и синтаксический анализ, дерево выражения (AST) и как это можно использовать для вычисления математических выражений. 92 | - [Красивые URL](https://gist.github.com/codedokode/772a4ccc03e41d6b7cba) - как можно организовать адреса страниц (URL) на сайте, чтобы это выглядело логично и было удобно. 93 | 94 | Вопросы/советы/замечания — шлите на codedokode@gmail.com 95 | 96 | Если вы обнаружили какие-то ошибки или опечатки, вы можете написать о них на почту, либо сделать пулл-реквест с исправлением. Заранее спасибо! 97 | 98 | Эти статьи написаны с помощью разметки [markdown](https://ru.wikipedia.org/wiki/Markdown) (она позволяет оформлять текст, добавлять заголовки, ссылки, блоки с кодом, картинки). Если вы с ней не знакомы, но вам интересно, как это сделано, просто откройте статью и нажмите кнопку Raw, чтобы увидеть исходный текст с разметкой. 99 | 100 | Оглавление генерируется скриптом `/util/create-readme.php`. 101 | 102 | Есть автоматизированный скрипт, который умеет обходить все статьи, находит в них ссылки и проверяет, что они работают: https://github.com/codedokode/pasta-link-checker 103 | 104 | Еще я использую набор скриптов, которые ищут опечатки в статьях с помощью программы hunspell: https://github.com/codedokode/pasta-spellcheck 105 | -------------------------------------------------------------------------------- /arch/mvc/mvc-model-types.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codedokode/pasta/a5b2872386ad51ec29a4c779931292cc3d3502bf/arch/mvc/mvc-model-types.png -------------------------------------------------------------------------------- /db/comments.md: -------------------------------------------------------------------------------- 1 | # Добавление комментариев в схему базы данных 2 | 3 | Иногда полезно иметь возможность добавить комментарий к таблице или колонке таблицы в базе данных. Этот комментарий сообщит другим разработчикам, что именно хранится в этой колонке или таблице, а также предупредит о каких-то особенностях работы с этими данными. 4 | 5 | Стандарт SQL не предлагает способов сделать это, но отдельные системы баз данных поддерживают свои нестандартные команды для добавления комментариев. 6 | 7 | ## MySQL 8 | 9 | В MySQL можно указать комментарий к таблице или полю при создании с помощью слова `COMMENT`: 10 | 11 | ```sql 12 | CREATE TABLE example ( 13 | id INT NOT NULL COMMENT 'Это пример комментария к колонке таблицы' 14 | ) COMMENT 'Это пример комментария к таблице' 15 | ``` 16 | 17 | Позже комментарий можно изменить командой `ALTER TABLE`: 18 | 19 | ```sql 20 | ALTER TABLE example COMMENT 'Новый комментарий к таблице'; 21 | ALTER TABLE example 22 | MODIFY COLUMN id INT NOT NULL COMMENT 'Новый комментарий к полю' 23 | ``` 24 | 25 | Увидеть эти комментарии можно командой `SHOW CREATE TABLE example`, также они могут отображаться в GUI программах вроде phpMyAdmin. 26 | 27 | Мануал: 28 | 29 | - (англ.) https://dev.mysql.com/doc/refman/5.7/en/create-table.html 30 | - (англ.) https://dev.mysql.com/doc/refman/5.7/en/alter-table.html 31 | - (рус., устаревший) http://www.mysql.ru/docs/man/CREATE_TABLE.html 32 | 33 | ## Postgresql 34 | 35 | В Postgresql можно добавлять и изменять комментарии к любым объектам базы данных (таблицы, колонки, индексы) с помощью отдельной команды `COMMENT`: 36 | 37 | ```sql 38 | COMMENT ON TABLE example IS 'Пример комментария к таблице'; 39 | COMMENT ON COLUMN example.id IS 'Пример комментария к колонке таблицы'; 40 | ``` 41 | 42 | - (рус., хороший перевод) https://postgrespro.ru/docs/postgrespro/9.6/sql-comment.html 43 | - (англ.) https://www.postgresql.org/docs/current/static/sql-comment.html 44 | 45 | ## Oracle Database 46 | 47 | Oracle использует аналогичный Postgresql синтаксис. 48 | 49 | - (англ.) https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_4009.htm 50 | 51 | ## MSSQL 52 | 53 | В MSSQL проще всего добавить комментарий к колонке через GUI программу SQL Server Management Studio. С помощью SQL кода добавлять комментарии довольно неудобно: http://stackoverflow.com/questions/4586842/sql-comments-on-create-table-on-sql-server-2008 54 | 55 | -------------------------------------------------------------------------------- /db/normalization.md: -------------------------------------------------------------------------------- 1 | # Нормализация баз данных 2 | 3 | Принципы нормализации описывают, как надо правильно проектировать таблицы для хранения данных. Если им не следовать, то потом с БД будет неудобно работать (а разработчики будут вспоминать проектировщика нехорошими словами). К сожалению, не везде эти принципы описаны понятным языком, потому я попытался найти доступные статьи, а также добавил пояснения своими словами. 4 | 5 | Перед чтением этого урока полезно вспомнить, какие виды отношений между таблицами бывают в базе данных (один-к-одному, один-ко-многим, многие-ко-многим). 6 | 7 | Ссылки по теме: 8 | 9 | - https://habrahabr.ru/post/129195/ 10 | - https://habrahabr.ru/post/254773/ 11 | - http://club.shelek.ru/viewart.php?id=177 12 | - http://alexvolkov.ru/database-normalizatio.html 13 | - (сложновато, но зато официально) https://ru.wikipedia.org/wiki/%D0%9D%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%84%D0%BE%D1%80%D0%BC%D0%B0 14 | 15 | Теория описывает так называемые *нормальные формы*, пронумерованные от 1NF до 6NF (на практике хватает первых трех). Каждая форма содержит определенный список требований, которым должна соответствовать база данных (говорят "таблица находится во второй нормальной форме"). При этом требования для N-й нормальной формы включают в себя и требования к формам с меньшими номерами. То есть, чем выше номер, тем больше этот список. Обычно достаточно, чтобы БД находилась в третьей нормальной форме (3NF). 16 | 17 | Большинство требований направлено на борьбу с дублированием данных, чтобы информация (например, email или имя пользователя) хранилась только в одном экземпляре. 18 | 19 | Я попробую описать эти формы своими словами и привести примеры ошибок проектирования БД: 20 | 21 | ## 1NF 22 | 23 | Требования: 24 | 25 | - В первой нормальной форме все значения в ячейках (их в теории называют *атрибуты*) должны быть атомарными, то есть содержать ровно одно неделимое значение, а не список из нескольких значений. 26 | 27 | Требуется хранить в одной ячейке таблицы одно неделимое значение. Вот пример таблицы сотрудников компании `employees`, где это правило нарушается. В одной колонке хранится и имя сотрудника, и его должность: 28 | 29 | | id | employee | 30 | |-----|-----------------------| 31 | | 1 | Иванов И.И., директор | 32 | | 2 | Петров П.П., менеджер | 33 | | 3 | Сидоров С.С.,менеджер | 34 | 35 | Из-за этого нам нелегко, например, найти всех менеджеров, или выбрать только фамилии без должностей. Также, непросто написать запрос для изменения должности сотрудника, например, с "менеджер" на "старший менеджер". Для решения проблемы необходимо вынести должность в отдельную колонку. Также, возможно, имеет смысл разбить ФИО на 3 отдельных колонки, но это зависит от того, как они будут использоваться - всегда вместе или по отдельности. 36 | 37 | Вот другой пример нарушения 1NF. Допустим, у нас есть блог и к каждому посту можно добавить теги (темы, к которым относится пост). Разработчик не соблюдает принцип атомарности в таблице `posts` и хранит в одной ячейке все теги сразу: 38 | 39 | | id | title | tags | 40 | |------|---------------|------------------------| 41 | | 1 | Основы PHP | PHP, программирование | 42 | | 2 | Мой кот | кот, личное | 43 | | 3 | Циклы в PHP | PHP, циклы | 44 | 45 | Имеем такие недостатки: название тега не может содержать в себе запятую. Неудобно искать посты по тегу. Чтобы добавить или убрать тег, надо сначала выбрать полный список тегов, отредактировать его и сохранить обратно и это нелегко сделать одним запросом. Если мы захотим переименовать тег, то придется делать поиск и замену по всей таблице (и есть риск, что вместе с заменой тега "PHP" мы заменим и тег "уроки PHP"). Трудно вывести список тегов и число постов по каждому. Нельзя добавить тегу какие-то свойства (например, цвет или ссылку). 46 | 47 | Для исправления проблемы теги необходимо сделать отдельной сущностью. Для этого нужно сделать отдельную таблицу `tags` для них: 48 | 49 | | id | name | 50 | |------|--------| 51 | | 1 | PHP | 52 | | 2 | программирование | 53 | | 3 | кот | 54 | | 4 | личное | 55 | | 5 | циклы | 56 | 57 | И таблицу связи постов с тегами (многие-ко-многим) `posts_to_tags`, состоящую из 2 колонок tag_id и post_id. Первичным ключом в ней будет эта пара колонок (это заодно не позволит поставить посту 2 одинаковых тега, так как значения первичного ключа должны быть уникальны). 58 | 59 | Мы заменили одну таблицу на три, но зато теперь с ними стало проще работать. Попробуй написать SQL-запросы для добавления тега к посту, удаления, переименования и увидишь разницу. 60 | 61 | Вот еще пример нарушения 1NF. Это та же таблица постов, где теги хранятся "горизонтально", каждый в своей колонке: 62 | 63 | | id | title | tag1 | tag2 | tag3 | 64 | |------|---------------|-------|-------------------|----------| 65 | | 1 | Основы PHP | PHP | программирование | NULL | 66 | | 2 | Мой кот | кот | личное | NULL | 67 | | 3 | Циклы в PHP | PHP | циклы | NULL | 68 | 69 | Кроме очевидной проблемы, что невозможно добавить более 3 тегов, тут есть и другие сложности. Например, попробуй написать запрос на добавление тега "PHP" к посту, если мы не знаем, какие колонки свободны. 70 | 71 | # 2NF 72 | 73 | На всякий случай напомню, что *первичным ключом* называют колонку или несколько колонок, значения которых не пусты, не повторяются и таким образом являются уникальным идентификатором. Первичный ключ бывает *естественный* - когда он уже содержится в данных (например, номер телефона может быть первичным ключом в телефонном справочнике) или *суррогатным* - когда он добавлен искусственно (например, числовой id). 74 | 75 | Практически для любой таблицы стоит определять первичный ключ, иначе с ней будет неудобно работать. 76 | 77 | Требования 2NF: 78 | 79 | - БД должна соответствовать 1NF 80 | - все поля в таблице должны *полностью зависеть* от первичного ключа целиком, а не от его части 81 | 82 | Обычно это требование применяется только тогда, когда первичный ключ составной и содержит 2 или больше колонок. В этом случае, если какие-то значения в таблице зависят только от части ключа, то они могут повторяться, и их надо вынести в отдельную таблицу. Если первичный ключ - это одно поле, то таблица уже соответствует требованию. 83 | 84 | "Поле A полностью зависит от B" здесь значит, что, зная B, можно найти значение A в таблице. Ну например, в таблице ниже поле `built_year` зависит от пары (`street_id`, `house_number`), но не зависит от них по отдельности (только по номеру дому нельзя понять о каком доме идет речь и найти его год постройки). 85 | 86 | Попробую привести пример нарушения этого требования. Допустим, у нас есть таблица `buildings`, в которой хранится информация о зданиях в городе: число этажей, год постройки дома, название улицы: 87 | 88 | | street_id | street_name | street_type | house_number | floors | built_year | 89 | |----------:|-------------|-------------|-------------:|---------:|-----------:| 90 | | 1 | Центральная | ул. | 1 | 5 | 1960 | 91 | | 1 | Центральная | ул. | 2 | 8 | 1962 | 92 | | 1 | Центральная | ул. | 3 | 1 | 1932 | 93 | | 2 | Спортивный | просп. | 1 | 12 | 1975 | 94 | | 2 | Спортивный | просп. | 2 | 18 | 1982 | 95 | 96 | Видно, что она соответствует 1NF, так как даже название улицы разбито на 2 части (`ул.` и `Центральная`). Попробуем понять, что в этой таблице может быть первичным ключом. Как указать на отдельный дом? Идентификаторы улиц встречаются по несколько раз, номера домов тоже. Однако их сочетание (`street_id`, `house_number`) - уникально. Это естественный первичный ключ. 97 | 98 | Теперь попробуй, глядя на таблицу, понять, как здесь нарушено требование к 2NF. 99 | 100 | Чтобы помешать подглядывать, я вставлю тут умное определение второй нормальной формы, которое не требуется учить наизусть (и даже читать), но которое помешает увидеть правильный ответ ниже. 101 | 102 | > Переменная отношения находится *во второй нормальной форме* тогда и только тогда, когда она находится в первой нормальной форме и каждый неключевой атрибут *неприводимо* зависит от её потенциального ключа. 103 | > 104 | > *Неприводимость* означает, что в составе потенциального ключа отсутствует меньшее подмножество атрибутов, от которого можно также вывести данную функциональную зависимость. Для неприводимой функциональной зависимости часто используется эквивалентное понятие «полная функциональная зависимость» 105 | 106 | Даже если ты не понял ни слова из определения, догадаться, в чем проблема, нетрудно. Видно, что значения в колонках `street_name` и `street_type` повторяются, так как они "зависят" только от одной колонки `street_id` (и нам достаточно знать только id улицы, без номера дома, чтобы найти ее название). Это дублирование увеличивает объем таблицы, а при попытке обновить название улицы, нам придется искать все ячейки, где оно есть, и заменять, что создает риск, что где-то мы его забудем поменять. 107 | 108 | Эти 2 колонки надо вынести в отдельную таблицу-справочник улиц `streets`. Я заодно убрал префикс `street` из названий полей, так как он уже есть в имени таблицы: 109 | 110 | | id | name | type | 111 | |-------|---------------|--------| 112 | | 1 | Центральная | ул. | 113 | | 2 | Спортивный | просп. | 114 | 115 | ## 3NF 116 | 117 | Требования: 118 | 119 | - должны выполняться требования 1NF и 2NF 120 | - значения полей должны зависеть только от первичного ключа, а не от других полей 121 | 122 | "Поле A зависит от B" значит, что одно поле (B) может служить идентификатором для другого (A). Ну к примеру, между фамилией человека (A) и номером паспорта (B) есть такая связь, так как (имея базу данных), по номеру паспорта можно определить фамилию (а обратное - неверно). Значит, фамилия человека "зависит" от его номера паспорта. В хорошо спроектированной таблице значения полей должны зависеть только от первичного ключа, но не от других полей. 123 | 124 | Вот пример таблицы `stations` со списком станций метро, нарушающей 3NF. Она содержит идентификатор станции (`id`), название станции (`name`), идентификатор ветки метро (`line_id`), название ветки (`line_name`). Попробуй догадаться, что здесь не так: 125 | 126 | | id | name | line_id | line_name | 127 | |-------|-------------------|-----------|--------------------| 128 | | 1 | Чистые пруды | 1 | Сокольническая | 129 | | 2 | Лубянка | 1 | Сокольническая | 130 | | 3 | Спортивная | 1 | Сокольническая | 131 | | 4 | Таганская | 2 | Кольцевая | 132 | | 5 | Курская | 2 | Кольцевая | 133 | 134 | Чтобы не подглядывать, вот текст, который не обязательно читать: 135 | 136 | > Запоминающееся и, по традиции, наглядное резюме определения 3NF Кодда было дано Биллом Кентом: каждый неключевой атрибут «должен предоставлять информацию о ключе, полном ключе и ни о чём, кроме ключа». 137 | > 138 | > Условие зависимости от «полного ключа» неключевых атрибутов обеспечивает то, что отношение находится во второй нормальной форме; а условие зависимости их от «ничего, кроме ключа» — то, что они находятся в третьей нормальной форме. 139 | 140 | Как и в прошлый раз, догадаться нетрудно, просто взглянув на таблицу: видно, что названия веток повторяются, так как "зависят" от `line_id`. Но 3NF требует чтобы поля зависели только от первичного ключа. Это значит, что поле `line_name` нужно вынести из этой таблицы в отдельную таблицу веток `lines`: 141 | 142 | | id | name | 143 | |------|-----------------| 144 | | 1 | Сокольническая | 145 | | 2 | Кольцевая | 146 | 147 | ## Другие нормальные формы 148 | 149 | Еще есть более строгие BCNF, 4NF, 5NF, 6NF. Про них можно почитать в статьях по ссылкам выше, но в общем их суть сводится к тому, чтобы при наличии в таблице отношений и зависимостей между колонками выносить их отдельно. 150 | 151 | ## Что будет, если не соблюдать требования нормализации 152 | 153 | - будет неудобно писать некоторые запросы к таблицам 154 | - данные будут дублироваться, что может привести к тому, что в одном месте будет одно значение, а в другом - другое и непонятно, какое из них правильное 155 | 156 | Конечно, пока в базе несколько таблиц, это не так заметно, но в больших системах с десятками и сотнями таблиц последствия нарушения требований могут быть тяжелыми. 157 | 158 | -------------------------------------------------------------------------------- /html/float-margins.md: -------------------------------------------------------------------------------- 1 | # Особенности свойства margin на элементах с float 2 | 3 | На плавающих элементах (с `float: left/right`) можно задавать маргины с 4 сторон, в том числе отрицательные. Некоторые маргины сдвигают сам плавающий элемент, а некоторые - отталкивают или втягивают окружающий его текст и инлайновые элементы. На картинке я попытался это отобразить. 4 | 5 | Для элементов `float: left`: левый маргин сдвигает флоат вправо-влево, правый — влияет на окружающий текст и элементы. 6 | 7 | Для элементов с `float: right`: левый маргин сдвигает окружающие элементы, а правый — сам плавающий элеимент. 8 | 9 | Верхний маргин всегда сдвигает сам флоат, а нижний - окружающие элементы. 10 | 11 | ![Влияние маргинов на положение флоатов и окружающий их текст](./float-margins/margins-on-float.png) 12 | -------------------------------------------------------------------------------- /html/float-margins/margins-on-float.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codedokode/pasta/a5b2872386ad51ec29a4c779931292cc3d3502bf/html/float-margins/margins-on-float.png -------------------------------------------------------------------------------- /html/position-absolute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codedokode/pasta/a5b2872386ad51ec29a4c779931292cc3d3502bf/html/position-absolute.png -------------------------------------------------------------------------------- /html/position-absolute.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 69 | 78 | Абсолютное позиционирование 92 | 93 | -------------------------------------------------------------------------------- /html/position-block-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codedokode/pasta/a5b2872386ad51ec29a4c779931292cc3d3502bf/html/position-block-example.png -------------------------------------------------------------------------------- /html/position-flex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codedokode/pasta/a5b2872386ad51ec29a4c779931292cc3d3502bf/html/position-flex.png -------------------------------------------------------------------------------- /html/position-flex.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 45 | 49 | 53 | 57 | 61 | 65 | 66 | 68 | 69 | 71 | image/svg+xml 72 | 74 | 75 | 76 | 77 | 78 | 83 | 92 | 101 | 110 | 119 | 128 | 137 | 142 | 147 | 152 | 157 | 162 | 167 | 172 | 177 | Flexbox 191 | 192 | -------------------------------------------------------------------------------- /html/position-float.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codedokode/pasta/a5b2872386ad51ec29a4c779931292cc3d3502bf/html/position-float.png -------------------------------------------------------------------------------- /html/position-float.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 23 | 25 | 46 | 50 | 54 | 55 | 57 | 58 | 60 | image/svg+xml 61 | 63 | 64 | 65 | 66 | 67 | 72 | 81 | 90 | 96 | Был холодный ясный апрельский день, и часы пробили тринадцать. Уткнув подбородок в грудь, чтобы спастись от злого ветра, Уинстон Смит торопливо шмыгнул за... стеклянную дверь жилого дома "Победа", но все-таки впустил за собой вихрь зернистой пыли. Плавающие (float) блоки 122 | 123 | -------------------------------------------------------------------------------- /html/position-inline-block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codedokode/pasta/a5b2872386ad51ec29a4c779931292cc3d3502bf/html/position-inline-block.png -------------------------------------------------------------------------------- /html/position-inline-block.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 45 | 49 | 53 | 54 | 56 | 57 | 59 | image/svg+xml 60 | 62 | 63 | 64 | 65 | 66 | 71 | 80 | 89 | 98 | 107 | 116 | 125 | 130 | 135 | Инлайн-блоки 149 | 150 | -------------------------------------------------------------------------------- /html/position-inline-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codedokode/pasta/a5b2872386ad51ec29a4c779931292cc3d3502bf/html/position-inline-example.png -------------------------------------------------------------------------------- /html/position-inline-example.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 46 | 50 | 54 | 55 | 57 | 58 | 60 | image/svg+xml 61 | 63 | 64 | 65 | 66 | 67 | 72 | 74 | 81 | 87 | 88 | 90 | 97 | 103 | 104 | Был холодный ясный апрельский день, и часы пробили тринадцать. Уткнув подбородок в грудь, чтобы спастись от злого ветра, Уинстон Смит торопливо шмыгнул за стеклянную дверь жилого дома background: #fcf4aa; border: 1px solid #c2b100; 136 | 137 | 138 | -------------------------------------------------------------------------------- /html/position-inline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codedokode/pasta/a5b2872386ad51ec29a4c779931292cc3d3502bf/html/position-inline.png -------------------------------------------------------------------------------- /html/position-inline.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 63 | 70 | 76 | 77 | 80 | 87 | 93 | 94 | Был холодный ясный апрельский день, и часы пробили тринадцать. Уткнув подбородок в грудь, чтобы спастись от злого ветра, Уинстон Смит торопливо шмыгнул за стеклянную дверь жилого дома "Победа", но все-таки впустил за собой вихрь зернистой пыли. Инлайновое позиционирование 121 | 122 | -------------------------------------------------------------------------------- /html/position-relative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codedokode/pasta/a5b2872386ad51ec29a4c779931292cc3d3502bf/html/position-relative.png -------------------------------------------------------------------------------- /html/position-relative.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 45 | 49 | 53 | 57 | 58 | 60 | 61 | 63 | image/svg+xml 64 | 66 | 67 | 68 | 69 | 70 | 75 | 84 | 93 | 102 | 111 | Относительное позиционирование 125 | 126 | -------------------------------------------------------------------------------- /html/position-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codedokode/pasta/a5b2872386ad51ec29a4c779931292cc3d3502bf/html/position-table.png -------------------------------------------------------------------------------- /html/position-table.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 45 | 49 | 53 | 57 | 61 | 65 | 69 | 73 | 77 | 81 | 85 | 86 | 88 | 89 | 91 | image/svg+xml 92 | 94 | 95 | 96 | 97 | 98 | 103 | 112 | 121 | 130 | 139 | 148 | 157 | Позиционирование как таблица 171 | 172 | -------------------------------------------------------------------------------- /html/positioning-block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codedokode/pasta/a5b2872386ad51ec29a4c779931292cc3d3502bf/html/positioning-block.png -------------------------------------------------------------------------------- /html/positioning-block.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 49 | 54 | 59 | 63 | 67 | 68 | 70 | 71 | 73 | image/svg+xml 74 | 76 | 77 | 78 | 79 | 80 | 85 | 94 | 103 | 112 | Блочное позиционирование 130 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /html/positioning.md: -------------------------------------------------------------------------------- 1 | # Способы позиционирования элементов в CSS 2 | 3 | В CSS есть разные способы *позиционировать* или располагать элементы относительно друг друга. Можно указать, что элементы должны выстраиваться горизонтально, или вертикально, друг над другом, или еще как-то. Ниже мы разберем все доступные варианты. 4 | 5 | Способ позиционирования элементов задается с помощью CSS-свойств `display` (по умолчанию имеет значение `block` или `inline` в зависимости от того, блочный это элемент или строчный), `float` (имеет значение `none`) и `position` (имеет по умолчанию значение `static`). 6 | 7 | ## Боксовая модель 8 | 9 | Бокс - это воображаемый прямоугольник на странице, который соответствует HTML-элементу (вроде `h1` или `p`). Боксовая модель описывает, как определяются размеры этого прямоугольника и его частей, что такое border, padding и margin. 10 | 11 | Прежде чем браться за позиционирование, необходимо выучить свойства `width`, `min-width`, `max-width`, `height`, `min-height`, `max-height`, `padding`, `background`, `border`, `margin`. Прочитать про них можно здесь: 12 | 13 | - http://softwaremaniacs.org/blog/2005/07/07/css-boxes/ (то, что написано про IE6, уже не актуально и можно не читать) 14 | - http://htmlbook.ru/samlayout/blochnaya-verstka/blochnaya-model 15 | - http://xiper.net/learn/css/box-model/what-is-the-box-model 16 | - https://developer.mozilla.org/ru/docs/Web/CSS/box_model 17 | - https://developer.mozilla.org/ru/docs/Web/CSS/box-sizing 18 | 19 | Также, необходимо прочитать про единицы измерения в CSS (в первую очередь - `px` и `%`): 20 | 21 | - http://htmlbook.ru/content/edinitsy-izmereniya 22 | 23 | Стоит помнить, что в некоторых случаях указание размера в процентах не работает. Например, для свойства `height` задавать значение в процентах можно только если для всех элементов, в которые он вложен (предков), задано значение `height`. 24 | 25 | ### Значения по умолчанию 26 | 27 | Если высота элемента не задана явно (или указано `height: auto`), то она определяется содержимым элемента. Если ширина не указана явно, то способ ее определения зависит от способа позиционирования. Свойства `margin` и `padding` имеют значение `0` по умолчанию, однако для некоторых элементов в браузере заданы ненулевые значения по умолчанию. Например, заголовки `

` и абазцы `

` имеют ненулевые `margin-top` и `margin-bottom`, чтобы между ними были отступы. 28 | 29 | ### Замещаемые элементы 30 | 31 | *Замещаемые* (replaced) элементы - это элементы, которые имеют внутренние размеры, например, картинки (``), кнопки (`