[{"data":1,"prerenderedAt":6410},["ShallowReactive",2],{"course:aidt-mag-frontend":3,"course:aidt-mag-frontend:topics":98,"course:aidt-mag-frontend:project":68},{"id":4,"title":5,"body":6,"course_slug":66,"description":67,"env_label":68,"env_url":68,"extension":69,"group":70,"is_course_project":71,"is_index":72,"level":73,"meta":74,"navigation":72,"path":94,"section":68,"seo":95,"stem":96,"topic_number":68,"topic_slug":68,"__hash__":97},"courses\u002Fcourses\u002Faidt-mag-frontend\u002Findex.md","Разработка пользовательских веб-интерфейсов",{"type":7,"value":8,"toc":62},"minimark",[9,19,26,33,36,55],[10,11,12,13,18],"p",{},"Требования к содержанию и оформлению материалов — в ",[14,15,17],"a",{"href":16},".\u002Fshared\u002FSTYLEGUIDE","shared\u002FSTYLEGUIDE.md",".",[10,20,21,22,18],{},"Содержание курса — в ",[14,23,25],{"href":24},".\u002Ftopics","topics.md",[10,27,28,29,18],{},"Порядок сдачи практических занятий и работа с git — в ",[14,30,32],{"href":31},".\u002Fshared\u002Fsubmission","shared\u002Fsubmission.md",[10,34,35],{},"Издательские метаданные:",[37,38,39,48],"ul",{},[40,41,42,43,47],"li",{},"учебного пособия (по теории) — в ",[14,44,46],{"href":45},".\u002Fpublishing\u002Ftextbook.yaml","publishing\u002Ftextbook.yaml",";",[40,49,50,51,18],{},"практикума (по заданиям) — в ",[14,52,54],{"href":53},".\u002Fpublishing\u002Fpracticum.yaml","publishing\u002Fpracticum.yaml",[10,56,57,58,18],{},"Общие части практикума (пояснительная записка и правила выполнения работ) — в ",[14,59,61],{"href":60},".\u002Fpracticum\u002F","practicum\u002F",{"title":63,"searchDepth":64,"depth":64,"links":65},"",2,[],"aidt-mag-frontend","Требования к содержанию и оформлению материалов — в shared\u002FSTYLEGUIDE.md.",null,"md","magistracy",false,true,"магистратура",{"topics_count":75,"has_lr":71,"has_pz":72,"has_course_project":71,"final_assessment":76,"tech_focus":77,"kind":78,"authors":79,"publication":86},10,"дифф. зачёт","TypeScript + Vite, без фреймворков","Учебное пособие",[80],{"last_name":81,"first_name":82,"patronymic":83,"role":84,"affiliation":85,"email":68},"Рындин","Никита","Александрович","автор","ВГТУ",{"city":87,"year":88,"founder":89,"publisher":90,"udk":63,"bbk":63,"shelf_mark":63,"isbn":63,"approval_body":93},"Воронеж",2026,"Министерство науки и высшего образования Российской Федерации",{"short":85,"full":91,"address":92},"Федеральное государственное бюджетное образовательное учреждение высшего образования «Воронежский государственный технический университет»\n","394026, Воронеж, Московский проспект, 14","Издается по решению редакционно-издательского совета\nВоронежского государственного технического университета\n","\u002Fcourses\u002Faidt-mag-frontend",{"title":5,"description":67},"courses\u002Faidt-mag-frontend\u002Findex","iMYEd7hNEHxF61y1SzYGvxfRDscqJIg-IxlFsYdmxUw",[99,2560],{"id":100,"title":101,"body":102,"course_slug":66,"description":110,"env_label":68,"env_url":68,"extension":69,"group":68,"is_course_project":71,"is_index":71,"level":68,"meta":2553,"navigation":72,"path":2554,"section":2555,"seo":2556,"stem":2557,"topic_number":490,"topic_slug":2558,"__hash__":2559},"courses\u002Fcourses\u002Faidt-mag-frontend\u002Ftopic-01-content.md","Веб и HTML: основы",{"type":7,"value":103,"toc":2511},[104,108,111,116,121,133,157,160,164,206,217,221,228,237,260,280,283,287,290,341,363,373,387,390,399,402,411,414,423,426,430,433,436,439,454,458,462,469,480,519,522,531,543,554,558,569,578,581,602,651,655,689,767,778,782,793,797,800,900,903,912,915,922,926,929,1082,1089,1102,1109,1118,1132,1137,1163,1171,1176,1233,1239,1257,1261,1264,1267,1311,1314,1346,1350,1354,1388,1391,1423,1448,1451,1488,1491,1826,1843,1846,1923,1926,2071,2075,2084,2289,2302,2306,2310,2315,2347,2354,2361,2365,2375,2378,2386,2390,2399,2414,2453,2456,2460,2463,2479,2482,2486,2507],[105,106,101],"h1",{"id":107},"веб-и-html-основы",[10,109,110],{},"Курс начинается с языка разметки HTML — фундамента, на котором держится клиентская часть любого веб-приложения. Прежде чем перейти к самому языку, обратимся к контексту: что такое веб, как устроена доставка документа от сервера к браузеру, какие организации стандартизируют веб-технологии. Эти сведения часто остаются за рамками курсов фронтенд-разработки, но без них непонятно, почему HTML устроен именно так и почему современные практики выглядят как выглядят.",[112,113,115],"h2",{"id":114},"базовые-понятия-веба","Базовые понятия веба",[117,118,120],"h3",{"id":119},"гипертекст-и-гипермедиа","Гипертекст и гипермедиа",[10,122,123,124,128,129,132],{},"Гипертекст (англ. ",[125,126,127],"em",{},"hypertext",") — это методика связи электронных текстовых документов с помощью интерактивных элементов — гиперссылок (англ. ",[125,130,131],{},"hyperlink","), позволяющая читателю самостоятельно выбирать последовательность просмотра. По размещённым в тексте ссылкам читатель переходит к другим документам или к иным фрагментам того же документа; порядок такого перемещения он определяет сам.",[10,134,135,136,139,140,152,153,156],{},"Идея нелинейного чтения возникла ещё в докомпьютерную эпоху, но воплощение в современном виде стало возможным с развитием вычислительной техники. Термин ",[125,137,138],{},"гипертекст"," был введён математиком и философом Тедом Нельсоном в 1965 году в докладе «Complex Information Processing: A File Structure for the Complex, the Changing and the Indeterminate» ",[141,142,145],"sup",{"className":143},[144],"cite",[14,146,148],{"href":147},"#ref-1",[149,150,151],"span",{},"1",". Несколько позже тем же автором был предложен расширенный термин гипермедиа (англ. ",[125,154,155],{},"hypermedia",") — концепция распространялась не только на текст, но и на другие виды электронного контента, — однако в обиходе закрепился именно первоначальный вариант.",[10,158,159],{},"Идеи Нельсона при его непосредственном участии воплотились в проекте гипертекстовой системы Xanadu, которая существует по сей день, но сколь-либо значимого распространения не получила. Несмотря на это, сама концепция гипертекста оказалась востребованной — особенно в научной среде, где она облегчала поиск и консолидацию больших объёмов информации.",[117,161,163],{"id":162},"всемирная-паутина-от-идеи-до-современного-состояния","Всемирная паутина: от идеи до современного состояния",[10,165,166,167,170,171,174,175,184,185,188,189,192,193,196,197,201,202,205],{},"В 1989 году в Европейской организации по ядерным исследованиям (фр. ",[125,168,169],{},"Organisation européenne pour la recherche nucléaire","; аббревиатура CERN сохранилась от исторического названия ",[125,172,173],{},"Conseil Européen pour la Recherche Nucléaire"," — временного совета 1952–1954 годов) исследователи Тим Бернерс-Ли и Роберт Кайо работали над информационной системой для структурирования служебной информации с использованием гипертекста ",[141,176,178],{"className":177},[144],[14,179,181],{"href":180},"#ref-2",[149,182,183],{},"2",". Результатом стал язык разметки документов ",[125,186,187],{},"HyperText Markup Language"," (HTML) и протокол передачи данных ",[125,190,191],{},"HyperText Transfer Protocol"," (HTTP). Параллельно Бернерс-Ли предложил концепцию Всемирной паутины (англ. ",[125,194,195],{},"World Wide Web",", WWW) — распределённой системы доступа к семантически связанным документам, расположенным на разных компьютерах единой сети, — а также написал первый в мире HTTP-сервер ",[198,199,200],"code",{},"httpd"," и программу-клиент, веб-браузер (англ. ",[125,203,204],{},"web browser",") WorldWideWeb (позднее переименованный в Nexus, чтобы избежать путаницы с самой паутиной).",[10,207,208,209,212,213,216],{},"К 1992 году благодаря распространению вычислительной техники и стандартизации межсетевого обмена набирала обороты тенденция укрупнения университетских и исследовательских сетей в единую глобальную сеть. Её прообразом была ARPANET (1969), созданная по заказу Министерства обороны США; опорной магистралью, объединившей региональные сети в гражданский Internet, стала NSFNet (1985) — сеть Национального научного фонда США (англ. ",[125,210,211],{},"National Science Foundation",", NSF). Концепция WWW была удачно имплементирована как сервис в развивающейся глобальной сети, а базовая механика — ",[125,214,215],{},"«пользователь вводит в браузере адрес HTML-документа (URL) → используя протокол HTTP, браузер отправляет запрос по этому URL на веб-сервер → веб-сервер возвращает HTML-документ»"," — практически без изменений используется по сей день.",[117,218,220],{"id":219},"url-и-http-как-основа-доступа-к-ресурсам","URL и HTTP как основа доступа к ресурсам",[10,222,223,224,227],{},"Бернерс-Ли также является автором ",[125,225,226],{},"Uniform Resource Locator"," (URL) — единообразного указателя местонахождения ресурса. URL представляет собой последовательность символов, определяющую протокол передачи данных, доменное имя и путь к конкретному ресурсу:",[229,230,235],"pre",{"className":231,"code":233,"language":234},[232],"language-text","https:\u002F\u002Fexample.org\u002Farticles\u002Fintro.html?lang=ru#section-2\n","text",[198,236,233],{"__ignoreMap":63},[10,238,239,240,243,244,247,248,251,252,255,256,259],{},"В этом адресе различимы пять частей: схема (",[198,241,242],{},"https","), хост (",[198,245,246],{},"example.org","), путь (",[198,249,250],{},"\u002Farticles\u002Fintro.html","), параметры запроса (",[198,253,254],{},"?lang=ru",") и фрагмент (",[198,257,258],{},"#section-2","). Параметры запроса позволяют передавать дополнительные данные между клиентом и сервером, фрагмент адресует часть документа на стороне клиента и серверу не отправляется.",[10,261,262,263,266,267,266,270,266,273,266,276,279],{},"HTTP — это прикладной протокол по схеме «запрос — ответ». Клиент (браузер) отправляет запрос, описывающий желаемое действие методом (",[198,264,265],{},"GET",", ",[198,268,269],{},"POST",[198,271,272],{},"PUT",[198,274,275],{},"PATCH",[198,277,278],{},"DELETE",") и адресом, а сервер возвращает ответ со статус-кодом и телом сообщения. Подробное рассмотрение протокола, методов, статус-кодов и заголовков мы отложим до темы 8, посвящённой API-клиенту; пока ограничимся пониманием, что HTTP — основной транспорт, по которому браузер получает HTML-документы, изображения, стили и скрипты.",[10,281,282],{},"В разговорной практике термины «HTTP-сервер» и «веб-сервер» часто используются как синонимы и обозначают программный продукт, реализующий работу с протоколом HTTP (nginx, Apache httpd, Caddy). При необходимости уточняют контекст: говорят о веб-сервере как о хосте (физической или виртуальной машине) с установленным на нём HTTP-сервером и обслуживаемым контентом, либо как о самом ПО.",[117,284,286],{"id":285},"архитектура-браузера-движок-рендеринг-javascript-интерпретатор","Архитектура браузера: движок, рендеринг, JavaScript-интерпретатор",[10,288,289],{},"Веб-браузер — это клиентское приложение, которое получает доступ к веб-страницам и отображает их пользователю. Современные браузеры являются очень сложными программными продуктами; их архитектура может различаться в деталях, но как правило включает следующие компоненты:",[37,291,292,299,306,313,320,327,334],{},[40,293,294,295,298],{},"пользовательский интерфейс (англ. ",[125,296,297],{},"user interface",", UI) — адресная строка, меню навигации, меню закладок и т. д.;",[40,300,301,302,305],{},"движок браузера (англ. ",[125,303,304],{},"browser engine",") — согласует действия между пользовательским интерфейсом и движком рендеринга;",[40,307,308,309,312],{},"движок рендеринга (англ. ",[125,310,311],{},"rendering engine",") — отвечает за отображение контента: разбирает (парсит) HTML и CSS и отображает результат на экране;",[40,314,315,316,319],{},"модуль сетевого взаимодействия (англ. ",[125,317,318],{},"networking module",") — обслуживает сетевые вызовы (например, HTTP-запросы);",[40,321,322,323,326],{},"бэкенд пользовательского интерфейса (англ. ",[125,324,325],{},"UI backend",") — отрисовывает базовые виджеты (выпадающие списки, поля ввода, флажки), абстрагируя различия операционных систем;",[40,328,329,330,333],{},"интерпретатор JavaScript, JavaScript-движок (англ. ",[125,331,332],{},"JavaScript engine",") — парсит и выполняет код на JavaScript;",[40,335,336,337,340],{},"модуль хранения данных (англ. ",[125,338,339],{},"Data storage module",") — отвечает за локальное хранение файлов cookie, данных Web Storage, IndexedDB и т. п.",[10,342,343,344,353,354,18],{},"Изучение устройства браузеров не является целью курса, но для лучшего понимания процессов веб-разработки полезно ознакомиться со статьями Tali Garsiel ",[141,345,347],{"className":346},[144],[14,348,350],{"href":349},"#ref-3",[149,351,352],{},"3"," и Mariko Kosaka ",[141,355,357],{"className":356},[144],[14,358,360],{"href":359},"#ref-4",[149,361,362],{},"4",[10,364,365,366,372],{},"На момент подготовки пособия наиболее распространённые браузеры (по данным независимой службы анализа веб-трафика ",[14,367,371],{"href":368,"rel":369},"https:\u002F\u002Fgs.statcounter.com\u002Fbrowser-market-share",[370],"nofollow","StatCounter",") перечислены ниже.",[374,375,376,377,376,383],"figure",{},"\n  ",[378,379],"img",{"src":380,"alt":381,"width":382},"\u002Fimg\u002Faidt-mag-frontend\u002Ftopic-01\u002Fbrowser_logo_chrome.svg","Логотип Google Chrome",50,[384,385,386],"figcaption",{},"Google Chrome",[10,388,389],{},"Chrome использует движок рендеринга Blink (форк WebKit) и высокопроизводительный JavaScript-движок V8. Реализована многопроцессная архитектура: каждая вкладка работает в отдельном процессе, что повышает стабильность и облегчает изоляцию (sandboxing). Технология Site Isolation изолирует сайты друг от друга в памяти. Chrome активно поддерживает передовые веб-стандарты — WebAssembly, WebRTC, PWA, HTTP\u002F3.",[374,391,376,392,376,396],{},[378,393],{"src":394,"alt":395,"width":382},"\u002Fimg\u002Faidt-mag-frontend\u002Ftopic-01\u002Fbrowser_logo_safari.svg","Логотип Apple Safari",[384,397,398],{},"Apple Safari",[10,400,401],{},"Safari работает на движке WebKit, который Apple оптимизирует для производительности и энергоэффективности на macOS и iOS. JavaScript исполняется движком JavaScriptCore (Nitro). Safari ориентирован на низкое энергопотребление и поддерживает Intelligent Tracking Prevention (ITP) — систему защиты от отслеживания. Safari известен консервативным подходом к внедрению новых веб-стандартов, из-за чего разработчикам приходится учитывать его ограничения.",[374,403,376,404,376,408],{},[378,405],{"src":406,"alt":407,"width":382},"\u002Fimg\u002Faidt-mag-frontend\u002Ftopic-01\u002Fbrowser_logo_edge.svg","Логотип Microsoft Edge",[384,409,410],{},"Microsoft Edge",[10,412,413],{},"С 2020 года Microsoft Edge основан на Chromium и использует те же Blink и V8, что и Chrome; ранее работал на собственном движке EdgeHTML. Edge обеспечивает более низкое потребление оперативной памяти благодаря системе Sleeping Tabs и поддерживает технологию Application Guard для виртуализации вкладок. На основе Chromium Edge поддерживает практически все современные веб-стандарты и расширения из Chrome Web Store.",[374,415,376,416,376,420],{},[378,417],{"src":418,"alt":419,"width":382},"\u002Fimg\u002Faidt-mag-frontend\u002Ftopic-01\u002Fbrowser_logo_firefox.svg","Логотип Mozilla Firefox",[384,421,422],{},"Mozilla Firefox",[10,424,425],{},"Firefox использует движок Gecko и JavaScript-движок SpiderMonkey. Технология Quantum обеспечивает многопоточный рендеринг. Firefox традиционно играет роль независимой реализации стандартов, не привязанной к Chromium, и активно поддерживает WebAssembly, WebRTC, HTTP\u002F3, TLS 1.3, а также расширения на основе WebExtensions API.",[117,427,429],{"id":428},"стандартизация-w3c-whatwg-html-как-living-standard","Стандартизация: W3C, WHATWG, HTML как Living Standard",[10,431,432],{},"Одна из ключевых организаций, отвечающих за стандартизацию веб-технологий, — W3C (World Wide Web Consortium). W3C — международная организация, основанная в 1994 году Тимом Бернерсом-Ли. Её основная задача — разработка и продвижение стандартов, обеспечивающих развитие интернета как открытой и доступной среды. Члены W3C включают крупные IT-компании (Google, Microsoft, Apple, Mozilla), академические учреждения и независимых экспертов. W3C разрабатывает спецификации, известные как W3C Recommendations, которые становятся официальными стандартами после обсуждения и тестирования. Эти рекомендации охватывают HTML, CSS, DOM, WCAG, Web APIs, SVG, Semantic Web и другие технологии.",[10,434,435],{},"Разработка нового стандарта проходит несколько этапов: Working Draft (черновик) → Candidate Recommendation (кандидат в рекомендации) → Proposed Recommendation (предложенная рекомендация) → W3C Recommendation (официальная рекомендация).",[10,437,438],{},"Параллельно с W3C над стандартами веба работает консорциум WHATWG (Web Hypertext Application Technology Working Group), основанный в 2004 году разработчиками браузеров Apple, Mozilla и Opera в ответ на медленный темп работы W3C. Современный HTML развивается именно в WHATWG, как непрерывно обновляемый Living Standard, без зафиксированных «версий». Ранее принятая нумерация (HTML 4.01, HTML5) сегодня используется скорее как маркетинговый и методический ярлык; формальный источник истины — спецификация WHATWG. Долгое время W3C и WHATWG публиковали параллельные, местами расходящиеся версии HTML и DOM, что создавало путаницу для разработчиков. В 2019 году организации подписали соглашение, по которому WHATWG стал единственным держателем спецификаций HTML и DOM, а W3C сосредоточилась на других направлениях — CSS, WCAG, Web APIs.",[10,440,441,442,447,448,453],{},"Несмотря на разработанные стандарты, разные браузерные движки интерпретируют код несколько по-разному, поэтому веб-страницы могут выглядеть в браузерах не идентично. Это породило практики кросс-браузерной вёрстки и кросс-браузерного тестирования. В 2021 году основные производители браузеров инициировали проект ",[14,443,446],{"href":444,"rel":445},"https:\u002F\u002Fweb.dev\u002Fblog\u002Fcompat2021",[370],"Compat 2021",", направленный на улучшение совместимости. Годом позже стартовал ",[14,449,452],{"href":450,"rel":451},"https:\u002F\u002Fwpt.fyi\u002Finterop-2022",[370],"Interop 2022",", в рамках которого вендоры договорились поэтапно доводить поддержку заранее оговорённого объёма веб-технологий до идентичной работы во всех браузерах. Год за годом расхождения сокращаются.",[112,455,457],{"id":456},"язык-html-и-его-роль","Язык HTML и его роль",[117,459,461],{"id":460},"html-как-язык-разметки-контента-а-не-оформления","HTML как язык разметки контента, а не оформления",[10,463,464,465,468],{},"HTML — это язык разметки, который используется для структурирования контента в электронных документах с помощью элементов, определяемых тегами (англ. ",[125,466,467],{},"tag","). Браузер интерпретирует теги и отображает содержимое в соответствии с их назначением. То есть, «оборачивая» ту или иную часть документа в определённый тег, разработчик передаёт браузеру инструкцию: что это за фрагмент и как его отобразить.",[10,470,471,472,475,476,479],{},"Наглядный пример — теги ",[198,473,474],{},"\u003Ch1>"," и ",[198,477,478],{},"\u003Cp>",", размечающие заголовок и абзац:",[229,481,485],{"className":482,"code":483,"language":484,"meta":63,"style":63},"language-html shiki shiki-themes github-light github-dark","\u003Ch1>Великолепный заголовок\u003C\u002Fh1>\n\u003Cp>Не менее потрясающий абзац.\u003C\u002Fp>\n","html",[198,486,487,506],{"__ignoreMap":63},[149,488,491,495,498,501,503],{"class":489,"line":490},"line",1,[149,492,494],{"class":493},"sVt8B","\u003C",[149,496,105],{"class":497},"s9eBZ",[149,499,500],{"class":493},">Великолепный заголовок\u003C\u002F",[149,502,105],{"class":497},[149,504,505],{"class":493},">\n",[149,507,508,510,512,515,517],{"class":489,"line":64},[149,509,494],{"class":493},[149,511,10],{"class":497},[149,513,514],{"class":493},">Не менее потрясающий абзац.\u003C\u002F",[149,516,10],{"class":497},[149,518,505],{"class":493},[10,520,521],{},"Браузер отобразит:",[374,523,376,524,376,528],{},[378,525],{"src":526,"alt":527},"\u002Fimg\u002Faidt-mag-frontend\u002Ftopic-01\u002Fhtml_render_example.svg","Заголовок и абзац, отрендеренные браузером по умолчанию",[384,529,530],{},"Результат отображения заголовка и абзаца с применением браузерных стилей по умолчанию",[10,532,533,534,475,536,538,539,542],{},"Несмотря на то, что текст заголовка и абзаца визуально различается, сам HTML не позволяет управлять начертанием, кеглем, отступами и прочими параметрами отображения. Для этого служит язык стилизации CSS, который мы рассмотрим в теме 2. Различие в отображении ",[198,535,474],{},[198,537,478],{}," объясняется тем, что браузер применяет к ним собственный стиль по умолчанию (англ. ",[125,540,541],{},"user-agent stylesheet",").",[10,544,545,546,549,550,553],{},"Здесь и далее под HTML-документом мы будем понимать код на языке HTML, помещённый в файл с расширением ",[198,547,548],{},".html"," или ",[198,551,552],{},".htm",", а под веб-страницей — результат рендера этого документа браузером, с применением CSS-стилизации и исполняемого JavaScript-кода, если они были использованы.",[117,555,557],{"id":556},"структура-html-элемента-открывающий-и-закрывающий-теги-атрибуты-содержимое","Структура HTML-элемента: открывающий и закрывающий теги, атрибуты, содержимое",[10,559,560,561,564,565,568],{},"Рассмотрим структуру HTML-элемента на примере элемента ",[198,562,563],{},"\u003Ca>"," (англ. ",[125,566,567],{},"anchor",", якорь), который предназначен для создания ссылок.",[374,570,376,571,376,575],{},[378,572],{"src":573,"alt":574},"\u002Fimg\u002Faidt-mag-frontend\u002Ftopic-01\u002Fhtml_tag_structure.svg","Схема HTML-элемента: открывающий тег с атрибутами, содержимое, закрывающий тег",[384,576,577],{},"Структура HTML-элемента: открывающий тег с атрибутами, содержимое, закрывающий тег",[10,579,580],{},"HTML-элемент состоит из:",[37,582,583,592,599],{},[40,584,585,586,475,588,591],{},"открывающего и закрывающего тегов (",[198,587,563],{},[198,589,590],{},"\u003C\u002Fa>",");",[40,593,594,595,598],{},"атрибутов в открывающем теге — пар вида ",[198,596,597],{},"имя=\"значение\"",", описывающих параметры элемента. Многие атрибуты применимы ко всем элементам, но часть атрибутов специфична для конкретных тегов. Полный перечень атрибутов, определённых стандартом, доступен в справочнике MDN;",[40,600,601],{},"содержимого — текста или вложенных элементов, к которым применяется тег.",[10,603,604,605,607,608,564,611,614,615,618,619,622,623,626,627,630,631,634,635,638,639,642,643,646,647,650],{},"У тега ",[198,606,563],{}," ключевой атрибут — ",[198,609,610],{},"href",[125,612,613],{},"hypertext reference","), задающий адрес перехода. В значении допустим не только веб-URL: ",[198,616,617],{},"href=\"mailto:author@example.org\""," откроет почтовый клиент, ",[198,620,621],{},"href=\"tel:+79991234567\""," — приложение для звонка, ",[198,624,625],{},"href=\"#section-2\""," прокрутит страницу к элементу с ",[198,628,629],{},"id=\"section-2\"",". Атрибут ",[198,632,633],{},"target=\"_blank\""," открывает ссылку в новой вкладке; при этом в ",[198,636,637],{},"rel"," принято указывать ",[198,640,641],{},"noopener"," (и для надёжности ",[198,644,645],{},"noreferrer","), иначе целевая страница получает через ",[198,648,649],{},"window.opener"," доступ к текущей — потенциальная уязвимость.",[117,652,654],{"id":653},"парные-и-пустые-элементы","Парные и пустые элементы",[10,656,657,658,660,661,664,665,668,669,672,673,676,677,680,681,684,685,688],{},"Тег ",[198,659,563],{}," является парным: его открывающая и закрывающая части обрамляют содержимое. Однако существуют и пустые (англ. ",[125,662,663],{},"void",") элементы, у которых нет содержимого и нет закрывающего тега. Типичные примеры — изображение ",[198,666,667],{},"\u003Cimg>",", перенос строки ",[198,670,671],{},"\u003Cbr>",", горизонтальная линия ",[198,674,675],{},"\u003Chr>",", поле ввода ",[198,678,679],{},"\u003Cinput>",", метатег ",[198,682,683],{},"\u003Cmeta>",", ссылка на ресурс ",[198,686,687],{},"\u003Clink>",". Такие элементы целиком описываются одним тегом и набором атрибутов:",[229,690,692],{"className":482,"code":691,"language":484,"meta":63,"style":63},"\u003Cimg src=\"logo.svg\" alt=\"Логотип компании\">\n\u003Cinput type=\"email\" name=\"contact\" required>\n\u003Cmeta charset=\"UTF-8\">\n",[198,693,694,721,749],{"__ignoreMap":63},[149,695,696,698,700,704,707,711,714,716,719],{"class":489,"line":490},[149,697,494],{"class":493},[149,699,378],{"class":497},[149,701,703],{"class":702},"sScJk"," src",[149,705,706],{"class":493},"=",[149,708,710],{"class":709},"sZZnC","\"logo.svg\"",[149,712,713],{"class":702}," alt",[149,715,706],{"class":493},[149,717,718],{"class":709},"\"Логотип компании\"",[149,720,505],{"class":493},[149,722,723,725,728,731,733,736,739,741,744,747],{"class":489,"line":64},[149,724,494],{"class":493},[149,726,727],{"class":497},"input",[149,729,730],{"class":702}," type",[149,732,706],{"class":493},[149,734,735],{"class":709},"\"email\"",[149,737,738],{"class":702}," name",[149,740,706],{"class":493},[149,742,743],{"class":709},"\"contact\"",[149,745,746],{"class":702}," required",[149,748,505],{"class":493},[149,750,752,754,757,760,762,765],{"class":489,"line":751},3,[149,753,494],{"class":493},[149,755,756],{"class":497},"meta",[149,758,759],{"class":702}," charset",[149,761,706],{"class":493},[149,763,764],{"class":709},"\"UTF-8\"",[149,766,505],{"class":493},[10,768,769,770,773,774,777],{},"В XHTML и XML-совместимой записи подобные теги принято завершать косой чертой (",[198,771,772],{},"\u003Cbr \u002F>",") — отсюда ещё одно распространённое название, «самозакрывающиеся» (англ. ",[125,775,776],{},"self-closing","). В современном HTML5 слеш в пустом теге парсером допускается, но игнорируется и на поведение не влияет, поэтому такая запись считается избыточной.",[117,779,781],{"id":780},"комментарии","Комментарии",[10,783,784,785,788,789,792],{},"Любой фрагмент HTML можно заключить в комментарий вида ",[198,786,787],{},"\u003C!-- ... -->",". Содержимое комментария не отображается на странице и не влияет на разметку, но видно в исходном коде и в DevTools. Комментарии используются для пояснений в разметке (обозначить начало секции, оставить TODO для команды) и временного отключения участков, которые жалко удалять окончательно. Главное ограничение — комментарии нельзя вкладывать друг в друга: парсер закроет внешний на первой же встреченной последовательности ",[198,790,791],{},"-->",", и остаток уйдёт в обычный текст страницы.",[117,794,796],{"id":795},"вложенность-элементов-и-иерархическая-модель-документа","Вложенность элементов и иерархическая модель документа",[10,798,799],{},"HTML позволяет вкладывать одни элементы в другие, образуя иерархическую структуру страницы. Вложенность важна для правильного отображения и логической организации контента. Пример:",[229,801,803],{"className":482,"code":802,"language":484,"meta":63,"style":63},"\u003Cdiv id=\"el-1\">\n    Элемент 1\n    \u003Cdiv id=\"el-2\">\n        Элемент 2\n    \u003C\u002Fdiv>\n    \u003Cdiv id=\"el-3\">\n        Элемент 3\n    \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n",[198,804,805,822,827,843,849,859,875,881,890],{"__ignoreMap":63},[149,806,807,809,812,815,817,820],{"class":489,"line":490},[149,808,494],{"class":493},[149,810,811],{"class":497},"div",[149,813,814],{"class":702}," id",[149,816,706],{"class":493},[149,818,819],{"class":709},"\"el-1\"",[149,821,505],{"class":493},[149,823,824],{"class":489,"line":64},[149,825,826],{"class":493},"    Элемент 1\n",[149,828,829,832,834,836,838,841],{"class":489,"line":751},[149,830,831],{"class":493},"    \u003C",[149,833,811],{"class":497},[149,835,814],{"class":702},[149,837,706],{"class":493},[149,839,840],{"class":709},"\"el-2\"",[149,842,505],{"class":493},[149,844,846],{"class":489,"line":845},4,[149,847,848],{"class":493},"        Элемент 2\n",[149,850,852,855,857],{"class":489,"line":851},5,[149,853,854],{"class":493},"    \u003C\u002F",[149,856,811],{"class":497},[149,858,505],{"class":493},[149,860,862,864,866,868,870,873],{"class":489,"line":861},6,[149,863,831],{"class":493},[149,865,811],{"class":497},[149,867,814],{"class":702},[149,869,706],{"class":493},[149,871,872],{"class":709},"\"el-3\"",[149,874,505],{"class":493},[149,876,878],{"class":489,"line":877},7,[149,879,880],{"class":493},"        Элемент 3\n",[149,882,884,886,888],{"class":489,"line":883},8,[149,885,854],{"class":493},[149,887,811],{"class":497},[149,889,505],{"class":493},[149,891,893,896,898],{"class":489,"line":892},9,[149,894,895],{"class":493},"\u003C\u002F",[149,897,811],{"class":497},[149,899,505],{"class":493},[10,901,902],{},"После небольшой стилизации браузер отобразит это так:",[374,904,376,905,376,909],{},[378,906],{"src":907,"alt":908},"\u002Fimg\u002Faidt-mag-frontend\u002Ftopic-01\u002Fhtml_inlay_sample.svg","Три вложенных контейнера: внешний и два внутренних",[384,910,911],{},"Вложенность HTML-элементов: внешний контейнер и два внутренних",[10,913,914],{},"По отношению к элементам 2 и 3 элемент 1 является родительским, а элементы 2 и 3 — дочерними по отношению к элементу 1. Совокупность таких отношений образует дерево документа: каждый элемент имеет ровно одного родителя (кроме корневого) и любое количество дочерних элементов. Это дерево лежит в основе всей последующей работы — на нём строятся CSS-селекторы, на нём же стоит DOM, через который JavaScript манипулирует страницей (тема 7).",[10,916,917,918,921],{},"Хорошим тоном при написании HTML-кода является явная демонстрация вложенности через отступы (англ. ",[125,919,920],{},"indent","), как показано в примере выше. Современные редакторы и форматировщики делают это автоматически.",[112,923,925],{"id":924},"структура-html-документа","Структура HTML-документа",[10,927,928],{},"Каждый HTML-документ имеет определённую структуру, состоящую из обязательных и вспомогательных элементов. Рассмотрим базовый пример:",[229,930,932],{"className":482,"code":931,"language":484,"meta":63,"style":63},"\u003C!DOCTYPE html>\n\u003Chtml lang=\"ru\">\n\u003Chead>\n    \u003Cmeta charset=\"UTF-8\">\n    \u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    \u003Ctitle>Вдохновляющий заголовок страницы\u003C\u002Ftitle>\n\u003C\u002Fhead>\n\u003Cbody>\n    \u003Ch1>Великолепный заголовок\u003C\u002Fh1>\n    \u003Cp>Не менее потрясающий абзац.\u003C\u002Fp>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n",[198,933,934,947,963,972,986,1009,1023,1031,1040,1052,1064,1073],{"__ignoreMap":63},[149,935,936,939,942,945],{"class":489,"line":490},[149,937,938],{"class":493},"\u003C!",[149,940,941],{"class":497},"DOCTYPE",[149,943,944],{"class":702}," html",[149,946,505],{"class":493},[149,948,949,951,953,956,958,961],{"class":489,"line":64},[149,950,494],{"class":493},[149,952,484],{"class":497},[149,954,955],{"class":702}," lang",[149,957,706],{"class":493},[149,959,960],{"class":709},"\"ru\"",[149,962,505],{"class":493},[149,964,965,967,970],{"class":489,"line":751},[149,966,494],{"class":493},[149,968,969],{"class":497},"head",[149,971,505],{"class":493},[149,973,974,976,978,980,982,984],{"class":489,"line":845},[149,975,831],{"class":493},[149,977,756],{"class":497},[149,979,759],{"class":702},[149,981,706],{"class":493},[149,983,764],{"class":709},[149,985,505],{"class":493},[149,987,988,990,992,994,996,999,1002,1004,1007],{"class":489,"line":851},[149,989,831],{"class":493},[149,991,756],{"class":497},[149,993,738],{"class":702},[149,995,706],{"class":493},[149,997,998],{"class":709},"\"viewport\"",[149,1000,1001],{"class":702}," content",[149,1003,706],{"class":493},[149,1005,1006],{"class":709},"\"width=device-width, initial-scale=1.0\"",[149,1008,505],{"class":493},[149,1010,1011,1013,1016,1019,1021],{"class":489,"line":861},[149,1012,831],{"class":493},[149,1014,1015],{"class":497},"title",[149,1017,1018],{"class":493},">Вдохновляющий заголовок страницы\u003C\u002F",[149,1020,1015],{"class":497},[149,1022,505],{"class":493},[149,1024,1025,1027,1029],{"class":489,"line":877},[149,1026,895],{"class":493},[149,1028,969],{"class":497},[149,1030,505],{"class":493},[149,1032,1033,1035,1038],{"class":489,"line":883},[149,1034,494],{"class":493},[149,1036,1037],{"class":497},"body",[149,1039,505],{"class":493},[149,1041,1042,1044,1046,1048,1050],{"class":489,"line":892},[149,1043,831],{"class":493},[149,1045,105],{"class":497},[149,1047,500],{"class":493},[149,1049,105],{"class":497},[149,1051,505],{"class":493},[149,1053,1054,1056,1058,1060,1062],{"class":489,"line":75},[149,1055,831],{"class":493},[149,1057,10],{"class":497},[149,1059,514],{"class":493},[149,1061,10],{"class":497},[149,1063,505],{"class":493},[149,1065,1067,1069,1071],{"class":489,"line":1066},11,[149,1068,895],{"class":493},[149,1070,1037],{"class":497},[149,1072,505],{"class":493},[149,1074,1076,1078,1080],{"class":489,"line":1075},12,[149,1077,895],{"class":493},[149,1079,484],{"class":497},[149,1081,505],{"class":493},[117,1083,1085,1088],{"id":1084},"doctype-и-режим-стандартов",[198,1086,1087],{},"\u003C!DOCTYPE>"," и режим стандартов",[10,1090,1091,1093,1094,1097,1098,1101],{},[198,1092,1087],{}," (",[125,1095,1096],{},"document type",") — объявление типа документа, в котором указывается тип и версия языка разметки для корректной обработки последующего содержимого браузером. Правильное объявление типа критически важно: при его отсутствии или некорректной форме браузер переходит в режим совместимости (англ. ",[125,1099,1100],{},"quirks mode","), имитирующий поведение старых версий браузеров. Это сделано, чтобы не сломать унаследованные сайты двадцатилетней давности, но почти гарантированно приведёт к неправильной интерпретации актуального HTML- и CSS-кода.",[10,1103,1104,1105,1108],{},"В современной практике используется HTML5, которому соответствует лаконичная инструкция ",[198,1106,1107],{},"\u003C!DOCTYPE html>"," — её и следует ставить первой строкой любого нового документа. Для более старых версий HTML и XHTML существовали свои громоздкие формы записи, которые сегодня встречаются только в исторических документах.",[10,1110,1111,1112,1117],{},"Проверить разметку на соответствие спецификации можно официальным валидатором W3C — ",[14,1113,1116],{"href":1114,"rel":1115},"https:\u002F\u002Fvalidator.w3.org\u002F",[370],"validator.w3.org",". Он принимает URL, файл или фрагмент кода и возвращает перечень нарушений: незакрытые теги, недопустимая вложенность, неизвестные атрибуты, проблемы с доступностью. Прогонять через валидатор готовые страницы — полезная привычка: часть ошибок браузеры молча «прощают», но они всплывают позже в виде странных артефактов рендера или проблем с доступностью.",[117,1119,1121,1122,1125,1126,475,1129],{"id":1120},"корневой-элемент-html-атрибуты-lang-и-dir","Корневой элемент ",[198,1123,1124],{},"\u003Chtml>",", атрибуты ",[198,1127,1128],{},"lang",[198,1130,1131],{},"dir",[10,1133,1134,1136],{},[198,1135,1124],{}," — корневой элемент, внутри которого размещается весь контент страницы. Из его атрибутов в практике важны прежде всего:",[37,1138,1139,1150],{},[40,1140,1141,1143,1144,1146,1147,1149],{},[198,1142,1128],{}," — указывает язык содержимого документа. В нашем примере значение ",[198,1145,960],{}," соответствует русскому языку. Атрибут позволяет браузеру корректно применить типографические правила (вид кавычек, расстановка переносов), а ассистивным технологиям — выбрать правильный движок синтеза речи. Указывать ",[198,1148,1128],{}," — обязательная практика;",[40,1151,1152,1154,1155,1158,1159,1162],{},[198,1153,1131],{}," — направление текста: ",[198,1156,1157],{},"ltr"," (слева направо, значение по умолчанию) или ",[198,1160,1161],{},"rtl"," (справа налево, для арабского, иврита и др.).",[117,1164,1166,1167,1170],{"id":1165},"раздел-head-кодировка-viewport-заголовок-подключение-ресурсов","Раздел ",[198,1168,1169],{},"\u003Chead>",": кодировка, viewport, заголовок, подключение ресурсов",[10,1172,1173,1175],{},[198,1174,1169],{}," содержит метаинформацию о документе, не отображаемую как контент страницы. Типовое наполнение:",[37,1177,1178,1184,1190,1196,1202],{},[40,1179,1180,1183],{},[198,1181,1182],{},"\u003Cmeta charset=\"UTF-8\">"," — кодировка документа. UTF-8 сегодня является де-факто стандартом, обеспечивающим корректное отображение символов любых письменностей;",[40,1185,1186,1189],{},[198,1187,1188],{},"\u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"," — управляет масштабом страницы на мобильных устройствах. Без этого тега мобильные браузеры покажут страницу в режиме «как на настольном компьютере» с уменьшенным масштабом, что для современных адаптивных сайтов нежелательно;",[40,1191,1192,1195],{},[198,1193,1194],{},"\u003Ctitle>"," — заголовок страницы, отображается на вкладке браузера, в результатах поиска и в подписях ссылок при шаринге;",[40,1197,1198,1201],{},[198,1199,1200],{},"\u003Clink rel=\"stylesheet\" href=\"styles.css\">"," — подключение внешнего файла со стилями;",[40,1203,1204,1207,1208,1211,1212,1215,1216,1219,1220,1222,1223,549,1225,1228,1229,1232],{},[198,1205,1206],{},"\u003Cscript src=\"script.js\" defer>\u003C\u002Fscript>"," — подключение внешнего JavaScript-файла. Атрибут ",[198,1209,1210],{},"defer"," откладывает выполнение скрипта до построения дерева документа. Скрипт может подключаться и в ",[198,1213,1214],{},"\u003Cbody>"," (обычно в самом конце, чтобы не блокировать рендер контента), но современная практика — размещать ",[198,1217,1218],{},"\u003Cscript>"," в ",[198,1221,1169],{}," с атрибутом ",[198,1224,1210],{},[198,1226,1227],{},"async",". Для ES-модулей используется запись ",[198,1230,1231],{},"\u003Cscript src=\"script.js\" type=\"module\">\u003C\u002Fscript>","; подробнее о модулях — в теме 6.",[117,1234,1166,1236,1238],{"id":1235},"раздел-body-видимый-контент-страницы",[198,1237,1214],{},": видимый контент страницы",[10,1240,1241,1243,1244,1246,1247,1249,1250,1252,1253,549,1255,542],{},[198,1242,1214],{}," содержит основное содержимое веб-страницы — текст, изображения, ссылки, формы, мультимедиа. Всё, что пользователь увидит на странице, должно располагаться здесь. У ",[198,1245,1214],{}," нет жёстких ограничений на состав, кроме одного: внутри ",[198,1248,1214],{}," не размещают теги, относящиеся к разделу ",[198,1251,1169],{}," (например, ",[198,1254,683],{},[198,1256,1194],{},[117,1258,1260],{"id":1259},"базовые-блочные-и-строчные-элементы","Базовые блочные и строчные элементы",[10,1262,1263],{},"Поток документа — естественный порядок размещения элементов перед применением стилей. Браузер рендерит HTML сверху вниз, располагая элементы в порядке их появления в коде. Этот процесс называется нормальным потоком документа.",[10,1265,1266],{},"По умолчанию браузер размещает элементы в одном из двух базовых режимов, определяемом типом элемента:",[37,1268,1269,1290],{},[40,1270,1271,1272,1275,1276,266,1279,266,1281,1283,1284,266,1287,47],{},"блочные (англ. ",[125,1273,1274],{},"block",") элементы занимают всю доступную ширину родительского контейнера и начинаются с новой строки, располагаясь друг под другом. Даже если ширина блочного элемента явно задана и рядом мог бы поместиться такой же, в потоке они выстраиваются один под другим. Блочные элементы могут содержать как другие блочные, так и строчные элементы. Примеры: ",[198,1277,1278],{},"\u003Cdiv>",[198,1280,478],{},[198,1282,474],{},"–",[198,1285,1286],{},"\u003Ch6>",[198,1288,1289],{},"\u003Csection>",[40,1291,1292,1293,1296,1297,1299,1300,266,1303,266,1305,266,1308,18],{},"строчные (англ. ",[125,1294,1295],{},"inline",") элементы занимают только необходимую ширину и не создают разрывов строк. Несколько строчных элементов стремятся уместиться на одной строке, насколько хватает ширины родителя; при недостатке ширины текст переносится на следующую строку. Как правило, строчные элементы содержат текст или другие строчные элементы; из этого правила есть исключения (например, у ",[198,1298,563],{}," в HTML5 прозрачная модель содержимого, и он может оборачивать блочные элементы), но на первых порах ориентироваться на упрощённое правило удобно. Примеры: ",[198,1301,1302],{},"\u003Cspan>",[198,1304,563],{},[198,1306,1307],{},"\u003Cq>",[198,1309,1310],{},"\u003Ccode>",[10,1312,1313],{},"Нормальный поток и его поведение мы детально рассмотрим в теме 3, посвящённой layout. Пока достаточно понимать, что разделение на блочные и строчные элементы — это базовая настройка отображения, которую затем можно переопределить с помощью CSS.",[10,1315,1316,1317,1320,1321,266,1324,266,1327,1330,1331,1334,1335,1338,1339,1342,1343,1345],{},"В HTML возможно использование специальных символов — мнемоник (англ. ",[125,1318,1319],{},"named character references","). В первую очередь они нужны для знаков, конфликтующих с синтаксисом самого HTML: ",[198,1322,1323],{},"&lt;",[198,1325,1326],{},"&gt;",[198,1328,1329],{},"&amp;",". Кроме того, мнемоники вроде ",[198,1332,1333],{},"&copy;"," (©), ",[198,1336,1337],{},"&mdash;"," (—), ",[198,1340,1341],{},"&nbsp;"," (неразрывный пробел) исторически применялись для типографических символов, отсутствующих на клавиатуре. При кодировке UTF-8 все эти знаки можно и удобнее записывать в исходнике напрямую; мнемоника ",[198,1344,1341],{}," остаётся востребованной, поскольку сам неразрывный пробел в коде визуально неотличим от обычного.",[112,1347,1349],{"id":1348},"семантическая-разметка","Семантическая разметка",[117,1351,1353],{"id":1352},"зачем-нужна-семантика-доступность-seo-ассистивные-технологии","Зачем нужна семантика: доступность, SEO, ассистивные технологии",[10,1355,1356,1357,1359,1360,1362,1363,1366,1367,266,1370,266,1373,266,1376,266,1378,266,1381,266,1384,1387],{},"Семантическая разметка — способ структурирования веб-страницы с использованием элементов, которые ясно передают смысл их содержимого. Большинство HTML-тегов уже несут семантическую нагрузку: ",[198,1358,474],{}," отмечает заголовок первого уровня, ",[198,1361,478],{}," — абзац, ",[198,1364,1365],{},"\u003Cul>"," — ненумерованный список. В HTML5 были добавлены специальные секционирующие теги — ",[198,1368,1369],{},"\u003Cheader>",[198,1371,1372],{},"\u003Cnav>",[198,1374,1375],{},"\u003Cmain>",[198,1377,1289],{},[198,1379,1380],{},"\u003Carticle>",[198,1382,1383],{},"\u003Caside>",[198,1385,1386],{},"\u003Cfooter>"," — позволяющие выразить не только смысл отдельных фрагментов, но и общую структуру страницы.",[10,1389,1390],{},"Семантичная разметка преследует три практические цели:",[37,1392,1393,1411,1418],{},[40,1394,1395,1396,1399,1400,1403,1404,1407,1408,1410],{},"доступность (англ. ",[125,1397,1398],{},"accessibility","): ассистивные технологии, в первую очередь программы чтения с экрана (англ. ",[125,1401,1402],{},"screen reader","), используют семантическую разметку для построения навигации по странице. Пользователь скринридера может перейти к следующему ",[198,1405,1406],{},"\u003Ch2>"," или попасть в основной блок ",[198,1409,1375],{}," одной командой — но только если эти элементы расставлены;",[40,1412,1413,1414,1417],{},"поисковая оптимизация (англ. ",[125,1415,1416],{},"Search Engine Optimization",", SEO): поисковые роботы используют семантическую разметку для понимания иерархии и важности контента;",[40,1419,1420,1421,18],{},"сопровождаемость кода: разметка с осмысленными именами тегов читается быстрее, чем сплошное полотно из ",[198,1422,1278],{},[117,1424,1426,1427,266,1430,266,1433,266,1436,266,1439,266,1442,266,1445],{"id":1425},"секционирующие-элементы-header-nav-main-article-section-aside-footer","Секционирующие элементы: ",[198,1428,1429],{},"header",[198,1431,1432],{},"nav",[198,1434,1435],{},"main",[198,1437,1438],{},"article",[198,1440,1441],{},"section",[198,1443,1444],{},"aside",[198,1446,1447],{},"footer",[10,1449,1450],{},"Секционирующие теги используются для определения структуры страницы и организации контента в крупные смысловые блоки:",[37,1452,1453,1458,1463,1468,1473,1478,1483],{},[40,1454,1455,1457],{},[198,1456,1369],{}," — заголовочная часть страницы или отдельного раздела;",[40,1459,1460,1462],{},[198,1461,1372],{}," — основная навигация сайта;",[40,1464,1465,1467],{},[198,1466,1375],{}," — основной контент страницы (уникальный для каждой страницы; на странице должен быть ровно один такой элемент);",[40,1469,1470,1472],{},[198,1471,1289],{}," — логически связанный раздел контента;",[40,1474,1475,1477],{},[198,1476,1380],{}," — независимый контент, который имеет смысл и вне страницы (статья, пост блога, карточка товара);",[40,1479,1480,1482],{},[198,1481,1383],{}," — боковой блок с дополнительной информацией, связанной с основным контентом косвенно (врезки, сноски, справочные блоки);",[40,1484,1485,1487],{},[198,1486,1386],{}," — нижняя часть страницы или раздела с контактами, копирайтом, ссылками.",[10,1489,1490],{},"Пример типового использования:",[229,1492,1494],{"className":482,"code":1493,"language":484,"meta":63,"style":63},"\u003Cheader>\n    \u003Ch1>Название отличного сайта\u003C\u002Fh1>\n    \u003Cnav>\n        \u003Cul>\n            \u003Cli>\u003Ca href=\"\u002F\">Главная\u003C\u002Fa>\u003C\u002Fli>\n            \u003Cli>\u003Ca href=\"\u002Fabout\">О нас\u003C\u002Fa>\u003C\u002Fli>\n        \u003C\u002Ful>\n    \u003C\u002Fnav>\n\u003C\u002Fheader>\n\u003Cmain>\n    \u003Csection>\n        \u003Ch2>Наши услуги\u003C\u002Fh2>\n        \u003Cp>Мы предоставляем лучшие решения.\u003C\u002Fp>\n    \u003C\u002Fsection>\n    \u003Caside>\n        \u003Ch3>Полезные ссылки\u003C\u002Fh3>\n        \u003Cul>\n            \u003Cli>\u003Ca href=\"\u002Fblog\">Блог\u003C\u002Fa>\u003C\u002Fli>\n            \u003Cli>\u003Ca href=\"\u002Fcontacts\">Контакты\u003C\u002Fa>\u003C\u002Fli>\n        \u003C\u002Ful>\n    \u003C\u002Faside>\n\u003C\u002Fmain>\n\u003Cfooter>\n    \u003Cp>&copy; 2026 Все права защищены.\u003C\u002Fp>\n\u003C\u002Ffooter>\n",[198,1495,1496,1504,1517,1525,1534,1566,1594,1603,1611,1619,1627,1635,1648,1662,1671,1680,1694,1703,1732,1761,1770,1779,1788,1797,1817],{"__ignoreMap":63},[149,1497,1498,1500,1502],{"class":489,"line":490},[149,1499,494],{"class":493},[149,1501,1429],{"class":497},[149,1503,505],{"class":493},[149,1505,1506,1508,1510,1513,1515],{"class":489,"line":64},[149,1507,831],{"class":493},[149,1509,105],{"class":497},[149,1511,1512],{"class":493},">Название отличного сайта\u003C\u002F",[149,1514,105],{"class":497},[149,1516,505],{"class":493},[149,1518,1519,1521,1523],{"class":489,"line":751},[149,1520,831],{"class":493},[149,1522,1432],{"class":497},[149,1524,505],{"class":493},[149,1526,1527,1530,1532],{"class":489,"line":845},[149,1528,1529],{"class":493},"        \u003C",[149,1531,37],{"class":497},[149,1533,505],{"class":493},[149,1535,1536,1539,1541,1544,1546,1549,1551,1554,1557,1559,1562,1564],{"class":489,"line":851},[149,1537,1538],{"class":493},"            \u003C",[149,1540,40],{"class":497},[149,1542,1543],{"class":493},">\u003C",[149,1545,14],{"class":497},[149,1547,1548],{"class":702}," href",[149,1550,706],{"class":493},[149,1552,1553],{"class":709},"\"\u002F\"",[149,1555,1556],{"class":493},">Главная\u003C\u002F",[149,1558,14],{"class":497},[149,1560,1561],{"class":493},">\u003C\u002F",[149,1563,40],{"class":497},[149,1565,505],{"class":493},[149,1567,1568,1570,1572,1574,1576,1578,1580,1583,1586,1588,1590,1592],{"class":489,"line":861},[149,1569,1538],{"class":493},[149,1571,40],{"class":497},[149,1573,1543],{"class":493},[149,1575,14],{"class":497},[149,1577,1548],{"class":702},[149,1579,706],{"class":493},[149,1581,1582],{"class":709},"\"\u002Fabout\"",[149,1584,1585],{"class":493},">О нас\u003C\u002F",[149,1587,14],{"class":497},[149,1589,1561],{"class":493},[149,1591,40],{"class":497},[149,1593,505],{"class":493},[149,1595,1596,1599,1601],{"class":489,"line":877},[149,1597,1598],{"class":493},"        \u003C\u002F",[149,1600,37],{"class":497},[149,1602,505],{"class":493},[149,1604,1605,1607,1609],{"class":489,"line":883},[149,1606,854],{"class":493},[149,1608,1432],{"class":497},[149,1610,505],{"class":493},[149,1612,1613,1615,1617],{"class":489,"line":892},[149,1614,895],{"class":493},[149,1616,1429],{"class":497},[149,1618,505],{"class":493},[149,1620,1621,1623,1625],{"class":489,"line":75},[149,1622,494],{"class":493},[149,1624,1435],{"class":497},[149,1626,505],{"class":493},[149,1628,1629,1631,1633],{"class":489,"line":1066},[149,1630,831],{"class":493},[149,1632,1441],{"class":497},[149,1634,505],{"class":493},[149,1636,1637,1639,1641,1644,1646],{"class":489,"line":1075},[149,1638,1529],{"class":493},[149,1640,112],{"class":497},[149,1642,1643],{"class":493},">Наши услуги\u003C\u002F",[149,1645,112],{"class":497},[149,1647,505],{"class":493},[149,1649,1651,1653,1655,1658,1660],{"class":489,"line":1650},13,[149,1652,1529],{"class":493},[149,1654,10],{"class":497},[149,1656,1657],{"class":493},">Мы предоставляем лучшие решения.\u003C\u002F",[149,1659,10],{"class":497},[149,1661,505],{"class":493},[149,1663,1665,1667,1669],{"class":489,"line":1664},14,[149,1666,854],{"class":493},[149,1668,1441],{"class":497},[149,1670,505],{"class":493},[149,1672,1674,1676,1678],{"class":489,"line":1673},15,[149,1675,831],{"class":493},[149,1677,1444],{"class":497},[149,1679,505],{"class":493},[149,1681,1683,1685,1687,1690,1692],{"class":489,"line":1682},16,[149,1684,1529],{"class":493},[149,1686,117],{"class":497},[149,1688,1689],{"class":493},">Полезные ссылки\u003C\u002F",[149,1691,117],{"class":497},[149,1693,505],{"class":493},[149,1695,1697,1699,1701],{"class":489,"line":1696},17,[149,1698,1529],{"class":493},[149,1700,37],{"class":497},[149,1702,505],{"class":493},[149,1704,1706,1708,1710,1712,1714,1716,1718,1721,1724,1726,1728,1730],{"class":489,"line":1705},18,[149,1707,1538],{"class":493},[149,1709,40],{"class":497},[149,1711,1543],{"class":493},[149,1713,14],{"class":497},[149,1715,1548],{"class":702},[149,1717,706],{"class":493},[149,1719,1720],{"class":709},"\"\u002Fblog\"",[149,1722,1723],{"class":493},">Блог\u003C\u002F",[149,1725,14],{"class":497},[149,1727,1561],{"class":493},[149,1729,40],{"class":497},[149,1731,505],{"class":493},[149,1733,1735,1737,1739,1741,1743,1745,1747,1750,1753,1755,1757,1759],{"class":489,"line":1734},19,[149,1736,1538],{"class":493},[149,1738,40],{"class":497},[149,1740,1543],{"class":493},[149,1742,14],{"class":497},[149,1744,1548],{"class":702},[149,1746,706],{"class":493},[149,1748,1749],{"class":709},"\"\u002Fcontacts\"",[149,1751,1752],{"class":493},">Контакты\u003C\u002F",[149,1754,14],{"class":497},[149,1756,1561],{"class":493},[149,1758,40],{"class":497},[149,1760,505],{"class":493},[149,1762,1764,1766,1768],{"class":489,"line":1763},20,[149,1765,1598],{"class":493},[149,1767,37],{"class":497},[149,1769,505],{"class":493},[149,1771,1773,1775,1777],{"class":489,"line":1772},21,[149,1774,854],{"class":493},[149,1776,1444],{"class":497},[149,1778,505],{"class":493},[149,1780,1782,1784,1786],{"class":489,"line":1781},22,[149,1783,895],{"class":493},[149,1785,1435],{"class":497},[149,1787,505],{"class":493},[149,1789,1791,1793,1795],{"class":489,"line":1790},23,[149,1792,494],{"class":493},[149,1794,1447],{"class":497},[149,1796,505],{"class":493},[149,1798,1800,1802,1804,1807,1810,1813,1815],{"class":489,"line":1799},24,[149,1801,831],{"class":493},[149,1803,10],{"class":497},[149,1805,1806],{"class":493},">",[149,1808,1333],{"class":1809},"sj4cs",[149,1811,1812],{"class":493}," 2026 Все права защищены.\u003C\u002F",[149,1814,10],{"class":497},[149,1816,505],{"class":493},[149,1818,1820,1822,1824],{"class":489,"line":1819},25,[149,1821,895],{"class":493},[149,1823,1447],{"class":497},[149,1825,505],{"class":493},[117,1827,1829,1830,266,1832,266,1834,266,1837,266,1840],{"id":1828},"текстовые-и-групповые-элементы-figure-figcaption-details-summary-dialog","Текстовые и групповые элементы: ",[198,1831,374],{},[198,1833,384],{},[198,1835,1836],{},"details",[198,1838,1839],{},"summary",[198,1841,1842],{},"dialog",[10,1844,1845],{},"Помимо секционирующих, в HTML5 есть набор текстовых и групповых элементов для разметки отдельных смысловых единиц:",[37,1847,1848,1854,1863,1878,1890,1896,1905,1911,1917],{},[40,1849,1850,1853],{},[198,1851,1852],{},"\u003Cfigure>"," — контейнер для иллюстраций, схем, фотографий, фрагментов кода, таблиц, на которые ссылается основной текст;",[40,1855,1856,1859,1860,1862],{},[198,1857,1858],{},"\u003Cfigcaption>"," — подпись к содержимому ",[198,1861,1852],{},", обычно первый или последний дочерний элемент;",[40,1864,1865,475,1868,1871,1872,1874,1875,1877],{},[198,1866,1867],{},"\u003Cdetails>",[198,1869,1870],{},"\u003Csummary>"," — раскрывающийся блок: пользователь видит ",[198,1873,1870],{},", а развёрнутое содержимое ",[198,1876,1867],{}," показывается по клику. Готовая встроенная функциональность аккордеона без JavaScript;",[40,1879,1880,1883,1884,1887,1888,47],{},[198,1881,1882],{},"\u003Cdialog>"," — модальное или немодальное диалоговое окно, открываемое через DOM-метод ",[198,1885,1886],{},"showModal()",". Современная замена ручных реализаций модальных окон поверх ",[198,1889,1278],{},[40,1891,1892,1895],{},[198,1893,1894],{},"\u003Cmark>"," — выделение фрагмента, который требует внимания читателя (например, найденный поиском текст);",[40,1897,1898,1901,1902,591],{},[198,1899,1900],{},"\u003Ctime>"," — дата или время в машинно-читаемой форме (",[198,1903,1904],{},"\u003Ctime datetime=\"2026-04-22\">22 апреля 2026\u003C\u002Ftime>",[40,1906,1907,1910],{},[198,1908,1909],{},"\u003Caddress>"," — контактная информация автора или владельца раздела;",[40,1912,1913,1916],{},[198,1914,1915],{},"\u003Ccite>"," — указание на источник или название цитируемой работы;",[40,1918,1919,1922],{},[198,1920,1921],{},"\u003Cblockquote>"," — блочная цитата большого объёма.",[10,1924,1925],{},"Пример сочетания нескольких контентных элементов:",[229,1927,1929],{"className":482,"code":1928,"language":484,"meta":63,"style":63},"\u003Carticle>\n    \u003Cfigure>\n        \u003Cimg src=\"cover.jpg\" alt=\"Обложка статьи\">\n        \u003Cfigcaption>Обложка статьи\u003C\u002Ffigcaption>\n    \u003C\u002Ffigure>\n    \u003Cp>Дата публикации: \u003Ctime datetime=\"2026-04-22\">22 апреля 2026\u003C\u002Ftime>\u003C\u002Fp>\n    \u003Cdetails>\n        \u003Csummary>Аннотация\u003C\u002Fsummary>\n        \u003Cp>Краткое содержание статьи, раскрываемое по клику.\u003C\u002Fp>\n    \u003C\u002Fdetails>\n\u003C\u002Farticle>\n",[198,1930,1931,1939,1947,1969,1982,1990,2021,2029,2042,2055,2063],{"__ignoreMap":63},[149,1932,1933,1935,1937],{"class":489,"line":490},[149,1934,494],{"class":493},[149,1936,1438],{"class":497},[149,1938,505],{"class":493},[149,1940,1941,1943,1945],{"class":489,"line":64},[149,1942,831],{"class":493},[149,1944,374],{"class":497},[149,1946,505],{"class":493},[149,1948,1949,1951,1953,1955,1957,1960,1962,1964,1967],{"class":489,"line":751},[149,1950,1529],{"class":493},[149,1952,378],{"class":497},[149,1954,703],{"class":702},[149,1956,706],{"class":493},[149,1958,1959],{"class":709},"\"cover.jpg\"",[149,1961,713],{"class":702},[149,1963,706],{"class":493},[149,1965,1966],{"class":709},"\"Обложка статьи\"",[149,1968,505],{"class":493},[149,1970,1971,1973,1975,1978,1980],{"class":489,"line":845},[149,1972,1529],{"class":493},[149,1974,384],{"class":497},[149,1976,1977],{"class":493},">Обложка статьи\u003C\u002F",[149,1979,384],{"class":497},[149,1981,505],{"class":493},[149,1983,1984,1986,1988],{"class":489,"line":851},[149,1985,854],{"class":493},[149,1987,374],{"class":497},[149,1989,505],{"class":493},[149,1991,1992,1994,1996,1999,2002,2005,2007,2010,2013,2015,2017,2019],{"class":489,"line":861},[149,1993,831],{"class":493},[149,1995,10],{"class":497},[149,1997,1998],{"class":493},">Дата публикации: \u003C",[149,2000,2001],{"class":497},"time",[149,2003,2004],{"class":702}," datetime",[149,2006,706],{"class":493},[149,2008,2009],{"class":709},"\"2026-04-22\"",[149,2011,2012],{"class":493},">22 апреля 2026\u003C\u002F",[149,2014,2001],{"class":497},[149,2016,1561],{"class":493},[149,2018,10],{"class":497},[149,2020,505],{"class":493},[149,2022,2023,2025,2027],{"class":489,"line":877},[149,2024,831],{"class":493},[149,2026,1836],{"class":497},[149,2028,505],{"class":493},[149,2030,2031,2033,2035,2038,2040],{"class":489,"line":883},[149,2032,1529],{"class":493},[149,2034,1839],{"class":497},[149,2036,2037],{"class":493},">Аннотация\u003C\u002F",[149,2039,1839],{"class":497},[149,2041,505],{"class":493},[149,2043,2044,2046,2048,2051,2053],{"class":489,"line":892},[149,2045,1529],{"class":493},[149,2047,10],{"class":497},[149,2049,2050],{"class":493},">Краткое содержание статьи, раскрываемое по клику.\u003C\u002F",[149,2052,10],{"class":497},[149,2054,505],{"class":493},[149,2056,2057,2059,2061],{"class":489,"line":75},[149,2058,854],{"class":493},[149,2060,1836],{"class":497},[149,2062,505],{"class":493},[149,2064,2065,2067,2069],{"class":489,"line":1066},[149,2066,895],{"class":493},[149,2068,1438],{"class":497},[149,2070,505],{"class":493},[117,2072,2074],{"id":2073},"сравнение-семантичной-разметки-и-div-ада","Сравнение семантичной разметки и «div-ада»",[10,2076,2077,2078,2080,2081,2083],{},"Среди всех HTML-элементов отдельно стоит выделить ",[198,2079,1278],{},". Этот элемент — конструкционный контейнер: он не несёт семантического значения и без стилизации невидим для пользователя. Та же страница, что в примере выше, могла бы быть собрана исключительно на ",[198,2082,1278],{},":",[229,2085,2087],{"className":482,"code":2086,"language":484,"meta":63,"style":63},"\u003Cdiv>\n    \u003Ch1>Название отличного сайта\u003C\u002Fh1>\n    \u003Cdiv>\n        \u003Cul>\n            \u003Cli>\u003Ca href=\"\u002F\">Главная\u003C\u002Fa>\u003C\u002Fli>\n            \u003Cli>\u003Ca href=\"\u002Fabout\">О нас\u003C\u002Fa>\u003C\u002Fli>\n        \u003C\u002Ful>\n    \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003Cdiv>\n    \u003Cdiv>\n        \u003Ch2>Наши услуги\u003C\u002Fh2>\n        \u003Cp>Мы предоставляем лучшие решения.\u003C\u002Fp>\n    \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003Cdiv>\n    \u003Cp>&copy; 2026 Все права защищены.\u003C\u002Fp>\n\u003C\u002Fdiv>\n",[198,2088,2089,2097,2109,2117,2125,2151,2177,2185,2193,2201,2209,2217,2229,2241,2249,2257,2265,2281],{"__ignoreMap":63},[149,2090,2091,2093,2095],{"class":489,"line":490},[149,2092,494],{"class":493},[149,2094,811],{"class":497},[149,2096,505],{"class":493},[149,2098,2099,2101,2103,2105,2107],{"class":489,"line":64},[149,2100,831],{"class":493},[149,2102,105],{"class":497},[149,2104,1512],{"class":493},[149,2106,105],{"class":497},[149,2108,505],{"class":493},[149,2110,2111,2113,2115],{"class":489,"line":751},[149,2112,831],{"class":493},[149,2114,811],{"class":497},[149,2116,505],{"class":493},[149,2118,2119,2121,2123],{"class":489,"line":845},[149,2120,1529],{"class":493},[149,2122,37],{"class":497},[149,2124,505],{"class":493},[149,2126,2127,2129,2131,2133,2135,2137,2139,2141,2143,2145,2147,2149],{"class":489,"line":851},[149,2128,1538],{"class":493},[149,2130,40],{"class":497},[149,2132,1543],{"class":493},[149,2134,14],{"class":497},[149,2136,1548],{"class":702},[149,2138,706],{"class":493},[149,2140,1553],{"class":709},[149,2142,1556],{"class":493},[149,2144,14],{"class":497},[149,2146,1561],{"class":493},[149,2148,40],{"class":497},[149,2150,505],{"class":493},[149,2152,2153,2155,2157,2159,2161,2163,2165,2167,2169,2171,2173,2175],{"class":489,"line":861},[149,2154,1538],{"class":493},[149,2156,40],{"class":497},[149,2158,1543],{"class":493},[149,2160,14],{"class":497},[149,2162,1548],{"class":702},[149,2164,706],{"class":493},[149,2166,1582],{"class":709},[149,2168,1585],{"class":493},[149,2170,14],{"class":497},[149,2172,1561],{"class":493},[149,2174,40],{"class":497},[149,2176,505],{"class":493},[149,2178,2179,2181,2183],{"class":489,"line":877},[149,2180,1598],{"class":493},[149,2182,37],{"class":497},[149,2184,505],{"class":493},[149,2186,2187,2189,2191],{"class":489,"line":883},[149,2188,854],{"class":493},[149,2190,811],{"class":497},[149,2192,505],{"class":493},[149,2194,2195,2197,2199],{"class":489,"line":892},[149,2196,895],{"class":493},[149,2198,811],{"class":497},[149,2200,505],{"class":493},[149,2202,2203,2205,2207],{"class":489,"line":75},[149,2204,494],{"class":493},[149,2206,811],{"class":497},[149,2208,505],{"class":493},[149,2210,2211,2213,2215],{"class":489,"line":1066},[149,2212,831],{"class":493},[149,2214,811],{"class":497},[149,2216,505],{"class":493},[149,2218,2219,2221,2223,2225,2227],{"class":489,"line":1075},[149,2220,1529],{"class":493},[149,2222,112],{"class":497},[149,2224,1643],{"class":493},[149,2226,112],{"class":497},[149,2228,505],{"class":493},[149,2230,2231,2233,2235,2237,2239],{"class":489,"line":1650},[149,2232,1529],{"class":493},[149,2234,10],{"class":497},[149,2236,1657],{"class":493},[149,2238,10],{"class":497},[149,2240,505],{"class":493},[149,2242,2243,2245,2247],{"class":489,"line":1664},[149,2244,854],{"class":493},[149,2246,811],{"class":497},[149,2248,505],{"class":493},[149,2250,2251,2253,2255],{"class":489,"line":1673},[149,2252,895],{"class":493},[149,2254,811],{"class":497},[149,2256,505],{"class":493},[149,2258,2259,2261,2263],{"class":489,"line":1682},[149,2260,494],{"class":493},[149,2262,811],{"class":497},[149,2264,505],{"class":493},[149,2266,2267,2269,2271,2273,2275,2277,2279],{"class":489,"line":1696},[149,2268,831],{"class":493},[149,2270,10],{"class":497},[149,2272,1806],{"class":493},[149,2274,1333],{"class":1809},[149,2276,1812],{"class":493},[149,2278,10],{"class":497},[149,2280,505],{"class":493},[149,2282,2283,2285,2287],{"class":489,"line":1705},[149,2284,895],{"class":493},[149,2286,811],{"class":497},[149,2288,505],{"class":493},[10,2290,2291,2292,2294,2295,2298,2299,2301],{},"Визуально после рендера обе страницы могут выглядеть идентично. Но, как несложно заметить, разметка на сплошных ",[198,2293,1278],{}," менее читаема, и — что важнее — она негативно влияет на SEO и доступность: поисковые роботы и скринридеры теряют возможность понять, где здесь шапка, где навигация, а где основной контент. Подобная практика получила в индустрии полуироничное название «div-ад» (англ. ",[125,2296,2297],{},"div soup",") и считается антипаттерном. Простое правило: если для смыслового блока существует подходящий семантический тег — использовать его, а к ",[198,2300,1278],{}," прибегать там, где нужен именно конструкционный контейнер для целей вёрстки.",[112,2303,2305],{"id":2304},"метаинформация-документа","Метаинформация документа",[117,2307,2309],{"id":2308},"метатеги-управления-рендерингом-и-индексацией","Метатеги управления рендерингом и индексацией",[10,2311,1166,2312,2314],{},[198,2313,1169],{}," помимо подключения ресурсов содержит набор метатегов, передающих браузеру и внешним системам сведения о документе. Среди практически значимых:",[37,2316,2317,2323,2335,2341],{},[40,2318,2319,2322],{},[198,2320,2321],{},"\u003Cmeta name=\"description\" content=\"...\">"," — короткое описание страницы, используемое поисковыми системами в качестве сниппета в результатах поиска. В пределах 150–160 символов;",[40,2324,2325,2328,2329,266,2332,2334],{},[198,2326,2327],{},"\u003Cmeta name=\"robots\" content=\"index, follow\">"," — инструкция поисковым роботам: индексировать ли страницу и переходить ли по ссылкам с неё. Значения ",[198,2330,2331],{},"noindex",[198,2333,370],{}," исключают страницу из индекса или запрещают переход по её ссылкам;",[40,2336,2337,2340],{},[198,2338,2339],{},"\u003Clink rel=\"canonical\" href=\"...\">"," — указание канонического URL страницы. Используется, когда одна и та же страница доступна по нескольким адресам, чтобы поисковые системы не считали их дубликатами;",[40,2342,2343,2346],{},[198,2344,2345],{},"\u003Clink rel=\"icon\" href=\"favicon.svg\">"," — пиктограмма страницы во вкладке браузера, в избранном, в результатах поиска.",[10,2348,2349,2350,2353],{},"Встречающийся в старой разметке ",[198,2351,2352],{},"\u003Cmeta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">"," относился к режимам совместимости Internet Explorer; с выводом IE из поддержки в 2022 году тег стал историческим артефактом и в новой разметке не нужен.",[10,2355,2356,2357,2360],{},"Метатег ",[198,2358,2359],{},"\u003Cmeta name=\"keywords\">"," исторически использовался для перечисления поисковых запросов, по которым автор хотел бы видеть страницу в выдаче. Современные поисковые системы его игнорируют — он остался как памятник эпохе массового SEO-спама.",[117,2362,2364],{"id":2363},"системы-разметки-метаданных","Системы разметки метаданных",[10,2366,2367,2368,475,2370,1219,2372,2374],{},"Помимо базовых метатегов, которые читают сами браузеры и поисковые роботы, существует ряд внешних систем разметки — протоколов и словарей, с помощью которых страница сообщает о себе сторонним сервисам: соцсетям, мессенджерам, агрегаторам, поисковым движкам. Технически все они выражаются через те же ",[198,2369,683],{},[198,2371,687],{},[198,2373,1169],{}," либо через атрибуты прямо на содержательной разметке, но логически это отдельный слой «разметки про разметку».",[10,2376,2377],{},"Задачи, которые решают такие системы, сводятся к двум:",[37,2379,2380,2383],{},[40,2381,2382],{},"сформировать превью при публикации ссылки — карточку с заголовком, описанием и изображением в соцсетях, мессенджерах, поисковых сниппетах (этим занимается протокол Open Graph и родственные ему Twitter Cards);",[40,2384,2385],{},"описать содержимое страницы как структурированные сущности — товар, событие, рецепт, организацию, статью — в формате, который поисковые системы могут использовать для расширенных сниппетов и агрегаций (этим занимаются словарь schema.org и форматы его записи: JSON-LD, Microdata, RDFa).",[112,2387,2389],{"id":2388},"доступность-на-уровне-разметки","Доступность на уровне разметки",[10,2391,2392,2393,2395,2396,2398],{},"Доступность (англ. ",[125,2394,1398],{},", a11y) — свойство веб-страницы быть пригодной к восприятию пользователями с разными возможностями: незрячими и слабовидящими, людьми с моторными или когнитивными нарушениями, пользователями в условиях плохой сети или нестандартного устройства ввода. Практически это означает, что страница должна корректно работать не только при визуальном просмотре мышью, но и при навигации клавиатурой, при озвучивании программой чтения с экрана (англ. ",[125,2397,1402],{},"), при увеличенном масштабе, при контрастной теме. Разработка с учётом доступности — не отдельная опция для узкой аудитории, а часть нормального качества продукта: те же приёмы, которые делают страницу пригодной для скринридера, улучшают её SEO, облегчают автоматическое тестирование и делают интерфейс устойчивее к нестандартным условиям использования.",[10,2400,2401,2402,2405,2406,2409,2410,2413],{},"Международный стандарт доступности — ",[125,2403,2404],{},"Web Content Accessibility Guidelines"," (WCAG), разрабатываемый W3C в рамках инициативы WAI (Web Accessibility Initiative). WCAG определяет четыре базовых принципа — воспринимаемость, управляемость, понятность, надёжность — и формулирует проверяемые критерии соответствия на трёх уровнях: A, AA (целевой для большинства публичных сайтов) и AAA. Дополняет стандарт спецификация WAI-ARIA, описывающая роли (",[198,2407,2408],{},"role","), состояния и свойства (",[198,2411,2412],{},"aria-*","), которыми размечаются кастомные интерактивные виджеты, когда встроенной семантики HTML недостаточно.",[10,2415,2416,2417,1283,2419,2421,2422,2424,2425,2427,2428,2431,2432,2435,2436,2440,2441,2444,2445,266,2448,266,2450,2452],{},"На уровне разметки грамотная доступность держится на нескольких простых подходах: логический порядок элементов в HTML соответствует порядку, в котором контент должен восприниматься (CSS может переупорядочить его визуально, но скринридер читает исходник); заголовки ",[198,2418,474],{},[198,2420,1286],{}," образуют последовательную иерархию и работают для скринридера как навигация; семантические теги используются вместо анонимных ",[198,2423,1278],{}," (см. предыдущий раздел); у каждого ",[198,2426,667],{}," задан осмысленный ",[198,2429,2430],{},"alt"," (пустой ",[198,2433,2434],{},"alt=\"\""," — явный сигнал декоративности, отсутствующий атрибут — ошибка). Действует устойчивая формулировка, известная как ",[2437,2438,2439],"strong",{},"первое правило ARIA",": ",[125,2442,2443],{},"«Не используйте ARIA, если можно обойтись нативным HTML-элементом»",". Нативные ",[198,2446,2447],{},"\u003Cbutton>",[198,2449,563],{},[198,2451,679],{}," из коробки получают правильную семантику, поведение клавиатуры и фокус — ARIA нужен только там, где этих средств недостаточно.",[10,2454,2455],{},"Базовую проверку доступности дают бесплатные инструменты, доступные прямо в браузере: расширение axe DevTools, встроенный в Chrome DevTools аудит Lighthouse, вкладка Accessibility с деревом доступности. Они быстро ловят типовые нарушения, но не заменяют ручной проверки клавиатурой и реальным скринридером, которая остаётся стандартом.",[112,2457,2459],{"id":2458},"итоги-темы","Итоги темы",[10,2461,2462],{},"Веб-страница — это конечный результат цепочки «URL → HTTP-запрос → HTML-документ → рендер браузером». В этой цепочке HTML играет роль базового языка, описывающего структуру и смысл контента, тогда как оформление и поведение возложены на CSS и JavaScript. Современный HTML — это Living Standard, поддерживаемый WHATWG; его развитие синхронизируется с реализациями в основных браузерных движках (Blink, WebKit, Gecko) через инициативы вроде Interop.",[10,2464,2465,2466,266,2468,266,2470,2472,2473,2475,2476,2478],{},"Корректная разметка строится из трёх слоёв: правильная структура документа (DOCTYPE, ",[198,2467,1124],{},[198,2469,1169],{},[198,2471,1214],{},"), осмысленный выбор семантических тегов вместо сплошных ",[198,2474,1278],{}," и согласованная метаинформация. Поверх этой основы накладывается забота о доступности: логический порядок элементов, иерархия заголовков, осмысленные атрибуты ",[198,2477,2430],{},", минимально необходимое использование ARIA. Эти решения принимаются на самом раннем этапе и стоят дёшево, если о них помнить с первой строки разметки, и дорого — если возвращаться к ним постфактум.",[10,2480,2481],{},"В следующей теме мы перейдём к языку CSS и научимся управлять оформлением страницы, сохраняя смысловую структуру, заложенную здесь.",[112,2483,2485],{"id":2484},"литература","Литература",[2487,2488,2491,2495,2499,2503],"ol",{"className":2489},[2490],"references",[40,2492,2494],{"id":2493},"ref-1","Nelson T. H. A File Structure for the Complex, the Changing and the Indeterminate. — Proceedings of the 1965 20th National Conference, 1965, С. 84–100, DOI: 10.1145\u002F800197.806036.",[40,2496,2498],{"id":2497},"ref-2","Berners-Lee T. Information Management: A Proposal. — CERN, 1989, https:\u002F\u002Fwww.w3.org\u002FHistory\u002F1989\u002Fproposal.html.",[40,2500,2502],{"id":2501},"ref-3","Garsiel T., Irish P. How browsers work: Behind the scenes of modern web browsers. — 2011, http:\u002F\u002Ftaligarsiel.com\u002FProjects\u002Fhowbrowserswork1.htm.",[40,2504,2506],{"id":2505},"ref-4","Kosaka M. Inside look at modern web browser. — 2018, https:\u002F\u002Fdeveloper.chrome.com\u002Fblog\u002Finside-browser-part1.",[2508,2509,2510],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":63,"searchDepth":64,"depth":64,"links":2512},[2513,2520,2527,2538,2546,2550,2551,2552],{"id":114,"depth":64,"text":115,"children":2514},[2515,2516,2517,2518,2519],{"id":119,"depth":751,"text":120},{"id":162,"depth":751,"text":163},{"id":219,"depth":751,"text":220},{"id":285,"depth":751,"text":286},{"id":428,"depth":751,"text":429},{"id":456,"depth":64,"text":457,"children":2521},[2522,2523,2524,2525,2526],{"id":460,"depth":751,"text":461},{"id":556,"depth":751,"text":557},{"id":653,"depth":751,"text":654},{"id":780,"depth":751,"text":781},{"id":795,"depth":751,"text":796},{"id":924,"depth":64,"text":925,"children":2528},[2529,2531,2533,2535,2537],{"id":1084,"depth":751,"text":2530},"\u003C!DOCTYPE> и режим стандартов",{"id":1120,"depth":751,"text":2532},"Корневой элемент \u003Chtml>, атрибуты lang и dir",{"id":1165,"depth":751,"text":2534},"Раздел \u003Chead>: кодировка, viewport, заголовок, подключение ресурсов",{"id":1235,"depth":751,"text":2536},"Раздел \u003Cbody>: видимый контент страницы",{"id":1259,"depth":751,"text":1260},{"id":1348,"depth":64,"text":1349,"children":2539},[2540,2541,2543,2545],{"id":1352,"depth":751,"text":1353},{"id":1425,"depth":751,"text":2542},"Секционирующие элементы: header, nav, main, article, section, aside, footer",{"id":1828,"depth":751,"text":2544},"Текстовые и групповые элементы: figure, figcaption, details, summary, dialog",{"id":2073,"depth":751,"text":2074},{"id":2304,"depth":64,"text":2305,"children":2547},[2548,2549],{"id":2308,"depth":751,"text":2309},{"id":2363,"depth":751,"text":2364},{"id":2388,"depth":64,"text":2389},{"id":2458,"depth":64,"text":2459},{"id":2484,"depth":64,"text":2485},{},"\u002Fcourses\u002Faidt-mag-frontend\u002Ftopic-01-content","content",{"title":101,"description":110},"courses\u002Faidt-mag-frontend\u002Ftopic-01-content","topic-01","EFVy4cJTsczWJbICBxXDhbO_4ll9ChAiKAM8rORw3nE",{"id":2561,"title":2562,"body":2563,"course_slug":66,"description":2570,"env_label":68,"env_url":68,"extension":69,"group":68,"is_course_project":71,"is_index":71,"level":68,"meta":6404,"navigation":72,"path":6405,"section":2555,"seo":6406,"stem":6407,"topic_number":64,"topic_slug":6408,"__hash__":6409},"courses\u002Fcourses\u002Faidt-mag-frontend\u002Ftopic-02-content.md","Тема 2. CSS: основы языка, оформление, дизайн-токены, темизация",{"type":7,"value":2564,"toc":6357},[2565,2568,2571,2575,2579,2601,2621,2625,2628,2688,2711,2725,2727,2742,2795,2799,2802,2816,2862,2872,2883,2938,2941,2949,2975,2981,2987,3008,3020,3024,3039,3042,3060,3064,3077,3124,3128,3134,3154,3160,3174,3199,3222,3234,3240,3285,3325,3332,3341,3367,3373,3376,3404,3407,3477,3494,3503,3524,3530,3534,3549,3735,3760,3771,3884,3897,3912,3916,3919,3925,3988,4016,4024,4051,4060,4104,4127,4136,4164,4177,4196,4199,4205,4286,4299,4308,4345,4351,4415,4424,4429,4456,4461,4483,4486,4490,4502,4506,4509,4537,4544,4562,4566,4572,4606,4617,4655,4661,4665,4697,4722,4725,4731,4737,4759,4762,4774,4778,4782,4800,4855,4861,4870,4890,4901,4912,4951,4960,4968,5006,5009,5022,5033,5043,5078,5113,5135,5157,5160,5171,5216,5228,5320,5330,5334,5344,5397,5404,5411,5415,5419,5429,5452,5594,5606,5610,5613,5619,5676,5686,5716,5722,5747,5754,5758,5761,5852,5861,5864,5891,5903,5907,5918,5921,5946,5949,5953,5956,5963,5977,6106,6109,6119,6125,6203,6206,6223,6229,6288,6294,6296,6299,6305,6307,6354],[105,2566,2562],{"id":2567},"тема-2-css-основы-языка-оформление-дизайн-токены-темизация",[10,2569,2570],{},"В прошлой теме мы условились, что HTML описывает структуру и смысл документа, не его внешний вид. Тогда возникает вопрос: чем же управлять оформлением — цветом, шрифтом, отступами, расположением блоков? Ответ — CSS, второй язык клиентской вёрстки. Мы рассмотрим CSS постепенно: от его роли и базового синтаксиса к селекторам и каскаду, затем к блочной модели и единицам измерения, и завершим темой, через которую разработчики управляют визуальной системой современных интерфейсов: дизайн-токенами и темизацией.",[112,2572,2574],{"id":2573},"css-как-язык","CSS как язык",[117,2576,2578],{"id":2577},"назначение-css-отделение-оформления-от-структуры","Назначение CSS: отделение оформления от структуры",[10,2580,2581,2582,2585,2586,2593,2600],{},"Каскадные таблицы стилей (",[125,2583,2584],{},"Cascading Style Sheets",", CSS) — язык, описывающий, как должен отображаться контент, размеченный с помощью HTML ",[141,2587,2589],{"className":2588},[144],[14,2590,2591],{"href":147},[149,2592,151],{},[141,2594,2596],{"className":2595},[144],[14,2597,2598],{"href":180},[149,2599,183],{},". CSS позволяет задавать цвета, шрифты, размеры, отступы, расположение элементов, анимации, реакцию на действия пользователя и адаптацию под размер экрана.",[10,2602,2603,2604,266,2607,266,2610,2613,2614,18],{},"Ключевая идея CSS — разделение содержания и оформления. Один и тот же HTML-документ может выглядеть совершенно по-разному в зависимости от подключённых стилей: на это свойство опирается, например, темизация, печать страницы, адаптация под мобильные устройства и доступность для пользователей с особыми потребностями. Подход «разметка отдельно, стилизация отдельно» сегодня воспринимается как очевидный, но он отнюдь не был исходным состоянием веба — в эпоху HTML 4 повсеместной была практика прямого управления оформлением через атрибуты тегов (",[198,2605,2606],{},"bgcolor",[198,2608,2609],{},"align",[198,2611,2612],{},"font",") и табличную вёрстку. Со временем стало ясно, что такая смесь делает разметку нечитаемой, поддержку — дорогой, а попытки изменить дизайн — болезненными. CSS появился именно как инструмент разделения этих забот ",[141,2615,2617],{"className":2616},[144],[14,2618,2619],{"href":349},[149,2620,352],{},[117,2622,2624],{"id":2623},"синтаксис-правила-селектор-блок-объявлений-свойство-и-значение","Синтаксис правила: селектор, блок объявлений, свойство и значение",[10,2626,2627],{},"CSS работает на основе правил. Каждое правило состоит из селектора и блока объявлений, разделённых фигурными скобками:",[229,2629,2633],{"className":2630,"code":2631,"language":2632,"meta":63,"style":63},"language-css shiki shiki-themes github-light github-dark","p {\n  color: #333;\n  font-size: 16px;\n  line-height: 1.5;\n}\n","css",[198,2634,2635,2642,2655,2671,2683],{"__ignoreMap":63},[149,2636,2637,2639],{"class":489,"line":490},[149,2638,10],{"class":497},[149,2640,2641],{"class":493}," {\n",[149,2643,2644,2647,2649,2652],{"class":489,"line":64},[149,2645,2646],{"class":1809},"  color",[149,2648,2440],{"class":493},[149,2650,2651],{"class":1809},"#333",[149,2653,2654],{"class":493},";\n",[149,2656,2657,2660,2662,2665,2669],{"class":489,"line":751},[149,2658,2659],{"class":1809},"  font-size",[149,2661,2440],{"class":493},[149,2663,2664],{"class":1809},"16",[149,2666,2668],{"class":2667},"szBVR","px",[149,2670,2654],{"class":493},[149,2672,2673,2676,2678,2681],{"class":489,"line":845},[149,2674,2675],{"class":1809},"  line-height",[149,2677,2440],{"class":493},[149,2679,2680],{"class":1809},"1.5",[149,2682,2654],{"class":493},[149,2684,2685],{"class":489,"line":851},[149,2686,2687],{"class":493},"}\n",[10,2689,2690,2691,2693,2694,2696,2697,266,2700,266,2703,2706,2707,2710],{},"Здесь ",[198,2692,10],{}," — селектор, указывающий, к каким HTML-элементам применить правило (в данном случае ко всем ",[198,2695,478],{},"); внутри фигурных скобок размещается блок объявлений; каждое объявление состоит из имени свойства (",[198,2698,2699],{},"color",[198,2701,2702],{},"font-size",[198,2704,2705],{},"line-height","), двоеточия и значения; объявления разделяются точкой с запятой. Пробелы и переносы строк не значимы — приведённый формат принят как соглашение для читаемости, но запись ",[198,2708,2709],{},"p{color:#333;font-size:16px}"," валидна и приведёт к тому же результату.",[10,2712,2713,2714,549,2719,2724],{},"Свойств в CSS — несколько сотен; их полный перечень с правилами применения и значениями приводится в спецификации W3C\u002FWHATWG, а на практике удобнее обращаться к справочникам ",[14,2715,2718],{"href":2716,"rel":2717},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fru\u002Fdocs\u002FWeb\u002FCSS\u002FReference",[370],"MDN",[14,2720,2723],{"href":2721,"rel":2722},"https:\u002F\u002Fdoka.guide\u002Fcss\u002F",[370],"Доке",". Запоминать каждое свойство наизусть не требуется — достаточно понимать систему типов значений (длины, цвета, ключевые слова, функции) и принципы каскада, о которых пойдёт речь ниже.",[117,2726,781],{"id":780},[10,2728,2729,2730,2733,2734,2737,2738,2741],{},"В CSS используется единственный синтаксис комментария — ",[198,2731,2732],{},"\u002F* ... *\u002F",". Однострочной формы вроде ",[198,2735,2736],{},"\u002F\u002F"," (как в JavaScript) в нативном CSS нет; комментарии тоже не вкладываются — первая встреченная пара ",[198,2739,2740],{},"*\u002F"," закрывает текущий комментарий, и всё, что после, читается как обычные правила. Внутри блока объявлений комментарием удобно временно отключать отдельные строки:",[229,2743,2745],{"className":2630,"code":2744,"language":2632,"meta":63,"style":63},".button {\n  background: #06c;\n  \u002F* color: white; *\u002F\n  padding: 8px 16px;\n}\n",[198,2746,2747,2754,2766,2772,2791],{"__ignoreMap":63},[149,2748,2749,2752],{"class":489,"line":490},[149,2750,2751],{"class":702},".button",[149,2753,2641],{"class":493},[149,2755,2756,2759,2761,2764],{"class":489,"line":64},[149,2757,2758],{"class":1809},"  background",[149,2760,2440],{"class":493},[149,2762,2763],{"class":1809},"#06c",[149,2765,2654],{"class":493},[149,2767,2768],{"class":489,"line":751},[149,2769,2771],{"class":2770},"sJ8bj","  \u002F* color: white; *\u002F\n",[149,2773,2774,2777,2779,2782,2784,2787,2789],{"class":489,"line":845},[149,2775,2776],{"class":1809},"  padding",[149,2778,2440],{"class":493},[149,2780,2781],{"class":1809},"8",[149,2783,2668],{"class":2667},[149,2785,2786],{"class":1809}," 16",[149,2788,2668],{"class":2667},[149,2790,2654],{"class":493},[149,2792,2793],{"class":489,"line":851},[149,2794,2687],{"class":493},[117,2796,2798],{"id":2797},"способы-подключения-стилей","Способы подключения стилей",[10,2800,2801],{},"Чтобы CSS-правила начали действовать, их нужно подключить к HTML-документу. Существуют три способа.",[10,2803,2804,2807,2808,2811,2812,1219,2814,2083],{},[2437,2805,2806],{},"Внешний CSS-файл"," — основной и предпочтительный способ. Стили записываются в отдельный файл с расширением ",[198,2809,2810],{},".css"," и подключаются через элемент ",[198,2813,687],{},[198,2815,1169],{},[229,2817,2819],{"className":482,"code":2818,"language":484,"meta":63,"style":63},"\u003Chead>\n  \u003Clink rel=\"stylesheet\" href=\"styles.css\">\n\u003C\u002Fhead>\n",[198,2820,2821,2829,2854],{"__ignoreMap":63},[149,2822,2823,2825,2827],{"class":489,"line":490},[149,2824,494],{"class":493},[149,2826,969],{"class":497},[149,2828,505],{"class":493},[149,2830,2831,2834,2837,2840,2842,2845,2847,2849,2852],{"class":489,"line":64},[149,2832,2833],{"class":493},"  \u003C",[149,2835,2836],{"class":497},"link",[149,2838,2839],{"class":702}," rel",[149,2841,706],{"class":493},[149,2843,2844],{"class":709},"\"stylesheet\"",[149,2846,1548],{"class":702},[149,2848,706],{"class":493},[149,2850,2851],{"class":709},"\"styles.css\"",[149,2853,505],{"class":493},[149,2855,2856,2858,2860],{"class":489,"line":751},[149,2857,895],{"class":493},[149,2859,969],{"class":497},[149,2861,505],{"class":493},[10,2863,2864,2865,2868,2869,2871],{},"Атрибут ",[198,2866,2867],{},"rel=\"stylesheet\""," сообщает браузеру, что подключаемый файл — таблица стилей; в ",[198,2870,610],{}," указывается путь к файлу. Вынесение стилей в отдельный файл даёт два важных преимущества: один и тот же файл стилей можно подключить к нескольким страницам, а браузер кеширует загруженный файл, ускоряя последующие переходы.",[10,2873,2874,2880,2881,2083],{},[2437,2875,2876,2877],{},"Элемент ",[198,2878,2879],{},"\u003Cstyle>"," позволяет встроить стили прямо в HTML-документ, обычно — в ",[198,2882,1169],{},[229,2884,2886],{"className":482,"code":2885,"language":484,"meta":63,"style":63},"\u003Chead>\n  \u003Cstyle>\n    p { color: #333; }\n  \u003C\u002Fstyle>\n\u003C\u002Fhead>\n",[198,2887,2888,2896,2904,2921,2930],{"__ignoreMap":63},[149,2889,2890,2892,2894],{"class":489,"line":490},[149,2891,494],{"class":493},[149,2893,969],{"class":497},[149,2895,505],{"class":493},[149,2897,2898,2900,2902],{"class":489,"line":64},[149,2899,2833],{"class":493},[149,2901,2508],{"class":497},[149,2903,505],{"class":493},[149,2905,2906,2909,2912,2914,2916,2918],{"class":489,"line":751},[149,2907,2908],{"class":497},"    p",[149,2910,2911],{"class":493}," { ",[149,2913,2699],{"class":1809},[149,2915,2440],{"class":493},[149,2917,2651],{"class":1809},[149,2919,2920],{"class":493},"; }\n",[149,2922,2923,2926,2928],{"class":489,"line":845},[149,2924,2925],{"class":493},"  \u003C\u002F",[149,2927,2508],{"class":497},[149,2929,505],{"class":493},[149,2931,2932,2934,2936],{"class":489,"line":851},[149,2933,895],{"class":493},[149,2935,969],{"class":497},[149,2937,505],{"class":493},[10,2939,2940],{},"Такая запись оправдана для критических стилей, которые должны применяться немедленно, до загрузки внешних таблиц, либо для одностраничных документов, у которых нет повторного использования стилей. В обычной практике её избегают: смешение разметки и стилизации затрудняет сопровождение.",[10,2942,2943,2948],{},[2437,2944,2945,2946],{},"Инлайн-атрибут ",[198,2947,2508],{}," позволяет задать стили прямо на элементе:",[229,2950,2952],{"className":482,"code":2951,"language":484,"meta":63,"style":63},"\u003Cp style=\"color: #333; font-size: 16px;\">Абзац с инлайн-стилями.\u003C\u002Fp>\n",[198,2953,2954],{"__ignoreMap":63},[149,2955,2956,2958,2960,2963,2965,2968,2971,2973],{"class":489,"line":490},[149,2957,494],{"class":493},[149,2959,10],{"class":497},[149,2961,2962],{"class":702}," style",[149,2964,706],{"class":493},[149,2966,2967],{"class":709},"\"color: #333; font-size: 16px;\"",[149,2969,2970],{"class":493},">Абзац с инлайн-стилями.\u003C\u002F",[149,2972,10],{"class":497},[149,2974,505],{"class":493},[10,2976,2977,2978,2980],{},"Это самая жёсткая привязка стилизации к разметке: правила нельзя переиспользовать, селекторы вообще не работают, специфичность таких объявлений максимальна. Инлайн-",[198,2979,2508],{}," уместен в редких случаях — например, когда значение свойства вычисляется на лету в JavaScript и применяется к конкретному элементу. В остальных ситуациях разумно держаться внешних стилей.",[10,2982,2983,2984,2083],{},"Помимо этих трёх способов внутри одного CSS-файла можно подключить другой — директивой ",[198,2985,2986],{},"@import",[229,2988,2990],{"className":2630,"code":2989,"language":2632,"meta":63,"style":63},"@import url('typography.css');\n",[198,2991,2992],{"__ignoreMap":63},[149,2993,2994,2996,2999,3002,3005],{"class":489,"line":490},[149,2995,2986],{"class":2667},[149,2997,2998],{"class":1809}," url",[149,3000,3001],{"class":493},"(",[149,3003,3004],{"class":709},"'typography.css'",[149,3006,3007],{"class":493},");\n",[10,3009,3010,3011,3013,3014,3016,3017,3019],{},"Так удобно разбивать большую стилевую базу на тематические файлы. На практике, однако, чаще подключают каждый файл собственным ",[198,3012,687],{},"-ом: браузер загружает их параллельно, тогда как ",[198,3015,2986],{},"-ы выстраиваются в последовательную цепочку и задерживают отрисовку. Поэтому ",[198,3018,2986],{}," чаще встречается для специальных случаев — например, для подключения шрифтов с CDN.",[117,3021,3023],{"id":3022},"браузерные-стили-по-умолчанию-user-agent-stylesheet-и-подходы-к-их-сбросу","Браузерные стили по умолчанию (user-agent stylesheet) и подходы к их сбросу",[10,3025,3026,3027,3029,3030,3032,3033,3035,3036,3038],{},"Браузерные стили по умолчанию (",[125,3028,541],{},") упоминались в теме 1: именно они объясняют, почему даже без авторских стилей ",[198,3031,474],{}," крупнее ",[198,3034,478],{},", ссылки ",[198,3037,563],{}," синие и подчёркнуты, а кнопки имеют рамку. Это встроенный в каждый браузер минимальный набор правил, обеспечивающий читаемость немаркированного документа.",[10,3040,3041],{},"Проблема в том, что user-agent stylesheet несколько различается между браузерами. Это означает: даже одинаковый HTML без собственных стилей может выглядеть в Chrome, Safari и Firefox чуть по-разному — разные отступы у списков, разный размер кнопок, разные рамки полей ввода. Для проектов, которым важен предсказуемый и одинаковый внешний вид, это нежелательно.",[10,3043,3044,3045,475,3048,3051,3052,3059],{},"Исторически сложились два подхода к выравниванию стартовой точки: ",[2437,3046,3047],{},"reset",[2437,3049,3050],{},"normalize"," ",[141,3053,3055],{"className":3054},[144],[14,3056,3057],{"href":359},[149,3058,362],{},". Reset обнуляет почти все встроенные стили: убирает отступы, размеры шрифтов, оформление списков, превращая разметку в визуально нейтральный полуфабрикат, поверх которого автор пишет стилизацию с нуля. Normalize поступает мягче: оставляет осмысленные браузерные стили и лишь сглаживает различия между браузерами там, где они нелогичны или нарушают консистентность.",[112,3061,3063],{"id":3062},"селекторы","Селекторы",[10,3065,3066,3067,3076],{},"CSS-селекторы — выражения, определяющие, к каким элементам страницы применить блок объявлений ",[141,3068,3070],{"className":3069},[144],[14,3071,3073],{"href":3072},"#ref-5",[149,3074,3075],{},"5",". Это, пожалуй, самая богатая часть языка: за тридцать лет в CSS накопилось несколько десятков видов селекторов и комбинаторов. Рассмотрим их по группам — от базовых к продвинутым.",[10,3078,3079,3080,3083,3084,3087,3088,3090,3091,3093,3094,3097,3098,3090,3100,3093,3102,3105,3106,3108,3109,3112,3113,3115,3116,3119,3120,3123],{},"Прежде чем переходить к самим селекторам, договоримся о терминологии родственных отношений между элементами. HTML-документ образует иерархию вложенных элементов; в этой иерархии любые два элемента находятся в одном из таких отношений. Если элемент ",[198,3081,3082],{},"B"," непосредственно вложен в элемент ",[198,3085,3086],{},"A",", то ",[198,3089,3086],{}," для ",[198,3092,3082],{}," — ",[2437,3095,3096],{},"родительский"," элемент, а ",[198,3099,3082],{},[198,3101,3086],{},[2437,3103,3104],{},"дочерний"," элемент. Все элементы, лежащие внутри ",[198,3107,3086],{}," на любой глубине вложенности, — его ",[2437,3110,3111],{},"элементы-потомки","; сам ",[198,3114,3086],{}," для них — ",[2437,3117,3118],{},"элемент-предок",". Элементы, имеющие общий родительский элемент, называются ",[2437,3121,3122],{},"соседними",". На этих четырёх понятиях держится почти весь язык селекторов.",[117,3125,3127],{"id":3126},"селекторы-по-тегу-классу-идентификатору-атрибуту","Селекторы по тегу, классу, идентификатору, атрибуту",[10,3129,3130,3133],{},[2437,3131,3132],{},"Селектор по тегу"," применяет правило ко всем элементам определённого типа:",[229,3135,3137],{"className":2630,"code":3136,"language":2632,"meta":63,"style":63},"p { color: blue; }\n",[198,3138,3139],{"__ignoreMap":63},[149,3140,3141,3143,3145,3147,3149,3152],{"class":489,"line":490},[149,3142,10],{"class":497},[149,3144,2911],{"class":493},[149,3146,2699],{"class":1809},[149,3148,2440],{"class":493},[149,3150,3151],{"class":1809},"blue",[149,3153,2920],{"class":493},[10,3155,3156,3157,3159],{},"Это правило окрасит в синий все ",[198,3158,478],{}," в документе. Селекторы по тегу удобны для базовой типографики и сброса браузерных стилей, но в большинстве компонентных интерфейсов используются вместе с другими видами селекторов, чтобы избежать слишком общего охвата.",[10,3161,3162,3165,3166,3169,3170,3173],{},[2437,3163,3164],{},"Селектор по идентификатору"," начинается с символа ",[198,3167,3168],{},"#"," и выбирает элемент, у которого атрибут ",[198,3171,3172],{},"id"," совпадает с указанным значением:",[229,3175,3177],{"className":482,"code":3176,"language":484,"meta":63,"style":63},"\u003Cp id=\"lead\">Лид-абзац статьи.\u003C\u002Fp>\n",[198,3178,3179],{"__ignoreMap":63},[149,3180,3181,3183,3185,3187,3189,3192,3195,3197],{"class":489,"line":490},[149,3182,494],{"class":493},[149,3184,10],{"class":497},[149,3186,814],{"class":702},[149,3188,706],{"class":493},[149,3190,3191],{"class":709},"\"lead\"",[149,3193,3194],{"class":493},">Лид-абзац статьи.\u003C\u002F",[149,3196,10],{"class":497},[149,3198,505],{"class":493},[229,3200,3202],{"className":2630,"code":3201,"language":2632,"meta":63,"style":63},"#lead { font-size: 24px; }\n",[198,3203,3204],{"__ignoreMap":63},[149,3205,3206,3209,3211,3213,3215,3218,3220],{"class":489,"line":490},[149,3207,3208],{"class":702},"#lead",[149,3210,2911],{"class":493},[149,3212,2702],{"class":1809},[149,3214,2440],{"class":493},[149,3216,3217],{"class":1809},"24",[149,3219,2668],{"class":2667},[149,3221,2920],{"class":493},[10,3223,3224,3225,3227,3228,3230,3231,18],{},"В рамках одного HTML-документа значение ",[198,3226,3172],{}," должно быть уникальным — это требование стандарта HTML, а не CSS. На практике id-селекторы используются редко: они сильнее по специфичности (см. ниже), плохо переиспользуются и затрудняют сопровождение. Большинство современных проектов держат стилизацию на классах, оставляя ",[198,3229,3172],{}," за якорными ссылками и привязками ",[198,3232,3233],{},"\u003Clabel for>",[10,3235,3236,3239],{},[2437,3237,3238],{},"Селектор по классу"," начинается с точки и выбирает все элементы с указанным классом:",[229,3241,3243],{"className":482,"code":3242,"language":484,"meta":63,"style":63},"\u003Cp class=\"callout\">Важное замечание.\u003C\u002Fp>\n\u003Cp class=\"callout\">Ещё одно.\u003C\u002Fp>\n",[198,3244,3245,3266],{"__ignoreMap":63},[149,3246,3247,3249,3251,3254,3256,3259,3262,3264],{"class":489,"line":490},[149,3248,494],{"class":493},[149,3250,10],{"class":497},[149,3252,3253],{"class":702}," class",[149,3255,706],{"class":493},[149,3257,3258],{"class":709},"\"callout\"",[149,3260,3261],{"class":493},">Важное замечание.\u003C\u002F",[149,3263,10],{"class":497},[149,3265,505],{"class":493},[149,3267,3268,3270,3272,3274,3276,3278,3281,3283],{"class":489,"line":64},[149,3269,494],{"class":493},[149,3271,10],{"class":497},[149,3273,3253],{"class":702},[149,3275,706],{"class":493},[149,3277,3258],{"class":709},[149,3279,3280],{"class":493},">Ещё одно.\u003C\u002F",[149,3282,10],{"class":497},[149,3284,505],{"class":493},[229,3286,3288],{"className":2630,"code":3287,"language":2632,"meta":63,"style":63},".callout {\n  background: #fffbe6;\n  padding: 12px;\n}\n",[198,3289,3290,3297,3308,3321],{"__ignoreMap":63},[149,3291,3292,3295],{"class":489,"line":490},[149,3293,3294],{"class":702},".callout",[149,3296,2641],{"class":493},[149,3298,3299,3301,3303,3306],{"class":489,"line":64},[149,3300,2758],{"class":1809},[149,3302,2440],{"class":493},[149,3304,3305],{"class":1809},"#fffbe6",[149,3307,2654],{"class":493},[149,3309,3310,3312,3314,3317,3319],{"class":489,"line":751},[149,3311,2776],{"class":1809},[149,3313,2440],{"class":493},[149,3315,3316],{"class":1809},"12",[149,3318,2668],{"class":2667},[149,3320,2654],{"class":493},[149,3322,3323],{"class":489,"line":845},[149,3324,2687],{"class":493},[10,3326,3327,3328,3331],{},"Класс — основной механизм навешивания стилей в современной разработке. У одного элемента может быть несколько классов через пробел (",[198,3329,3330],{},"class=\"button primary\"","); один класс может применяться к любому количеству элементов.",[10,3333,3334,3337,3338,2083],{},[2437,3335,3336],{},"Селектор по атрибуту"," позволяет выбирать элементы по наличию указанного HTML-атрибута или по его значению. Базовая форма — ",[198,3339,3340],{},"[имя]",[229,3342,3344],{"className":2630,"code":3343,"language":2632,"meta":63,"style":63},"[disabled] { opacity: 0.5; }\n",[198,3345,3346],{"__ignoreMap":63},[149,3347,3348,3351,3354,3357,3360,3362,3365],{"class":489,"line":490},[149,3349,3350],{"class":493},"[",[149,3352,3353],{"class":702},"disabled",[149,3355,3356],{"class":493},"] { ",[149,3358,3359],{"class":1809},"opacity",[149,3361,2440],{"class":493},[149,3363,3364],{"class":1809},"0.5",[149,3366,2920],{"class":493},[10,3368,3369,3370,3372],{},"Это правило подействует на любой элемент, у которого в разметке есть атрибут ",[198,3371,3353],{},", независимо от его значения.",[10,3374,3375],{},"Если нужно проверить и значение, добавляется оператор сравнения. Простейший — точное равенство:",[229,3377,3379],{"className":2630,"code":3378,"language":2632,"meta":63,"style":63},"[type=\"submit\"] { background: #06c; }\n",[198,3380,3381],{"__ignoreMap":63},[149,3382,3383,3385,3388,3390,3393,3395,3398,3400,3402],{"class":489,"line":490},[149,3384,3350],{"class":493},[149,3386,3387],{"class":702},"type",[149,3389,706],{"class":2667},[149,3391,3392],{"class":709},"\"submit\"",[149,3394,3356],{"class":493},[149,3396,3397],{"class":1809},"background",[149,3399,2440],{"class":493},[149,3401,2763],{"class":1809},[149,3403,2920],{"class":493},[10,3405,3406],{},"Помимо точного равенства CSS поддерживает несколько операторов для частичного сопоставления значения:",[37,3408,3409,3419,3428,3437,3455],{},[40,3410,3411,3414,3415,3418],{},[198,3412,3413],{},"[href^=\"https:\u002F\u002F\"]"," — значение ",[2437,3416,3417],{},"начинается"," с указанной строки;",[40,3420,3421,3414,3424,3427],{},[198,3422,3423],{},"[src$=\".jpg\"]",[2437,3425,3426],{},"заканчивается"," указанной строкой;",[40,3429,3430,3414,3433,3436],{},[198,3431,3432],{},"[title*=\"важно\"]",[2437,3434,3435],{},"содержит"," указанную подстроку;",[40,3438,3439,3442,3443,3051,3446,3449,3450,266,3453,591],{},[198,3440,3441],{},"[class~=\"highlight\"]"," — в значении есть ",[2437,3444,3445],{},"слово",[198,3447,3448],{},"highlight"," целиком (для атрибутов, хранящих список слов через пробел: ",[198,3451,3452],{},"class",[198,3454,637],{},[40,3456,3457,3460,3461,3464,3465,3468,3469,266,3471,266,3474,542],{},[198,3458,3459],{},"[lang|=\"en\"]"," — значение равно ",[198,3462,3463],{},"en"," либо начинается с ",[198,3466,3467],{},"en-"," (формат языковых кодов: ",[198,3470,3463],{},[198,3472,3473],{},"en-US",[198,3475,3476],{},"en-GB",[10,3478,3479,3480,266,3483,3486,3487,3489,3490,3493],{},"Атрибутные селекторы особенно полезны при стилизации форм (",[198,3481,3482],{},"[type=\"email\"]",[198,3484,3485],{},"[required]","), внешних ссылок (",[198,3488,3413],{},"), элементов с состоянием (",[198,3491,3492],{},"[aria-pressed=\"true\"]",") — везде, где состояние уже выражено в разметке через атрибут и заводить под него отдельный класс нерационально.",[10,3495,3496,3051,3499,3502],{},[2437,3497,3498],{},"Универсальный селектор",[198,3500,3501],{},"*"," соответствует любому элементу:",[229,3504,3506],{"className":2630,"code":3505,"language":2632,"meta":63,"style":63},"* { box-sizing: border-box; }\n",[198,3507,3508],{"__ignoreMap":63},[149,3509,3510,3512,3514,3517,3519,3522],{"class":489,"line":490},[149,3511,3501],{"class":497},[149,3513,2911],{"class":493},[149,3515,3516],{"class":1809},"box-sizing",[149,3518,2440],{"class":493},[149,3520,3521],{"class":1809},"border-box",[149,3523,2920],{"class":493},[10,3525,3526,3527,3529],{},"Универсальный селектор уместен в стартовых установках вроде сброса ",[198,3528,3516],{}," (см. ниже), но в прикладной стилизации его применение лучше ограничить — массовое применение правил ко всем элементам страницы может незаметно влиять на производительность и приводить к нежелательным побочным эффектам.",[117,3531,3533],{"id":3532},"псевдоклассы-и-псевдоэлементы","Псевдоклассы и псевдоэлементы",[10,3535,3536,3537,3540,3541,3544,3545,3548],{},"Все рассмотренные выше селекторы опираются только на то, что прямо записано в разметке: имя тега, класс, идентификатор, значение атрибута. Но у элемента бывают признаки, которых в HTML нет: ",[2437,3538,3539],{},"динамические состояния"," (наведён курсором, получил фокус, заблокирован, отмечен) и ",[2437,3542,3543],{},"позиционные характеристики",", не выраженные атрибутами («первый дочерний среди соседей», «каждый чётный»). Чтобы выбирать элементы по таким признакам, в CSS введены ",[2437,3546,3547],{},"псевдоклассы",". Имя псевдокласса записывается после селектора через одно двоеточие — как будто к элементу присоединили дополнительный класс. Отсюда и приставка «псевдо»: в разметке этого «класса» нет, но селектор работает так, словно он там есть.",[229,3550,3552],{"className":2630,"code":3551,"language":2632,"meta":63,"style":63},"a:hover { text-decoration: underline; }     \u002F* курсор над элементом *\u002F\na:focus { outline: 2px solid #06c; }      \u002F* элемент получил фокус *\u002F\ninput:checked + label { font-weight: 600; } \u002F* чекбокс отмечен *\u002F\ninput:disabled { opacity: 0.5; }            \u002F* элемент заблокирован *\u002F\n\nli:first-child { margin-top: 0; }             \u002F* первый дочерний *\u002F\nli:last-child { margin-bottom: 0; }           \u002F* последний дочерний *\u002F\nli:nth-child(odd) { background: #f5f5f5; }  \u002F* нечётные дочерние *\u002F\n",[198,3553,3554,3577,3607,3636,3657,3662,3685,3707],{"__ignoreMap":63},[149,3555,3556,3558,3561,3563,3566,3568,3571,3574],{"class":489,"line":490},[149,3557,14],{"class":497},[149,3559,3560],{"class":702},":hover",[149,3562,2911],{"class":493},[149,3564,3565],{"class":1809},"text-decoration",[149,3567,2440],{"class":493},[149,3569,3570],{"class":1809},"underline",[149,3572,3573],{"class":493},"; }     ",[149,3575,3576],{"class":2770},"\u002F* курсор над элементом *\u002F\n",[149,3578,3579,3581,3584,3586,3589,3591,3593,3595,3598,3601,3604],{"class":489,"line":64},[149,3580,14],{"class":497},[149,3582,3583],{"class":702},":focus",[149,3585,2911],{"class":493},[149,3587,3588],{"class":1809},"outline",[149,3590,2440],{"class":493},[149,3592,183],{"class":1809},[149,3594,2668],{"class":2667},[149,3596,3597],{"class":1809}," solid",[149,3599,3600],{"class":1809}," #06c",[149,3602,3603],{"class":493},"; }      ",[149,3605,3606],{"class":2770},"\u002F* элемент получил фокус *\u002F\n",[149,3608,3609,3611,3614,3617,3620,3622,3625,3627,3630,3633],{"class":489,"line":751},[149,3610,727],{"class":497},[149,3612,3613],{"class":702},":checked",[149,3615,3616],{"class":2667}," +",[149,3618,3619],{"class":497}," label",[149,3621,2911],{"class":493},[149,3623,3624],{"class":1809},"font-weight",[149,3626,2440],{"class":493},[149,3628,3629],{"class":1809},"600",[149,3631,3632],{"class":493},"; } ",[149,3634,3635],{"class":2770},"\u002F* чекбокс отмечен *\u002F\n",[149,3637,3638,3640,3643,3645,3647,3649,3651,3654],{"class":489,"line":845},[149,3639,727],{"class":497},[149,3641,3642],{"class":702},":disabled",[149,3644,2911],{"class":493},[149,3646,3359],{"class":1809},[149,3648,2440],{"class":493},[149,3650,3364],{"class":1809},[149,3652,3653],{"class":493},"; }            ",[149,3655,3656],{"class":2770},"\u002F* элемент заблокирован *\u002F\n",[149,3658,3659],{"class":489,"line":851},[149,3660,3661],{"emptyLinePlaceholder":72},"\n",[149,3663,3664,3666,3669,3671,3674,3676,3679,3682],{"class":489,"line":861},[149,3665,40],{"class":497},[149,3667,3668],{"class":702},":first-child",[149,3670,2911],{"class":493},[149,3672,3673],{"class":1809},"margin-top",[149,3675,2440],{"class":493},[149,3677,3678],{"class":1809},"0",[149,3680,3681],{"class":493},"; }             ",[149,3683,3684],{"class":2770},"\u002F* первый дочерний *\u002F\n",[149,3686,3687,3689,3692,3694,3697,3699,3701,3704],{"class":489,"line":877},[149,3688,40],{"class":497},[149,3690,3691],{"class":702},":last-child",[149,3693,2911],{"class":493},[149,3695,3696],{"class":1809},"margin-bottom",[149,3698,2440],{"class":493},[149,3700,3678],{"class":1809},[149,3702,3703],{"class":493},"; }           ",[149,3705,3706],{"class":2770},"\u002F* последний дочерний *\u002F\n",[149,3708,3709,3711,3714,3716,3719,3722,3724,3726,3729,3732],{"class":489,"line":883},[149,3710,40],{"class":497},[149,3712,3713],{"class":702},":nth-child",[149,3715,3001],{"class":493},[149,3717,3718],{"class":1809},"odd",[149,3720,3721],{"class":493},") { ",[149,3723,3397],{"class":1809},[149,3725,2440],{"class":493},[149,3727,3728],{"class":1809},"#f5f5f5",[149,3730,3731],{"class":493},"; }  ",[149,3733,3734],{"class":2770},"\u002F* нечётные дочерние *\u002F\n",[10,3736,3737,3738,266,3740,266,3742,266,3745,266,3747,3749,3750,266,3752,266,3754,266,3756,3759],{},"Псевдоклассы состояния (",[198,3739,3560],{},[198,3741,3583],{},[198,3743,3744],{},":active",[198,3746,3613],{},[198,3748,3642],{},") — основа интерактивности на уровне CSS: огромное количество поведений интерфейса описывается с их помощью. Структурные псевдоклассы (",[198,3751,3668],{},[198,3753,3691],{},[198,3755,3713],{},[198,3757,3758],{},":empty",") выбирают элементы по их положению в иерархии разметки и количеству соседних элементов.",[10,3761,3762,3763,3766,3767,3770],{},"Если псевдокласс — это виртуальный признак на уже существующем элементе, то ",[2437,3764,3765],{},"псевдоэлемент"," — это виртуальный ",[125,3768,3769],{},"элемент",", которого в разметке вовсе нет, но CSS позволяет его адресовать и стилизовать. К таким «несуществующим» частям относятся первая строка абзаца, первая буква, выделенный пользователем фрагмент текста, а также искусственно вставленное содержимое до или после элемента. Имя псевдоэлемента пишется через два двоеточия — этим он синтаксически отличается от псевдокласса:",[229,3772,3774],{"className":2630,"code":3773,"language":2632,"meta":63,"style":63},"p::first-line { font-weight: 600; }     \u002F* первая строка абзаца *\u002F\np::first-letter { font-size: 200%; }    \u002F* буквица *\u002F\np::selection { background: #ffe066; } \u002F* выделенный текст *\u002F\n\n.quote::before { content: \"« \"; } \u002F* содержимое перед элементом *\u002F\n.quote::after { content: \" »\"; }  \u002F* содержимое после *\u002F\n",[198,3775,3776,3796,3821,3842,3846,3865],{"__ignoreMap":63},[149,3777,3778,3780,3783,3785,3787,3789,3791,3793],{"class":489,"line":490},[149,3779,10],{"class":497},[149,3781,3782],{"class":702},"::first-line",[149,3784,2911],{"class":493},[149,3786,3624],{"class":1809},[149,3788,2440],{"class":493},[149,3790,3629],{"class":1809},[149,3792,3573],{"class":493},[149,3794,3795],{"class":2770},"\u002F* первая строка абзаца *\u002F\n",[149,3797,3798,3800,3803,3805,3807,3809,3812,3815,3818],{"class":489,"line":64},[149,3799,10],{"class":497},[149,3801,3802],{"class":702},"::first-letter",[149,3804,2911],{"class":493},[149,3806,2702],{"class":1809},[149,3808,2440],{"class":493},[149,3810,3811],{"class":1809},"200",[149,3813,3814],{"class":2667},"%",[149,3816,3817],{"class":493},"; }    ",[149,3819,3820],{"class":2770},"\u002F* буквица *\u002F\n",[149,3822,3823,3825,3828,3830,3832,3834,3837,3839],{"class":489,"line":751},[149,3824,10],{"class":497},[149,3826,3827],{"class":702},"::selection",[149,3829,2911],{"class":493},[149,3831,3397],{"class":1809},[149,3833,2440],{"class":493},[149,3835,3836],{"class":1809},"#ffe066",[149,3838,3632],{"class":493},[149,3840,3841],{"class":2770},"\u002F* выделенный текст *\u002F\n",[149,3843,3844],{"class":489,"line":845},[149,3845,3661],{"emptyLinePlaceholder":72},[149,3847,3848,3851,3853,3855,3857,3860,3862],{"class":489,"line":851},[149,3849,3850],{"class":702},".quote::before",[149,3852,2911],{"class":493},[149,3854,2555],{"class":1809},[149,3856,2440],{"class":493},[149,3858,3859],{"class":709},"\"« \"",[149,3861,3632],{"class":493},[149,3863,3864],{"class":2770},"\u002F* содержимое перед элементом *\u002F\n",[149,3866,3867,3870,3872,3874,3876,3879,3881],{"class":489,"line":861},[149,3868,3869],{"class":702},".quote::after",[149,3871,2911],{"class":493},[149,3873,2555],{"class":1809},[149,3875,2440],{"class":493},[149,3877,3878],{"class":709},"\" »\"",[149,3880,3731],{"class":493},[149,3882,3883],{"class":2770},"\u002F* содержимое после *\u002F\n",[10,3885,3886,3887,475,3890,3893,3894,3896],{},"Особо стоит выделить ",[198,3888,3889],{},"::before",[198,3891,3892],{},"::after"," со свойством ",[198,3895,2555],{}," — они генерируют псевдоузлы перед и после содержимого элемента и широко используются для декоративных элементов, кавычек, иконок, маркеров списков, разделителей. Эти псевдоузлы не присутствуют в HTML, недоступны JavaScript-скриптам и в большинстве случаев не воспринимаются скринридерами как контент — что и удобно, когда мы добавляем чисто декоративные детали.",[10,3898,3899,3900,266,3903,3906,3907,475,3909,3911],{},"Исторически псевдоэлементы записывались с одним двоеточием, как и псевдоклассы (",[198,3901,3902],{},":before",[198,3904,3905],{},":after","), и старая запись по сей день поддерживается ради совместимости — но в новом коде следует использовать ",[198,3908,3889],{},[198,3910,3892],{},", чтобы синтаксически отличать псевдоэлементы от псевдоклассов.",[117,3913,3915],{"id":3914},"комбинаторы-потомки-дочерние-соседние","Комбинаторы: потомки, дочерние, соседние",[10,3917,3918],{},"Комбинаторы выражают отношения между элементами в дереве документа. Их четыре.",[10,3920,3921,3924],{},[2437,3922,3923],{},"Потомковый комбинатор"," (пробел) выбирает все элементы, вложенные в указанный родительский элемент на любом уровне:",[229,3926,3928],{"className":482,"code":3927,"language":484,"meta":63,"style":63},"\u003Cdiv>\n  \u003Cp>Прямой потомок div.\u003C\u002Fp>\n  \u003Cspan>\n    \u003Cp>Потомок div через span.\u003C\u002Fp>\n  \u003C\u002Fspan>\n\u003C\u002Fdiv>\n",[198,3929,3930,3938,3951,3959,3972,3980],{"__ignoreMap":63},[149,3931,3932,3934,3936],{"class":489,"line":490},[149,3933,494],{"class":493},[149,3935,811],{"class":497},[149,3937,505],{"class":493},[149,3939,3940,3942,3944,3947,3949],{"class":489,"line":64},[149,3941,2833],{"class":493},[149,3943,10],{"class":497},[149,3945,3946],{"class":493},">Прямой потомок div.\u003C\u002F",[149,3948,10],{"class":497},[149,3950,505],{"class":493},[149,3952,3953,3955,3957],{"class":489,"line":751},[149,3954,2833],{"class":493},[149,3956,149],{"class":497},[149,3958,505],{"class":493},[149,3960,3961,3963,3965,3968,3970],{"class":489,"line":845},[149,3962,831],{"class":493},[149,3964,10],{"class":497},[149,3966,3967],{"class":493},">Потомок div через span.\u003C\u002F",[149,3969,10],{"class":497},[149,3971,505],{"class":493},[149,3973,3974,3976,3978],{"class":489,"line":851},[149,3975,2925],{"class":493},[149,3977,149],{"class":497},[149,3979,505],{"class":493},[149,3981,3982,3984,3986],{"class":489,"line":861},[149,3983,895],{"class":493},[149,3985,811],{"class":497},[149,3987,505],{"class":493},[229,3989,3991],{"className":2630,"code":3990,"language":2632,"meta":63,"style":63},"div p { font-size: 18px; }  \u002F* оба \u003Cp> получат правило *\u002F\n",[198,3992,3993],{"__ignoreMap":63},[149,3994,3995,3997,4000,4002,4004,4006,4009,4011,4013],{"class":489,"line":490},[149,3996,811],{"class":497},[149,3998,3999],{"class":497}," p",[149,4001,2911],{"class":493},[149,4003,2702],{"class":1809},[149,4005,2440],{"class":493},[149,4007,4008],{"class":1809},"18",[149,4010,2668],{"class":2667},[149,4012,3731],{"class":493},[149,4014,4015],{"class":2770},"\u002F* оба \u003Cp> получат правило *\u002F\n",[10,4017,4018,1093,4021,4023],{},[2437,4019,4020],{},"Дочерний комбинатор",[198,4022,1806],{},") выбирает только прямых потомков:",[229,4025,4027],{"className":2630,"code":4026,"language":2632,"meta":63,"style":63},"div > p { color: blue; }    \u002F* только первый \u003Cp>, второй нет *\u002F\n",[198,4028,4029],{"__ignoreMap":63},[149,4030,4031,4033,4036,4038,4040,4042,4044,4046,4048],{"class":489,"line":490},[149,4032,811],{"class":497},[149,4034,4035],{"class":2667}," >",[149,4037,3999],{"class":497},[149,4039,2911],{"class":493},[149,4041,2699],{"class":1809},[149,4043,2440],{"class":493},[149,4045,3151],{"class":1809},[149,4047,3817],{"class":493},[149,4049,4050],{"class":2770},"\u002F* только первый \u003Cp>, второй нет *\u002F\n",[10,4052,4053,1093,4056,4059],{},[2437,4054,4055],{},"Смежный комбинатор",[198,4057,4058],{},"+",") выбирает элемент, идущий непосредственно после указанного, на том же уровне вложенности:",[229,4061,4063],{"className":482,"code":4062,"language":484,"meta":63,"style":63},"\u003Ch2>Заголовок\u003C\u002Fh2>\n\u003Cp>Этот абзац получит margin-top: 0.\u003C\u002Fp>\n\u003Cp>А этот нет — он не следует сразу за h2.\u003C\u002Fp>\n",[198,4064,4065,4078,4091],{"__ignoreMap":63},[149,4066,4067,4069,4071,4074,4076],{"class":489,"line":490},[149,4068,494],{"class":493},[149,4070,112],{"class":497},[149,4072,4073],{"class":493},">Заголовок\u003C\u002F",[149,4075,112],{"class":497},[149,4077,505],{"class":493},[149,4079,4080,4082,4084,4087,4089],{"class":489,"line":64},[149,4081,494],{"class":493},[149,4083,10],{"class":497},[149,4085,4086],{"class":493},">Этот абзац получит margin-top: 0.\u003C\u002F",[149,4088,10],{"class":497},[149,4090,505],{"class":493},[149,4092,4093,4095,4097,4100,4102],{"class":489,"line":751},[149,4094,494],{"class":493},[149,4096,10],{"class":497},[149,4098,4099],{"class":493},">А этот нет — он не следует сразу за h2.\u003C\u002F",[149,4101,10],{"class":497},[149,4103,505],{"class":493},[229,4105,4107],{"className":2630,"code":4106,"language":2632,"meta":63,"style":63},"h2 + p { margin-top: 0; }\n",[198,4108,4109],{"__ignoreMap":63},[149,4110,4111,4113,4115,4117,4119,4121,4123,4125],{"class":489,"line":490},[149,4112,112],{"class":497},[149,4114,3616],{"class":2667},[149,4116,3999],{"class":497},[149,4118,2911],{"class":493},[149,4120,3673],{"class":1809},[149,4122,2440],{"class":493},[149,4124,3678],{"class":1809},[149,4126,2920],{"class":493},[10,4128,4129,1093,4132,4135],{},[2437,4130,4131],{},"Общий соседний комбинатор",[198,4133,4134],{},"~",") выбирает все элементы, идущие после указанного на том же уровне:",[229,4137,4139],{"className":2630,"code":4138,"language":2632,"meta":63,"style":63},"h2 ~ p { color: gray; }  \u002F* все \u003Cp>, идущие после h2, серые *\u002F\n",[198,4140,4141],{"__ignoreMap":63},[149,4142,4143,4145,4148,4150,4152,4154,4156,4159,4161],{"class":489,"line":490},[149,4144,112],{"class":497},[149,4146,4147],{"class":2667}," ~",[149,4149,3999],{"class":497},[149,4151,2911],{"class":493},[149,4153,2699],{"class":1809},[149,4155,2440],{"class":493},[149,4157,4158],{"class":1809},"gray",[149,4160,3731],{"class":493},[149,4162,4163],{"class":2770},"\u002F* все \u003Cp>, идущие после h2, серые *\u002F\n",[10,4165,4166,4167,4170,4171,4173,4174,4176],{},"Один селектор может объединять несколько комбинаторов в цепочку: ",[198,4168,4169],{},"nav ul > li:first-child a"," — все ссылки внутри первого пункта списка, который является прямым потомком ",[198,4172,1365],{}," внутри ",[198,4175,1372],{},". Длинные цепочки селекторов работают, но их сложно читать и поддерживать; в современной практике их обычно удерживают на двух-трёх уровнях, опираясь на классы.",[117,4178,4180,4181,266,4184,266,4187,266,4190,266,4193],{"id":4179},"современные-псевдоклассы-is-where-has-focus-visible-focus-within","Современные псевдоклассы: ",[198,4182,4183],{},":is",[198,4185,4186],{},":where",[198,4188,4189],{},":has",[198,4191,4192],{},":focus-visible",[198,4194,4195],{},":focus-within",[10,4197,4198],{},"За последние годы CSS пополнился несколькими функциональными псевдоклассами, заметно меняющими привычные приёмы.",[10,4200,4201,4204],{},[198,4202,4203],{},":is(...)"," принимает список селекторов и выбирает элементы, подходящие хотя бы под один из них. Это сокращает повторение:",[229,4206,4208],{"className":2630,"code":4207,"language":2632,"meta":63,"style":63},"\u002F* было *\u002F\nheader h1, main h1, aside h1 { font-family: serif; }\n\n\u002F* стало *\u002F\n:is(header, main, aside) h1 { font-family: serif; }\n",[198,4209,4210,4215,4246,4250,4255],{"__ignoreMap":63},[149,4211,4212],{"class":489,"line":490},[149,4213,4214],{"class":2770},"\u002F* было *\u002F\n",[149,4216,4217,4219,4222,4224,4226,4228,4230,4232,4234,4236,4239,4241,4244],{"class":489,"line":64},[149,4218,1429],{"class":497},[149,4220,4221],{"class":497}," h1",[149,4223,266],{"class":493},[149,4225,1435],{"class":497},[149,4227,4221],{"class":497},[149,4229,266],{"class":493},[149,4231,1444],{"class":497},[149,4233,4221],{"class":497},[149,4235,2911],{"class":493},[149,4237,4238],{"class":1809},"font-family",[149,4240,2440],{"class":493},[149,4242,4243],{"class":1809},"serif",[149,4245,2920],{"class":493},[149,4247,4248],{"class":489,"line":751},[149,4249,3661],{"emptyLinePlaceholder":72},[149,4251,4252],{"class":489,"line":845},[149,4253,4254],{"class":2770},"\u002F* стало *\u002F\n",[149,4256,4257,4259,4261,4263,4265,4267,4269,4271,4274,4276,4278,4280,4282,4284],{"class":489,"line":851},[149,4258,4183],{"class":702},[149,4260,3001],{"class":493},[149,4262,1429],{"class":497},[149,4264,266],{"class":493},[149,4266,1435],{"class":497},[149,4268,266],{"class":493},[149,4270,1444],{"class":497},[149,4272,4273],{"class":493},") ",[149,4275,105],{"class":497},[149,4277,2911],{"class":493},[149,4279,4238],{"class":1809},[149,4281,2440],{"class":493},[149,4283,4243],{"class":1809},[149,4285,2920],{"class":493},[10,4287,4288,4289,4291,4292,4295,4296,4298],{},"У ",[198,4290,4183],{}," есть нюанс, связанный со ",[2437,4293,4294],{},"специфичностью"," — условным «весом» селектора, по которому каскад выбирает между конкурирующими правилами (формальное определение даётся ниже, в разделе «Каскад, специфичность, наследование»). Специфичность ",[198,4297,4183],{}," равна специфичности самого «тяжёлого» из перечисленных селекторов, что иногда приводит к неожиданному поведению.",[10,4300,4301,4304,4305,4307],{},[198,4302,4303],{},":where(...)"," работает так же, как ",[198,4306,4183],{},", но имеет нулевую специфичность — то есть в каскаде ведёт себя так, словно его нет, и не повышает приоритет правила. Это делает его идеальным для написания низкоприоритетных «базовых» стилей, которые легко переопределить дальше:",[229,4309,4311],{"className":2630,"code":4310,"language":2632,"meta":63,"style":63},":where(article, aside) p { line-height: 1.6; }\n\u002F* такое правило перебьётся любым более специфичным *\u002F\n",[198,4312,4313,4340],{"__ignoreMap":63},[149,4314,4315,4317,4319,4321,4323,4325,4327,4329,4331,4333,4335,4338],{"class":489,"line":490},[149,4316,4186],{"class":702},[149,4318,3001],{"class":493},[149,4320,1438],{"class":497},[149,4322,266],{"class":493},[149,4324,1444],{"class":497},[149,4326,4273],{"class":493},[149,4328,10],{"class":497},[149,4330,2911],{"class":493},[149,4332,2705],{"class":1809},[149,4334,2440],{"class":493},[149,4336,4337],{"class":1809},"1.6",[149,4339,2920],{"class":493},[149,4341,4342],{"class":489,"line":64},[149,4343,4344],{"class":2770},"\u002F* такое правило перебьётся любым более специфичным *\u002F\n",[10,4346,4347,4350],{},[198,4348,4349],{},":has(...)"," — родительский селектор, долго ожидавшийся в CSS. Он выбирает элемент, если внутри него есть совпадающий с указанным селектор:",[229,4352,4354],{"className":2630,"code":4353,"language":2632,"meta":63,"style":63},"article:has(img) { padding-block: 24px; }         \u002F* статья содержит картинку *\u002F\nform:has(input:invalid) button { opacity: 0.5; }  \u002F* в форме есть некорректное поле *\u002F\n",[198,4355,4356,4383],{"__ignoreMap":63},[149,4357,4358,4360,4362,4364,4366,4368,4371,4373,4375,4377,4380],{"class":489,"line":490},[149,4359,1438],{"class":497},[149,4361,4189],{"class":702},[149,4363,3001],{"class":493},[149,4365,378],{"class":497},[149,4367,3721],{"class":493},[149,4369,4370],{"class":1809},"padding-block",[149,4372,2440],{"class":493},[149,4374,3217],{"class":1809},[149,4376,2668],{"class":2667},[149,4378,4379],{"class":493},"; }         ",[149,4381,4382],{"class":2770},"\u002F* статья содержит картинку *\u002F\n",[149,4384,4385,4388,4390,4392,4394,4397,4399,4402,4404,4406,4408,4410,4412],{"class":489,"line":64},[149,4386,4387],{"class":497},"form",[149,4389,4189],{"class":702},[149,4391,3001],{"class":493},[149,4393,727],{"class":497},[149,4395,4396],{"class":702},":invalid",[149,4398,4273],{"class":493},[149,4400,4401],{"class":497},"button",[149,4403,2911],{"class":493},[149,4405,3359],{"class":1809},[149,4407,2440],{"class":493},[149,4409,3364],{"class":1809},[149,4411,3731],{"class":493},[149,4413,4414],{"class":2770},"\u002F* в форме есть некорректное поле *\u002F\n",[10,4416,4417,4418,4420,4421,4423],{},"До ",[198,4419,4189],{}," подобные сценарии решались только с помощью языка JavaScript. Поддержка в браузерах появилась относительно недавно, и ",[198,4422,4189],{}," уже стал частью повседневного инструментария.",[10,4425,4426,4428],{},[198,4427,4192],{}," срабатывает только тогда, когда фокус получен через клавиатуру (Tab, стрелки), но не через клик мышью. Это позволяет показывать чёткую видимую обводку фокуса для пользователей, ориентирующихся клавиатурой, и не показывать её при кликах мышью, где она часто воспринимается как визуальный шум:",[229,4430,4432],{"className":2630,"code":4431,"language":2632,"meta":63,"style":63},"button:focus-visible { outline: 2px solid #06c; }\n",[198,4433,4434],{"__ignoreMap":63},[149,4435,4436,4438,4440,4442,4444,4446,4448,4450,4452,4454],{"class":489,"line":490},[149,4437,4401],{"class":497},[149,4439,4192],{"class":702},[149,4441,2911],{"class":493},[149,4443,3588],{"class":1809},[149,4445,2440],{"class":493},[149,4447,183],{"class":1809},[149,4449,2668],{"class":2667},[149,4451,3597],{"class":1809},[149,4453,3600],{"class":1809},[149,4455,2920],{"class":493},[10,4457,4458,4460],{},[198,4459,4195],{}," срабатывает на элементе, если фокус находится внутри него или на нём самом — удобно для подсветки контейнера активной формы или раскрытого пункта меню:",[229,4462,4464],{"className":2630,"code":4463,"language":2632,"meta":63,"style":63},"form:focus-within { background: #f9fbff; }\n",[198,4465,4466],{"__ignoreMap":63},[149,4467,4468,4470,4472,4474,4476,4478,4481],{"class":489,"line":490},[149,4469,4387],{"class":497},[149,4471,4195],{"class":702},[149,4473,2911],{"class":493},[149,4475,3397],{"class":1809},[149,4477,2440],{"class":493},[149,4479,4480],{"class":1809},"#f9fbff",[149,4482,2920],{"class":493},[10,4484,4485],{},"Эти псевдоклассы аккуратно закрывают сценарии, ради которых раньше приходилось писать вспомогательный JavaScript-код, и заметно упрощают доступную интерактивность.",[112,4487,4489],{"id":4488},"каскад-специфичность-наследование","Каскад, специфичность, наследование",[10,4491,4492,4493,18],{},"Слово «cascading» в названии CSS не случайно: к одному и тому же элементу может относиться несколько правил из разных источников, и язык должен решать, какое из них применить. Этот процесс — каскад — устроен предсказуемо, но требует понимания ",[141,4494,4496],{"className":4495},[144],[14,4497,4499],{"href":4498},"#ref-6",[149,4500,4501],{},"6",[117,4503,4505],{"id":4504},"источники-стилей-и-порядок-их-применения","Источники стилей и порядок их применения",[10,4507,4508],{},"Стили попадают к элементу из нескольких источников, упорядоченных по приоритету:",[2487,4510,4511,4517,4523],{},[40,4512,4513,4516],{},[2437,4514,4515],{},"Браузерные стили по умолчанию"," (user-agent) — самый низкий приоритет.",[40,4518,4519,4522],{},[2437,4520,4521],{},"Пользовательские стили"," — стили, установленные пользователем через настройки браузера или расширения. На практике встречаются редко.",[40,4524,4525,4528,4529,4531,4532,266,4534,4536],{},[2437,4526,4527],{},"Авторские стили"," — то, что написал разработчик: внешние таблицы, ",[198,4530,2879],{},", инлайн-",[198,4533,2508],{},[198,4535,2986],{},"-ы.",[10,4538,4539,4540,4543],{},"Внутри каждой группы порядок дополнительно определяется тремя факторами: происхождением правила (",[198,4541,4542],{},"!important"," повышает приоритет), его специфичностью и порядком следования в файле (более позднее правило перебивает более раннее при равной специфичности).",[10,4545,4546,4547,1093,4550,4553,4554,4561],{},"Помимо этих базовых механизмов, в современный CSS добавлены ",[2437,4548,4549],{},"каскадные слои",[198,4551,4552],{},"@layer",") — способ автору явно задать собственную иерархию приоритетов между группами правил, не полагаясь на хитросплетения специфичности ",[141,4555,4557],{"className":4556},[144],[14,4558,4559],{"href":4498},[149,4560,4501],{},". Это инструмент крупных проектов и дизайн-систем; в простой стилизации без него легко обходятся.",[117,4563,4565],{"id":4564},"вычисление-специфичности-селекторов-и-типовые-ошибки-интерпретации","Вычисление специфичности селекторов и типовые ошибки интерпретации",[10,4567,4568,4569,2083],{},"Когда несколько правил из одного источника применимы к элементу и задают разные значения одного свойства, побеждает правило с большей специфичностью. Специфичность — целочисленный «вес» селектора, вычисляемый как тройка чисел ",[198,4570,4571],{},"(a, b, c)",[37,4573,4574,4582,4596],{},[40,4575,4576,4578,4579,591],{},[198,4577,14],{}," — количество селекторов по идентификатору (",[198,4580,4581],{},"#id",[40,4583,4584,4587,4588,266,4591,266,4594,591],{},[198,4585,4586],{},"b"," — количество селекторов по классу, атрибуту и псевдоклассу (",[198,4589,4590],{},".btn",[198,4592,4593],{},"[type=\"text\"]",[198,4595,3560],{},[40,4597,4598,4601,4602,266,4604,542],{},[198,4599,4600],{},"c"," — количество селекторов по тегу и псевдоэлементу (",[198,4603,10],{},[198,4605,3889],{},[10,4607,4608,4609,4612,4613,4616],{},"Сравниваются тройки лексикографически: ",[198,4610,4611],{},"(1, 0, 0)"," сильнее ",[198,4614,4615],{},"(0, 9, 9)",". Из этого следуют типичные наблюдения:",[37,4618,4619,4622,4631,4647],{},[40,4620,4621],{},"селектор по идентификатору всегда сильнее любой комбинации классов и тегов;",[40,4623,4624,4625,4628,4629,47],{},"инлайн-",[198,4626,4627],{},"style=\"...\""," имеет ещё более высокий приоритет, эквивалентный тысячам идентификаторов; победить его можно только ",[198,4630,4542],{},[40,4632,4633,4634,4636,4637,266,4639,266,4641,4643,4644,4646],{},"универсальный селектор ",[198,4635,3501],{},", комбинаторы (",[198,4638,1806],{},[198,4640,4058],{},[198,4642,4134],{},") и псевдокласс ",[198,4645,4303],{}," не вносят вклад в специфичность;",[40,4648,4649,475,4651,4654],{},[198,4650,4203],{},[198,4652,4653],{},":not(...)"," имеют специфичность, равную самому «тяжёлому» из перечисленных в них селекторов.",[10,4656,4657,4658,4660],{},"Типичная ошибка — пытаться «победить» нежелательный стиль, добавляя ещё одно одинаковое правило ниже в файле. Если у конкурирующего правила выше специфичность, порядок не поможет. Правильное решение — либо повысить специфичность вашего селектора, либо понизить специфичность конкурента (часто переписав его с использованием ",[198,4659,4186],{},"), либо реструктурировать стили, чтобы конкурента вовсе не возникало.",[117,4662,4664],{"id":4663},"наследование-как-ортогональный-каскаду-механизм","Наследование как ортогональный каскаду механизм",[10,4666,4667,4668,266,4670,266,4672,266,4674,266,4676,4679,4680,266,4682,266,4685,266,4688,266,4691,266,4694,18],{},"Помимо каскада, в CSS работает наследование: некоторые свойства, заданные на родительском элементе, передаются всем потомкам, если у тех нет собственного значения. Наследуются преимущественно типографические свойства: ",[198,4669,2699],{},[198,4671,4238],{},[198,4673,2702],{},[198,4675,2705],{},[198,4677,4678],{},"text-align",". Не наследуются свойства, относящиеся к собственному оформлению элемента: ",[198,4681,3397],{},[198,4683,4684],{},"border",[198,4686,4687],{},"padding",[198,4689,4690],{},"margin",[198,4692,4693],{},"width",[198,4695,4696],{},"height",[10,4698,4699,4700,4703,4704,4707,4708,4711,4712,4714,4715,4717,4718,4721],{},"Какие свойства наследуются, а какие нет — определяется спецификацией; узнать это для конкретного свойства всегда можно в его справочнике. Принудительно изменить поведение можно ключевыми словами ",[198,4701,4702],{},"inherit"," (взять значение от родительского элемента), ",[198,4705,4706],{},"initial"," (вернуть к начальному значению из спецификации), ",[198,4709,4710],{},"unset"," (либо ",[198,4713,4702],{},", если свойство наследуемое, либо ",[198,4716,4706],{},"), ",[198,4719,4720],{},"revert"," (вернуть к user-agent значению).",[10,4723,4724],{},"Наследование — отдельный механизм, не конкурирующий с каскадом: каскад выбирает, какое значение применить к самому элементу, а наследование передаёт это значение вглубь иерархии, если у элементов-потомков своего нет.",[117,4726,4728,4730],{"id":4727},"important-как-исключение-а-не-инструмент",[198,4729,4542],{}," как исключение, а не инструмент",[10,4732,4733,4734,4736],{},"Пометка ",[198,4735,4542],{}," в конце объявления повышает его приоритет, перебивая любые правила обычной специфичности из того же источника:",[229,4738,4740],{"className":2630,"code":4739,"language":2632,"meta":63,"style":63},".button { background: gray !important; }\n",[198,4741,4742],{"__ignoreMap":63},[149,4743,4744,4746,4748,4750,4752,4754,4757],{"class":489,"line":490},[149,4745,2751],{"class":702},[149,4747,2911],{"class":493},[149,4749,3397],{"class":1809},[149,4751,2440],{"class":493},[149,4753,4158],{"class":1809},[149,4755,4756],{"class":2667}," !important",[149,4758,2920],{"class":493},[10,4760,4761],{},"Эта возможность задумана как страховочный механизм: например, для пользовательских стилей в браузере, переопределяющих оформление сайта в целях доступности. В авторских стилях прибегать к ней следует только в исключительных случаях — например, при необходимости перебить стили сторонней библиотеки, которые иначе нельзя обойти.",[10,4763,4764,4765,4767,4768,4770,4771,4773],{},"Массовое использование ",[198,4766,4542],{}," в собственном проекте быстро превращается в гонку: одно ",[198,4769,4542],{}," тянет за собой второе, специфичность теряет смысл, и поддержка стилей становится мучительной. Если возникает соблазн поставить ",[198,4772,4542],{},", обычно это сигнал к рефакторингу селекторов, а не к усилению давления.",[112,4775,4777],{"id":4776},"модель-блока-и-единицы-измерения","Модель блока и единицы измерения",[117,4779,4781],{"id":4780},"блочная-модель-содержимое-padding-border-margin","Блочная модель: содержимое, padding, border, margin",[10,4783,4784,4785,564,4788,4273,4791,18],{},"Каждый элемент на странице с точки зрения CSS — это прямоугольная коробка с четырьмя слоями: содержимое, внутренние отступы, рамка и внешние отступы. Эта схема называется ",[2437,4786,4787],{},"блочной моделью",[125,4789,4790],{},"box model",[141,4792,4794],{"className":4793},[144],[14,4795,4797],{"href":4796},"#ref-7",[149,4798,4799],{},"7",[37,4801,4802,4811,4830,4847],{},[40,4803,4804,4806,4807,475,4809,47],{},[2437,4805,2555],{}," — собственно содержимое элемента: текст, изображение, дочерние элементы. Его размеры контролируются свойствами ",[198,4808,4693],{},[198,4810,4696],{},[40,4812,4813,4815,4816,266,4818,266,4821,266,4824,266,4827,47],{},[2437,4814,4687],{}," — внутренний отступ между содержимым и рамкой. Управляется свойствами ",[198,4817,4687],{},[198,4819,4820],{},"padding-top",[198,4822,4823],{},"padding-right",[198,4825,4826],{},"padding-bottom",[198,4828,4829],{},"padding-left",[40,4831,4832,4834,4835,266,4838,266,4841,4844,4845,47],{},[2437,4833,4684],{}," — рамка вокруг padding. Управляется свойствами ",[198,4836,4837],{},"border-width",[198,4839,4840],{},"border-style",[198,4842,4843],{},"border-color"," или составным ",[198,4846,4684],{},[40,4848,4849,4851,4852,4854],{},[2437,4850,4690],{}," — внешний отступ между рамкой элемента и соседними элементами. Управляется аналогичными ",[198,4853,4690],{},"-свойствами.",[10,4856,4857,4858,4860],{},"Понимание блочной модели — основа всех расчётов вёрстки. Когда два соседних блока «не сходятся» по ширине, или элемент занимает больше места, чем кажется по ",[198,4859,4693],{},", объяснение почти всегда найдётся в padding-е, border-е или margin-е.",[374,4862,376,4863,376,4867],{},[378,4864],{"src":4865,"alt":4866},"\u002Fimg\u002Faidt-mag-frontend\u002Ftopic-02\u002Fbox_model.svg","Блочная модель CSS: content, padding, border, margin",[384,4868,4869],{},"Блочная модель CSS",[10,4871,4872,4873,564,4876,4879,4880,4883,4884,4887,4888,542],{},"Особое поведение демонстрируют вертикальные margin-ы соседних блочных элементов — они ",[2437,4874,4875],{},"схлопываются",[125,4877,4878],{},"margin collapsing","): если один блок имеет ",[198,4881,4882],{},"margin-bottom: 20px",", а следующий за ним — ",[198,4885,4886],{},"margin-top: 30px",", итоговый промежуток между ними будет 30 px, а не 50. Это поведение происходит из исторической логики работы с печатным текстом и часто становится источником недоумения; именно поэтому многие современные практики предпочитают задавать вертикальные интервалы только с одной стороны (например, всегда ",[198,4889,3673],{},[117,4891,4893,2440,4895,4898,4899],{"id":4892},"box-sizing-content-box-против-border-box",[198,4894,3516],{},[198,4896,4897],{},"content-box"," против ",[198,4900,3521],{},[10,4902,4903,4904,4906,4907,475,4909,4911],{},"Свойство ",[198,4905,3516],{}," определяет, как трактуются ",[198,4908,4693],{},[198,4910,4696],{}," элемента:",[37,4913,4914,4933],{},[40,4915,4916,4918,4919,4921,4922,4925,4926,4929,4930,47],{},[198,4917,4897],{}," (значение по умолчанию) — ",[198,4920,4693],{}," задаёт ширину только содержимого, padding и border добавляются ",[125,4923,4924],{},"сверху",". Если ",[198,4927,4928],{},"width: 160px; padding: 20px; border: 1px solid;",", итоговая ширина элемента — ",[198,4931,4932],{},"160 + 20*2 + 1*2 = 202 px",[40,4934,4935,3093,4937,4939,4940,4943,4944,4947,4948,18],{},[198,4936,3521],{},[198,4938,4693],{}," задаёт ширину ",[125,4941,4942],{},"вместе с"," padding и border. При тех же значениях итоговая ширина останется ",[198,4945,4946],{},"200 px",", а на содержимое останется ",[198,4949,4950],{},"160 - 20*2 - 1*2 = 118 px",[374,4952,376,4953,376,4957],{},[378,4954],{"src":4955,"alt":4956},"\u002Fimg\u002Faidt-mag-frontend\u002Ftopic-02\u002Fbox_sizing_comparison.svg","Сравнение content-box и border-box при одинаковых width, padding, border",[384,4958,4959],{},"Сравнение content-box и border-box",[10,4961,4962,4964,4965,4967],{},[198,4963,3521],{}," предсказуемее в большинстве сценариев: вы задаёте «коробку шириной 200 пикселей» — и она ровно такой и оказывается. Поэтому почти все современные проекты переключают всё дерево на ",[198,4966,3521],{}," универсальным правилом в начале таблицы стилей:",[229,4969,4971],{"className":2630,"code":4970,"language":2632,"meta":63,"style":63},"*, *::before, *::after {\n  box-sizing: border-box;\n}\n",[198,4972,4973,4991,5002],{"__ignoreMap":63},[149,4974,4975,4977,4979,4981,4983,4985,4987,4989],{"class":489,"line":490},[149,4976,3501],{"class":497},[149,4978,266],{"class":493},[149,4980,3501],{"class":497},[149,4982,3889],{"class":702},[149,4984,266],{"class":493},[149,4986,3501],{"class":497},[149,4988,3892],{"class":702},[149,4990,2641],{"class":493},[149,4992,4993,4996,4998,5000],{"class":489,"line":64},[149,4994,4995],{"class":1809},"  box-sizing",[149,4997,2440],{"class":493},[149,4999,3521],{"class":1809},[149,5001,2654],{"class":493},[149,5003,5004],{"class":489,"line":751},[149,5005,2687],{"class":493},[10,5007,5008],{},"Это компактное правило экономит часы отладки и стало де-факто стандартом первой строки CSS-проекта.",[117,5010,5012,5013,266,5015,266,5017,266,5020],{"id":5011},"абсолютные-и-относительные-единицы-px-em-rem","Абсолютные и относительные единицы: ",[198,5014,2668],{},[198,5016,125],{},[198,5018,5019],{},"rem",[198,5021,3814],{},[10,5023,5024,5025,18],{},"CSS поддерживает много единиц измерения, разделяемых на абсолютные и относительные ",[141,5026,5028],{"className":5027},[144],[14,5029,5031],{"href":5030},"#ref-8",[149,5032,2781],{},[10,5034,5035,5039,5040,5042],{},[2437,5036,5037],{},[198,5038,2668],{}," (пиксели) — основная абсолютная единица. В современных браузерах 1 px не равен физическому пикселю экрана: это логическая единица, привязанная к плотности экрана и масштабу. Для большинства практических задач ",[198,5041,2668],{}," достаточно предсказуем, чтобы использовать его как «опору».",[10,5044,5045,5049,5050,3051,5052,5055,5056,5058,5059,3087,5062,5065,5066,5068,5069,5071,5072,5074,5075,5077],{},[2437,5046,5047],{},[198,5048,125],{}," — относительная единица: 1em равен значению ",[198,5051,2702],{},[125,5053,5054],{},"текущего элемента",". Если у ",[198,5057,478],{}," задан ",[198,5060,5061],{},"font-size: 16px",[198,5063,5064],{},"1em = 16px"," для свойств этого ",[198,5067,478],{},". ",[198,5070,125],{}," каскадируется и умножается: вложенные элементы наследуют размер от родительского элемента, и ",[198,5073,125],{}," в их свойствах считается уже от наследованного значения. Это делает ",[198,5076,125],{}," мощным, но требующим аккуратности — при глубокой вложенности легко получить непредсказуемые размеры.",[10,5079,5080,5084,5085,5087,5088,5090,5091,5093,5094,5096,5097,5099,5100,5102,5103,5105,5106,5109,5110,5112],{},[2437,5081,5082],{},[198,5083,5019],{}," (root em) — то же, что и ",[198,5086,125],{},", но всегда привязан к ",[198,5089,2702],{}," корневого элемента ",[198,5092,1124],{},", независимо от вложенности. Это даёт предсказуемость ",[198,5095,125],{}," без её каскадных сюрпризов и потому стал основной единицей в современной типографике. Стандартное соглашение: ставят ",[198,5098,5061],{}," на ",[198,5101,1124],{}," (или оставляют дефолтное значение браузера, обычно те же 16 px) и далее везде используют ",[198,5104,5019],{},". Тогда ",[198,5107,5108],{},"1rem = 16px",", и при изменении базового размера на ",[198,5111,1124],{}," пропорционально пересчитывается весь интерфейс.",[10,5114,5115,5119,5120,5122,5123,5125,5126,5128,5129,5131,5132,5134],{},[2437,5116,5117],{},[198,5118,3814],{}," — процент. Единица «контекстная»: процент от чего — зависит от свойства. Для ",[198,5121,4693],{}," — процент от ширины родительского элемента; для ",[198,5124,2702],{}," — процент от ",[198,5127,2702],{}," родительского элемента; для ",[198,5130,2705],{}," — процент от собственного ",[198,5133,2702],{},". Полезна там, где нужна привязка к контейнеру, а не к фиксированной величине.",[117,5136,5138,5139,266,5142,266,5145,266,5148,266,5151,266,5154],{"id":5137},"современные-единицы-и-функции-ch-dvh-svw-clamp-min-max","Современные единицы и функции: ",[198,5140,5141],{},"ch",[198,5143,5144],{},"dvh",[198,5146,5147],{},"svw",[198,5149,5150],{},"clamp",[198,5152,5153],{},"min",[198,5155,5156],{},"max",[10,5158,5159],{},"К базовому набору единиц современный CSS добавил несколько практически ценных вариантов.",[10,5161,5162,5166,5167,5170],{},[2437,5163,5164],{},[198,5165,5141],{}," — ширина символа «0» в текущем шрифте. Идеален для задач с полем ширины «столько-то символов»: например, ограничить максимальную ширину абзаца как ",[198,5168,5169],{},"max-width: 70ch",", чтобы строка вмещала примерно 70 знаков и оставалась читаемой.",[10,5172,5173,5176,5177,5180,5181,475,5184,5187,5188,5191,5192,266,5194,266,5197,5200,5201,266,5204,266,5206,5209,5210,5213,5214,18],{},[2437,5174,5175],{},"Единицы вьюпорта."," Вьюпортом (англ. ",[125,5178,5179],{},"viewport",") в вебе называют видимую область окна браузера, в которой отображается страница; её размер меняется при изменении размеров окна, повороте устройства или появлении\u002Fскрытии браузерных панелей. На вьюпорт опираются единицы ",[198,5182,5183],{},"vw",[198,5185,5186],{},"vh"," — соответственно 1 % ширины и 1 % высоты этой области. Долгое время на мобильных устройствах с ними была неприятность: панели браузера то появляются, то скрываются, и ",[198,5189,5190],{},"100vh"," мог оказываться больше реального видимого окна, отрезая контент. Чтобы это исправить, добавили ",[198,5193,5144],{},[198,5195,5196],{},"svh",[198,5198,5199],{},"lvh"," (dynamic, small, large viewport height) — соответственно текущая, минимальная и максимальная высота вьюпорта при изменчивых панелях. Аналогично — ",[198,5202,5203],{},"dvw",[198,5205,5147],{},[198,5207,5208],{},"lvw",". На сегодня для полноэкранных секций ",[198,5211,5212],{},"100dvh"," — корректная замена ",[198,5215,5190],{},[10,5217,5218,5227],{},[2437,5219,5220,5221,266,5223,266,5225],{},"Функции ",[198,5222,5153],{},[198,5224,5156],{},[198,5226,5150],{}," позволяют выражать значения, реагирующие на контекст:",[229,5229,5231],{"className":2630,"code":5230,"language":2632,"meta":63,"style":63},".container {\n  width: min(100%, 1200px);             \u002F* меньшее из двух: либо 100% контейнера, либо 1200 px *\u002F\n}\n\n.title {\n  font-size: clamp(1.5rem, 4vw, 3rem);  \u002F* плавный размер: между 1.5rem и 3rem, по 4% от ширины *\u002F\n}\n",[198,5232,5233,5240,5269,5273,5277,5284,5316],{"__ignoreMap":63},[149,5234,5235,5238],{"class":489,"line":490},[149,5236,5237],{"class":702},".container",[149,5239,2641],{"class":493},[149,5241,5242,5245,5247,5249,5251,5254,5256,5258,5261,5263,5266],{"class":489,"line":64},[149,5243,5244],{"class":1809},"  width",[149,5246,2440],{"class":493},[149,5248,5153],{"class":1809},[149,5250,3001],{"class":493},[149,5252,5253],{"class":1809},"100",[149,5255,3814],{"class":2667},[149,5257,266],{"class":493},[149,5259,5260],{"class":1809},"1200",[149,5262,2668],{"class":2667},[149,5264,5265],{"class":493},");             ",[149,5267,5268],{"class":2770},"\u002F* меньшее из двух: либо 100% контейнера, либо 1200 px *\u002F\n",[149,5270,5271],{"class":489,"line":751},[149,5272,2687],{"class":493},[149,5274,5275],{"class":489,"line":845},[149,5276,3661],{"emptyLinePlaceholder":72},[149,5278,5279,5282],{"class":489,"line":851},[149,5280,5281],{"class":702},".title",[149,5283,2641],{"class":493},[149,5285,5286,5288,5290,5292,5294,5296,5298,5300,5302,5304,5306,5308,5310,5313],{"class":489,"line":861},[149,5287,2659],{"class":1809},[149,5289,2440],{"class":493},[149,5291,5150],{"class":1809},[149,5293,3001],{"class":493},[149,5295,2680],{"class":1809},[149,5297,5019],{"class":2667},[149,5299,266],{"class":493},[149,5301,362],{"class":1809},[149,5303,5183],{"class":2667},[149,5305,266],{"class":493},[149,5307,352],{"class":1809},[149,5309,5019],{"class":2667},[149,5311,5312],{"class":493},");  ",[149,5314,5315],{"class":2770},"\u002F* плавный размер: между 1.5rem и 3rem, по 4% от ширины *\u002F\n",[149,5317,5318],{"class":489,"line":877},[149,5319,2687],{"class":493},[10,5321,5322,5325,5326,5329],{},[198,5323,5324],{},"clamp(min, preferred, max)"," особенно ценен: он задаёт «жидкое» значение, плавно меняющееся в заданном диапазоне в зависимости от размера экрана. Без него адаптация под разные ширины окна потребовала бы перечисления нескольких правил — по одному для каждого порогового размера. Этот приём — основа подхода «жидкой» типографики (англ. ",[125,5327,5328],{},"fluid typography","): одно правило на размер шрифта работает на всех экранах, без отдельной настройки для каждого диапазона.",[112,5331,5333],{"id":5332},"препроцессоры-css","Препроцессоры CSS",[10,5335,5336,5337,564,5340,5343],{},"До появления в CSS собственных переменных и других удобств разработчики долго пользовались ",[2437,5338,5339],{},"препроцессорами",[125,5341,5342],{},"CSS preprocessors",") — внешними инструментами, которые принимают на вход исходник на расширенном диалекте, а на выходе дают валидный CSS, понятный браузеру. Сегодня препроцессоры по-прежнему встречаются в больших кодовых базах, поэтому представление о них необходимо хотя бы для чтения чужого кода.",[10,5345,5346,5347,5354,5355,5358,5359,5362,5363,475,5372,3051,5379,5388,5389,5392,5393,5396],{},"Самые распространённые препроцессоры — ",[2437,5348,5349],{},[14,5350,5353],{"href":5351,"rel":5352},"https:\u002F\u002Fsass-lang.com\u002F",[370],"Sass"," (с двумя синтаксисами: ",[198,5356,5357],{},".sass"," без скобок и ",[198,5360,5361],{},".scss",", синтаксически совместимый с CSS) ",[141,5364,5366],{"className":5365},[144],[14,5367,5369],{"href":5368},"#ref-9",[149,5370,5371],{},"9",[2437,5373,5374],{},[14,5375,5378],{"href":5376,"rel":5377},"https:\u002F\u002Flesscss.org\u002F",[370],"Less",[141,5380,5382],{"className":5381},[144],[14,5383,5385],{"href":5384},"#ref-10",[149,5386,5387],{},"10",". Эти препроцессоры добавляют над CSS примерно один и тот же набор возможностей: переменные (",[198,5390,5391],{},"$primary"," в Sass, ",[198,5394,5395],{},"@primary"," в Less), вложенность селекторов, миксины (переиспользуемые блоки правил), функции для работы с цветами и числами, импорт частей таблицы, ветвления и циклы.",[10,5398,5399,5400,5403],{},"Принципиальное отличие от CSS Custom Properties — нативных переменных самого CSS, которым посвящён следующий раздел, — заключается в моменте работы. Препроцессор запускается на этапе ",[2437,5401,5402],{},"сборки",": он читает исходник, разворачивает все конструкции и порождает обычный CSS-файл, в котором уже нет ни переменных, ни миксинов. До браузера доезжает только итог. Поэтому препроцессорные переменные могут участвовать в селекторах, медиа-запросах, расчётах на этапе компиляции — но не могут изменяться во время выполнения.",[10,5405,5406,5407,5410],{},"Отдельное место занимает ",[2437,5408,5409],{},"PostCSS"," — формально не препроцессор, а инструмент трансформации CSS через систему плагинов. С его помощью можно реализовать часть возможностей Sass (autoprefixer, nested), а можно, наоборот, отказаться от препроцессора в пользу нативного CSS с минимальной обработкой. В современных проектах сборка часто строится именно на PostCSS-плагинах, а Sass подключается избирательно — только там, где его выразительность реально нужна.",[112,5412,5414],{"id":5413},"css-custom-properties-и-дизайн-токены","CSS Custom Properties и дизайн-токены",[117,5416,5418],{"id":5417},"переменные-css-как-способ-декларации-дизайн-токенов","Переменные CSS как способ декларации дизайн-токенов",[10,5420,5421,5422,5425,5426,18],{},"Современный интерфейс редко строится на хаотичной палитре цветов и случайных размерах: у проекта обычно есть ",[125,5423,5424],{},"дизайн-система"," — набор согласованных значений (цветов, шрифтов, отступов, скруглений, теней), повторяющихся по всему интерфейсу. Эти значения называют ",[2437,5427,5428],{},"дизайн-токенами",[10,5430,5431,5432,5435,5436,3051,5439,5448,5449,2083],{},"Чтобы хранить такие значения в самой таблице стилей и переиспользовать их, в CSS существуют пользовательские свойства (англ. ",[125,5433,5434],{},"Custom Properties","), обычно называемые ",[2437,5437,5438],{},"CSS-переменными",[141,5440,5442],{"className":5441},[144],[14,5443,5445],{"href":5444},"#ref-11",[149,5446,5447],{},"11",". Декларируются они с двойным дефисом в имени и используются через функцию ",[198,5450,5451],{},"var(...)",[229,5453,5455],{"className":2630,"code":5454,"language":2632,"meta":63,"style":63},":root {\n  --color-text: #1a1a1a;\n  --color-accent: #06c;\n  --space-md: 16px;\n  --radius-md: 8px;\n}\n\n.button {\n  color: var(--color-text);\n  background: var(--color-accent);\n  padding: var(--space-md);\n  border-radius: var(--radius-md);\n}\n",[198,5456,5457,5464,5477,5488,5501,5514,5518,5522,5528,5544,5559,5574,5590],{"__ignoreMap":63},[149,5458,5459,5462],{"class":489,"line":490},[149,5460,5461],{"class":702},":root",[149,5463,2641],{"class":493},[149,5465,5466,5470,5472,5475],{"class":489,"line":64},[149,5467,5469],{"class":5468},"s4XuR","  --color-text",[149,5471,2440],{"class":493},[149,5473,5474],{"class":1809},"#1a1a1a",[149,5476,2654],{"class":493},[149,5478,5479,5482,5484,5486],{"class":489,"line":751},[149,5480,5481],{"class":5468},"  --color-accent",[149,5483,2440],{"class":493},[149,5485,2763],{"class":1809},[149,5487,2654],{"class":493},[149,5489,5490,5493,5495,5497,5499],{"class":489,"line":845},[149,5491,5492],{"class":5468},"  --space-md",[149,5494,2440],{"class":493},[149,5496,2664],{"class":1809},[149,5498,2668],{"class":2667},[149,5500,2654],{"class":493},[149,5502,5503,5506,5508,5510,5512],{"class":489,"line":851},[149,5504,5505],{"class":5468},"  --radius-md",[149,5507,2440],{"class":493},[149,5509,2781],{"class":1809},[149,5511,2668],{"class":2667},[149,5513,2654],{"class":493},[149,5515,5516],{"class":489,"line":861},[149,5517,2687],{"class":493},[149,5519,5520],{"class":489,"line":877},[149,5521,3661],{"emptyLinePlaceholder":72},[149,5523,5524,5526],{"class":489,"line":883},[149,5525,2751],{"class":702},[149,5527,2641],{"class":493},[149,5529,5530,5532,5534,5537,5539,5542],{"class":489,"line":892},[149,5531,2646],{"class":1809},[149,5533,2440],{"class":493},[149,5535,5536],{"class":1809},"var",[149,5538,3001],{"class":493},[149,5540,5541],{"class":5468},"--color-text",[149,5543,3007],{"class":493},[149,5545,5546,5548,5550,5552,5554,5557],{"class":489,"line":75},[149,5547,2758],{"class":1809},[149,5549,2440],{"class":493},[149,5551,5536],{"class":1809},[149,5553,3001],{"class":493},[149,5555,5556],{"class":5468},"--color-accent",[149,5558,3007],{"class":493},[149,5560,5561,5563,5565,5567,5569,5572],{"class":489,"line":1066},[149,5562,2776],{"class":1809},[149,5564,2440],{"class":493},[149,5566,5536],{"class":1809},[149,5568,3001],{"class":493},[149,5570,5571],{"class":5468},"--space-md",[149,5573,3007],{"class":493},[149,5575,5576,5579,5581,5583,5585,5588],{"class":489,"line":1075},[149,5577,5578],{"class":1809},"  border-radius",[149,5580,2440],{"class":493},[149,5582,5536],{"class":1809},[149,5584,3001],{"class":493},[149,5586,5587],{"class":5468},"--radius-md",[149,5589,3007],{"class":493},[149,5591,5592],{"class":489,"line":1650},[149,5593,2687],{"class":493},[10,5595,5596,5597,5599,5600,5602,5603,5605],{},"Декларация в ",[198,5598,5461],{}," (псевдокласс, эквивалентный корневому ",[198,5601,1124],{},") делает переменные доступными во всём документе. Изменив одно значение на корне, мы автоматически меняем его во всех правилах, использующих ",[198,5604,5451],{}," — это и есть основной механизм системной стилизации и темизации.",[117,5607,5609],{"id":5608},"семантические-уровни-токенов-primitive-semantic-component","Семантические уровни токенов: primitive, semantic, component",[10,5611,5612],{},"В зрелых дизайн-системах токены разделяют на три уровня по смыслу.",[10,5614,5615,5618],{},[2437,5616,5617],{},"Primitive"," (примитивные) — «сырая» палитра: конкретные цвета, размеры, числа. Они не несут смысла применения, только описывают значение:",[229,5620,5622],{"className":2630,"code":5621,"language":2632,"meta":63,"style":63},"--blue-500: #06c;\n--blue-700: #04488f;\n--gray-100: #f5f5f5;\n--gray-900: #1a1a1a;\n--space-1: 4px;\n--space-2: 8px;\n--space-3: 16px;\n",[198,5623,5624,5634,5644,5652,5661,5666,5671],{"__ignoreMap":63},[149,5625,5626,5629,5632],{"class":489,"line":490},[149,5627,5628],{"class":493},"--blue-500: ",[149,5630,2763],{"class":5631},"s7hpK",[149,5633,2654],{"class":493},[149,5635,5636,5639,5642],{"class":489,"line":64},[149,5637,5638],{"class":493},"--blue-700: ",[149,5640,5641],{"class":5631},"#04488f",[149,5643,2654],{"class":493},[149,5645,5646,5649],{"class":489,"line":751},[149,5647,5648],{"class":493},"--gray-100: ",[149,5650,5651],{"class":5631},"#f5f5f5;\n",[149,5653,5654,5657,5659],{"class":489,"line":845},[149,5655,5656],{"class":493},"--gray-900: ",[149,5658,5474],{"class":5631},[149,5660,2654],{"class":493},[149,5662,5663],{"class":489,"line":851},[149,5664,5665],{"class":493},"--space-1: 4px;\n",[149,5667,5668],{"class":489,"line":861},[149,5669,5670],{"class":493},"--space-2: 8px;\n",[149,5672,5673],{"class":489,"line":877},[149,5674,5675],{"class":493},"--space-3: 16px;\n",[10,5677,5678,5681,5682,5685],{},[2437,5679,5680],{},"Semantic"," (семантические) — токены, описывающие ",[125,5683,5684],{},"роль"," значения в интерфейсе. Они ссылаются на примитивные:",[229,5687,5689],{"className":2630,"code":5688,"language":2632,"meta":63,"style":63},"--color-text-primary: var(--gray-900);\n--color-text-muted: var(--gray-700);\n--color-link: var(--blue-500);\n--color-link-hover: var(--blue-700);\n--space-card-padding: var(--space-3);\n",[198,5690,5691,5696,5701,5706,5711],{"__ignoreMap":63},[149,5692,5693],{"class":489,"line":490},[149,5694,5695],{"class":493},"--color-text-primary: var(--gray-900);\n",[149,5697,5698],{"class":489,"line":64},[149,5699,5700],{"class":493},"--color-text-muted: var(--gray-700);\n",[149,5702,5703],{"class":489,"line":751},[149,5704,5705],{"class":493},"--color-link: var(--blue-500);\n",[149,5707,5708],{"class":489,"line":845},[149,5709,5710],{"class":493},"--color-link-hover: var(--blue-700);\n",[149,5712,5713],{"class":489,"line":851},[149,5714,5715],{"class":493},"--space-card-padding: var(--space-3);\n",[10,5717,5718,5721],{},[2437,5719,5720],{},"Component"," (компонентные) — токены, специфичные для конкретного компонента. Они ссылаются на семантические:",[229,5723,5725],{"className":2630,"code":5724,"language":2632,"meta":63,"style":63},"--button-bg: var(--color-link);\n--button-bg-hover: var(--color-link-hover);\n--button-padding-y: var(--space-2);\n--button-padding-x: var(--space-3);\n",[198,5726,5727,5732,5737,5742],{"__ignoreMap":63},[149,5728,5729],{"class":489,"line":490},[149,5730,5731],{"class":493},"--button-bg: var(--color-link);\n",[149,5733,5734],{"class":489,"line":64},[149,5735,5736],{"class":493},"--button-bg-hover: var(--color-link-hover);\n",[149,5738,5739],{"class":489,"line":751},[149,5740,5741],{"class":493},"--button-padding-y: var(--space-2);\n",[149,5743,5744],{"class":489,"line":845},[149,5745,5746],{"class":493},"--button-padding-x: var(--space-3);\n",[10,5748,5749,5750,5753],{},"Такое расслоение даёт два важных свойства. Во-первых, при смене темы достаточно переопределить семантический слой — компонентам не нужно ничего знать об альтернативной палитре. Во-вторых, при изменении дизайна (скажем, замена основного синего на бирюзовый) точка изменения одна — ",[198,5751,5752],{},"--color-link"," в семантическом слое.",[117,5755,5757],{"id":5756},"каскадируемость-переменных-и-пересчёт-на-лету","Каскадируемость переменных и пересчёт на лету",[10,5759,5760],{},"CSS Custom Properties подчиняются обычным правилам каскада и наследования: переменная, объявленная на родительском элементе, доступна на всех элементах-потомках, если те не переопределили её. Это позволяет менять значения локально, не дублируя само правило компонента:",[229,5762,5764],{"className":2630,"code":5763,"language":2632,"meta":63,"style":63},":root {\n  --button-bg: #06c;          \u002F* по умолчанию кнопки синие *\u002F\n}\n\n.section-danger {\n  --button-bg: #c00;          \u002F* в «опасной» секции — красные *\u002F\n}\n\n.button {\n  background: var(--button-bg);  \u002F* возьмёт ближайшее значение из контекста *\u002F\n}\n",[198,5765,5766,5772,5787,5791,5795,5802,5816,5820,5824,5830,5848],{"__ignoreMap":63},[149,5767,5768,5770],{"class":489,"line":490},[149,5769,5461],{"class":702},[149,5771,2641],{"class":493},[149,5773,5774,5777,5779,5781,5784],{"class":489,"line":64},[149,5775,5776],{"class":5468},"  --button-bg",[149,5778,2440],{"class":493},[149,5780,2763],{"class":1809},[149,5782,5783],{"class":493},";          ",[149,5785,5786],{"class":2770},"\u002F* по умолчанию кнопки синие *\u002F\n",[149,5788,5789],{"class":489,"line":751},[149,5790,2687],{"class":493},[149,5792,5793],{"class":489,"line":845},[149,5794,3661],{"emptyLinePlaceholder":72},[149,5796,5797,5800],{"class":489,"line":851},[149,5798,5799],{"class":702},".section-danger",[149,5801,2641],{"class":493},[149,5803,5804,5806,5808,5811,5813],{"class":489,"line":861},[149,5805,5776],{"class":5468},[149,5807,2440],{"class":493},[149,5809,5810],{"class":1809},"#c00",[149,5812,5783],{"class":493},[149,5814,5815],{"class":2770},"\u002F* в «опасной» секции — красные *\u002F\n",[149,5817,5818],{"class":489,"line":877},[149,5819,2687],{"class":493},[149,5821,5822],{"class":489,"line":883},[149,5823,3661],{"emptyLinePlaceholder":72},[149,5825,5826,5828],{"class":489,"line":892},[149,5827,2751],{"class":702},[149,5829,2641],{"class":493},[149,5831,5832,5834,5836,5838,5840,5843,5845],{"class":489,"line":75},[149,5833,2758],{"class":1809},[149,5835,2440],{"class":493},[149,5837,5536],{"class":1809},[149,5839,3001],{"class":493},[149,5841,5842],{"class":5468},"--button-bg",[149,5844,5312],{"class":493},[149,5846,5847],{"class":2770},"\u002F* возьмёт ближайшее значение из контекста *\u002F\n",[149,5849,5850],{"class":489,"line":1066},[149,5851,2687],{"class":493},[10,5853,5854,5855,5857,5858,5860],{},"Правило ",[198,5856,2751],{}," в проекте одно, но сама кнопка отрисовывается по-разному в зависимости от того, в какое окружение она вложена: синей по умолчанию и красной — внутри ",[198,5859,5799],{},". То же правило каскада, что и для обычных свойств, работает и для переменных.",[10,5862,5863],{},"Кроме того, CSS-переменные читаются и могут быть изменены из JavaScript — языка скриптов веб-страницы, которому посвящена тема 5:",[229,5865,5869],{"className":5866,"code":5867,"language":5868,"meta":63,"style":63},"language-js shiki shiki-themes github-light github-dark","document.documentElement.style.setProperty('--color-accent', '#e91e63');\n","js",[198,5870,5871],{"__ignoreMap":63},[149,5872,5873,5876,5879,5881,5884,5886,5889],{"class":489,"line":490},[149,5874,5875],{"class":493},"document.documentElement.style.",[149,5877,5878],{"class":702},"setProperty",[149,5880,3001],{"class":493},[149,5882,5883],{"class":709},"'--color-accent'",[149,5885,266],{"class":493},[149,5887,5888],{"class":709},"'#e91e63'",[149,5890,3007],{"class":493},[10,5892,5893,5894,5896,5897,5900,5901,18],{},"Это даёт возможность темизации, пользовательских настроек, динамических акцентов в реальном времени без перерисовки всего CSS. Функция ",[198,5895,5451],{}," поддерживает значение по умолчанию: ",[198,5898,5899],{},"var(--color-accent, #06c)"," — если переменная не объявлена, использовать ",[198,5902,2763],{},[117,5904,5906],{"id":5905},"ограничения-custom-properties-в-сравнении-с-препроцессорными-переменными","Ограничения Custom Properties в сравнении с препроцессорными переменными",[10,5908,5909,5910,5913,5914,5917],{},"Существенное отличие CSS-переменных от переменных препроцессоров (Sass ",[198,5911,5912],{},"$var",", Less ",[198,5915,5916],{},"@var",") — в моменте их разрешения. Препроцессорные переменные подставляются на этапе сборки: после компиляции в CSS никаких переменных уже нет, остаются только конкретные значения. CSS Custom Properties живут в браузере во время выполнения — поэтому их можно менять динамически.",[10,5919,5920],{},"Из этого вытекают два практических ограничения:",[37,5922,5923,5940],{},[40,5924,5925,1093,5928,5931,5932,5935,5936,5939],{},[2437,5926,5927],{},"Custom Properties нельзя использовать в селекторах и медиа-запросах",[198,5929,5930],{},"@media","-правилах, отвечающих за адаптацию вёрстки под разные ширины экрана; они подробно разбираются в теме 3). Запись ",[198,5933,5934],{},"@media (min-width: var(--breakpoint-md))"," не работает: медиа-запрос разбирается до того, как переменные получают значения. То же касается селекторов — ",[198,5937,5938],{},"var(--my-class)"," в селекторе невозможна;",[40,5941,5942,5945],{},[2437,5943,5944],{},"Тип значения не контролируется",". Препроцессор может проверить, что вы используете цветовую переменную там, где ожидается цвет; CSS-переменная — просто строка, и подстановка некорректного значения тихо приведёт к невалидному CSS-объявлению, которое браузер просто проигнорирует.",[10,5947,5948],{},"В проектах с большой дизайн-системой эти два мира часто сосуществуют: препроцессор отвечает за вещи, известные на этапе сборки (брейкпоинты, утилитные миксины), а CSS Custom Properties — за всё, что должно меняться динамически или различаться по контексту (темы, локальные акценты).",[112,5950,5952],{"id":5951},"темизация-интерфейса","Темизация интерфейса",[10,5954,5955],{},"Темизация — самый частый практический повод осваивать дизайн-токены: переключение между светлой и тёмной темой стало стандартным ожиданием от современных интерфейсов.",[117,5957,5959,5960],{"id":5958},"автоматическая-тема-через-prefers-color-scheme","Автоматическая тема через ",[198,5961,5962],{},"prefers-color-scheme",[10,5964,5965,5966,3051,5968,5976],{},"Операционные системы дают пользователям возможность выбрать предпочитаемое оформление: светлое или тёмное. Браузер транслирует этот выбор в медиа-фичу ",[198,5967,5962],{},[141,5969,5971],{"className":5970},[144],[14,5972,5974],{"href":5973},"#ref-12",[149,5975,3316],{},", которую можно использовать в медиа-запросах CSS:",[229,5978,5980],{"className":2630,"code":5979,"language":2632,"meta":63,"style":63},":root {\n  --color-bg: #ffffff;\n  --color-text: #1a1a1a;\n}\n\n@media (prefers-color-scheme: dark) {\n  :root {\n    --color-bg: #1a1a1a;\n    --color-text: #f5f5f5;\n  }\n}\n\nbody {\n  background: var(--color-bg);\n  color: var(--color-text);\n}\n",[198,5981,5982,5988,6000,6010,6014,6018,6025,6032,6043,6054,6059,6063,6067,6073,6088,6102],{"__ignoreMap":63},[149,5983,5984,5986],{"class":489,"line":490},[149,5985,5461],{"class":702},[149,5987,2641],{"class":493},[149,5989,5990,5993,5995,5998],{"class":489,"line":64},[149,5991,5992],{"class":5468},"  --color-bg",[149,5994,2440],{"class":493},[149,5996,5997],{"class":1809},"#ffffff",[149,5999,2654],{"class":493},[149,6001,6002,6004,6006,6008],{"class":489,"line":751},[149,6003,5469],{"class":5468},[149,6005,2440],{"class":493},[149,6007,5474],{"class":1809},[149,6009,2654],{"class":493},[149,6011,6012],{"class":489,"line":845},[149,6013,2687],{"class":493},[149,6015,6016],{"class":489,"line":851},[149,6017,3661],{"emptyLinePlaceholder":72},[149,6019,6020,6022],{"class":489,"line":861},[149,6021,5930],{"class":2667},[149,6023,6024],{"class":493}," (prefers-color-scheme: dark) {\n",[149,6026,6027,6030],{"class":489,"line":877},[149,6028,6029],{"class":702},"  :root",[149,6031,2641],{"class":493},[149,6033,6034,6037,6039,6041],{"class":489,"line":883},[149,6035,6036],{"class":5468},"    --color-bg",[149,6038,2440],{"class":493},[149,6040,5474],{"class":1809},[149,6042,2654],{"class":493},[149,6044,6045,6048,6050,6052],{"class":489,"line":892},[149,6046,6047],{"class":5468},"    --color-text",[149,6049,2440],{"class":493},[149,6051,3728],{"class":1809},[149,6053,2654],{"class":493},[149,6055,6056],{"class":489,"line":75},[149,6057,6058],{"class":493},"  }\n",[149,6060,6061],{"class":489,"line":1066},[149,6062,2687],{"class":493},[149,6064,6065],{"class":489,"line":1075},[149,6066,3661],{"emptyLinePlaceholder":72},[149,6068,6069,6071],{"class":489,"line":1650},[149,6070,1037],{"class":497},[149,6072,2641],{"class":493},[149,6074,6075,6077,6079,6081,6083,6086],{"class":489,"line":1664},[149,6076,2758],{"class":1809},[149,6078,2440],{"class":493},[149,6080,5536],{"class":1809},[149,6082,3001],{"class":493},[149,6084,6085],{"class":5468},"--color-bg",[149,6087,3007],{"class":493},[149,6089,6090,6092,6094,6096,6098,6100],{"class":489,"line":1673},[149,6091,2646],{"class":1809},[149,6093,2440],{"class":493},[149,6095,5536],{"class":1809},[149,6097,3001],{"class":493},[149,6099,5541],{"class":5468},[149,6101,3007],{"class":493},[149,6103,6104],{"class":489,"line":1682},[149,6105,2687],{"class":493},[10,6107,6108],{},"При таком подходе сайт сам подстраивается под предпочтения пользователя, без явного переключателя в интерфейсе. Это удачная база, но во многих проектах нужен и явный выбор — например, чтобы пользователь мог переопределить системную настройку или зафиксировать тему независимо от ОС.",[117,6110,6112,6113,6115,6116],{"id":6111},"ручное-переключение-темы-атрибут-на-html-синхронизация-с-localstorage","Ручное переключение темы: атрибут на ",[198,6114,484],{},", синхронизация с ",[198,6117,6118],{},"localStorage",[10,6120,6121,6122,6124],{},"Сложившийся способ ручной темизации — управлять темой через атрибут на корневом элементе ",[198,6123,1124],{}," и завести две группы переменных:",[229,6126,6128],{"className":2630,"code":6127,"language":2632,"meta":63,"style":63},":root {\n  --color-bg: #ffffff;\n  --color-text: #1a1a1a;\n}\n\n[data-theme=\"dark\"] {\n  --color-bg: #1a1a1a;\n  --color-text: #f5f5f5;\n}\n",[198,6129,6130,6136,6146,6156,6160,6164,6179,6189,6199],{"__ignoreMap":63},[149,6131,6132,6134],{"class":489,"line":490},[149,6133,5461],{"class":702},[149,6135,2641],{"class":493},[149,6137,6138,6140,6142,6144],{"class":489,"line":64},[149,6139,5992],{"class":5468},[149,6141,2440],{"class":493},[149,6143,5997],{"class":1809},[149,6145,2654],{"class":493},[149,6147,6148,6150,6152,6154],{"class":489,"line":751},[149,6149,5469],{"class":5468},[149,6151,2440],{"class":493},[149,6153,5474],{"class":1809},[149,6155,2654],{"class":493},[149,6157,6158],{"class":489,"line":845},[149,6159,2687],{"class":493},[149,6161,6162],{"class":489,"line":851},[149,6163,3661],{"emptyLinePlaceholder":72},[149,6165,6166,6168,6171,6173,6176],{"class":489,"line":861},[149,6167,3350],{"class":493},[149,6169,6170],{"class":702},"data-theme",[149,6172,706],{"class":2667},[149,6174,6175],{"class":709},"\"dark\"",[149,6177,6178],{"class":493},"] {\n",[149,6180,6181,6183,6185,6187],{"class":489,"line":877},[149,6182,5992],{"class":5468},[149,6184,2440],{"class":493},[149,6186,5474],{"class":1809},[149,6188,2654],{"class":493},[149,6190,6191,6193,6195,6197],{"class":489,"line":883},[149,6192,5469],{"class":5468},[149,6194,2440],{"class":493},[149,6196,3728],{"class":1809},[149,6198,2654],{"class":493},[149,6200,6201],{"class":489,"line":892},[149,6202,2687],{"class":493},[10,6204,6205],{},"Тогда переключение темы — это присваивание атрибуту значения, выполняемое из JavaScript:",[229,6207,6209],{"className":5866,"code":6208,"language":5868,"meta":63,"style":63},"document.documentElement.dataset.theme = 'dark';\n",[198,6210,6211],{"__ignoreMap":63},[149,6212,6213,6216,6218,6221],{"class":489,"line":490},[149,6214,6215],{"class":493},"document.documentElement.dataset.theme ",[149,6217,706],{"class":2667},[149,6219,6220],{"class":709}," 'dark'",[149,6222,2654],{"class":493},[10,6224,6225,6226,6228],{},"Чтобы выбор пользователя сохранялся между визитами, его записывают в ",[198,6227,6118],{}," (подробнее о Storage API — в теме 7) и читают на ранней стадии загрузки страницы, ещё до показа интерфейса, чтобы избежать «вспышки» неправильной темы:",[229,6230,6232],{"className":482,"code":6231,"language":484,"meta":63,"style":63},"\u003Cscript>\n  const saved = localStorage.getItem('theme');\n  if (saved) document.documentElement.dataset.theme = saved;\n\u003C\u002Fscript>\n",[198,6233,6234,6243,6267,6280],{"__ignoreMap":63},[149,6235,6236,6238,6241],{"class":489,"line":490},[149,6237,494],{"class":493},[149,6239,6240],{"class":497},"script",[149,6242,505],{"class":493},[149,6244,6245,6248,6251,6254,6257,6260,6262,6265],{"class":489,"line":64},[149,6246,6247],{"class":2667},"  const",[149,6249,6250],{"class":1809}," saved",[149,6252,6253],{"class":2667}," =",[149,6255,6256],{"class":493}," localStorage.",[149,6258,6259],{"class":702},"getItem",[149,6261,3001],{"class":493},[149,6263,6264],{"class":709},"'theme'",[149,6266,3007],{"class":493},[149,6268,6269,6272,6275,6277],{"class":489,"line":751},[149,6270,6271],{"class":2667},"  if",[149,6273,6274],{"class":493}," (saved) document.documentElement.dataset.theme ",[149,6276,706],{"class":2667},[149,6278,6279],{"class":493}," saved;\n",[149,6281,6282,6284,6286],{"class":489,"line":845},[149,6283,895],{"class":493},[149,6285,6240],{"class":497},[149,6287,505],{"class":493},[10,6289,6290,6291,6293],{},"Часто две схемы — автоматическая через ",[198,6292,5962],{}," и ручная через атрибут — комбинируются: атрибут перебивает медиа-запрос, и в результате пользователь получает предсказуемое поведение «по умолчанию — как в системе, при явном выборе — как выбрал».",[112,6295,2459],{"id":2458},[10,6297,6298],{},"CSS — не «настройка цветов и шрифтов», а полноценный декларативный язык, в котором каждое правило — утверждение «к таким-то элементам в такой-то ситуации применяй такие-то свойства». Когда правил становится больше, чем элементов, в дело вступает каскад: система предсказуемо разрешает противоречия по источнику, специфичности и порядку. Понимание этих трёх осей превращает CSS из эзотерики в инструмент, поведение которого можно объяснять и предсказывать.",[10,6300,6301,6302,6304],{},"На уровне отдельного элемента CSS оперирует блочной моделью: коробкой с четырьмя слоями, размер которой зависит от значения ",[198,6303,3516],{},". На уровне всего интерфейса современные практики строятся на дизайн-токенах через CSS Custom Properties, расслоённых на примитивные, семантические и компонентные. Эта структура естественно перерастает в темизацию — переключение между светлой и тёмной темой, синхронизированное с системными предпочтениями пользователя и его явным выбором.",[112,6306,2485],{"id":2484},[2487,6308,6310,6313,6316,6319,6322,6326,6330,6334,6338,6342,6346,6350],{"className":6309},[2490],[40,6311,6312],{"id":2493},"Consortium} {. W. W. Cascading Style Sheets, Level 1. — 1996, https:\u002F\u002Fwww.w3.org\u002FTR\u002FCSS1\u002F.",[40,6314,6315],{"id":2497},"Lie H. W., Bos B. Cascading Style Sheets: Designing for the Web. — Addison-Wesley, 2005.",[40,6317,6318],{"id":2501},"Lie H. W. Cascading HTML style sheets –- a proposal. — 1994, https:\u002F\u002Fwww.w3.org\u002FPeople\u002Fhowcome\u002Fp\u002Fcascade.html.",[40,6320,6321],{"id":2505},"Meyer E. A. CSS Tools: Reset CSS. — 2007, https:\u002F\u002Fmeyerweb.com\u002Feric\u002Ftools\u002Fcss\u002Freset\u002F.",[40,6323,6325],{"id":6324},"ref-5","Consortium} {. W. W. Selectors Level 4. — 2022, https:\u002F\u002Fwww.w3.org\u002FTR\u002Fselectors-4\u002F.",[40,6327,6329],{"id":6328},"ref-6","Consortium} {. W. W. CSS Cascading and Inheritance Level 5. — 2024, https:\u002F\u002Fwww.w3.org\u002FTR\u002Fcss-cascade-5\u002F.",[40,6331,6333],{"id":6332},"ref-7","Consortium} {. W. W. CSS Box Model Module Level 3. — 2024, https:\u002F\u002Fwww.w3.org\u002FTR\u002Fcss-box-3\u002F.",[40,6335,6337],{"id":6336},"ref-8","Consortium} {. W. W. CSS Values and Units Module Level 4. — 2024, https:\u002F\u002Fwww.w3.org\u002FTR\u002Fcss-values-4\u002F.",[40,6339,6341],{"id":6340},"ref-9","Team} {. Sass Documentation. — 2024, https:\u002F\u002Fsass-lang.com\u002Fdocumentation\u002F.",[40,6343,6345],{"id":6344},"ref-10","Team} {. C. Less Language Reference. — 2024, https:\u002F\u002Flesscss.org\u002Ffeatures\u002F.",[40,6347,6349],{"id":6348},"ref-11","Consortium} {. W. W. CSS Custom Properties for Cascading Variables Module Level 1. — 2022, https:\u002F\u002Fwww.w3.org\u002FTR\u002Fcss-variables-1\u002F.",[40,6351,6353],{"id":6352},"ref-12","Consortium} {. W. W. Media Queries Level 5. — 2024, https:\u002F\u002Fwww.w3.org\u002FTR\u002Fmediaqueries-5\u002F.",[2508,6355,6356],{},"html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .s7hpK, html code.shiki .s7hpK{--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}",{"title":63,"searchDepth":64,"depth":64,"links":6358},[6359,6366,6373,6380,6389,6390,6396,6402,6403],{"id":2573,"depth":64,"text":2574,"children":6360},[6361,6362,6363,6364,6365],{"id":2577,"depth":751,"text":2578},{"id":2623,"depth":751,"text":2624},{"id":780,"depth":751,"text":781},{"id":2797,"depth":751,"text":2798},{"id":3022,"depth":751,"text":3023},{"id":3062,"depth":64,"text":3063,"children":6367},[6368,6369,6370,6371],{"id":3126,"depth":751,"text":3127},{"id":3532,"depth":751,"text":3533},{"id":3914,"depth":751,"text":3915},{"id":4179,"depth":751,"text":6372},"Современные псевдоклассы: :is, :where, :has, :focus-visible, :focus-within",{"id":4488,"depth":64,"text":4489,"children":6374},[6375,6376,6377,6378],{"id":4504,"depth":751,"text":4505},{"id":4564,"depth":751,"text":4565},{"id":4663,"depth":751,"text":4664},{"id":4727,"depth":751,"text":6379},"!important как исключение, а не инструмент",{"id":4776,"depth":64,"text":4777,"children":6381},[6382,6383,6385,6387],{"id":4780,"depth":751,"text":4781},{"id":4892,"depth":751,"text":6384},"box-sizing: content-box против border-box",{"id":5011,"depth":751,"text":6386},"Абсолютные и относительные единицы: px, em, rem, %",{"id":5137,"depth":751,"text":6388},"Современные единицы и функции: ch, dvh, svw, clamp, min, max",{"id":5332,"depth":64,"text":5333},{"id":5413,"depth":64,"text":5414,"children":6391},[6392,6393,6394,6395],{"id":5417,"depth":751,"text":5418},{"id":5608,"depth":751,"text":5609},{"id":5756,"depth":751,"text":5757},{"id":5905,"depth":751,"text":5906},{"id":5951,"depth":64,"text":5952,"children":6397},[6398,6400],{"id":5958,"depth":751,"text":6399},"Автоматическая тема через prefers-color-scheme",{"id":6111,"depth":751,"text":6401},"Ручное переключение темы: атрибут на html, синхронизация с localStorage",{"id":2458,"depth":64,"text":2459},{"id":2484,"depth":64,"text":2485},{},"\u002Fcourses\u002Faidt-mag-frontend\u002Ftopic-02-content",{"title":2562,"description":2570},"courses\u002Faidt-mag-frontend\u002Ftopic-02-content","topic-02","30736zjSztZlQffIyKuHnJMAW3BIeRGQfrAXnzERFIs",1779455410464]