Skip to content
Open
Show file tree
Hide file tree
Changes from 85 commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
461bb27
WebComponents. Тег <slot>
DrakesBot12 Aug 4, 2025
2eeb589
Добавляю пустую строку
DrakesBot12 Aug 4, 2025
355265d
Добавляю <slot> в HTML
DrakesBot12 Aug 4, 2025
07f9b85
Добавляю Атрибут part в HTML
DrakesBot12 Aug 4, 2025
96fd426
Исправляю ошибки линтера
DrakesBot12 Aug 4, 2025
db2e7b0
Исправляю ошибки линтера
DrakesBot12 Aug 4, 2025
206f118
Добавляю Атрибут exportparts в HTML
DrakesBot12 Aug 4, 2025
d026809
Добавляю Атрибут exportparts в HTML
DrakesBot12 Aug 4, 2025
56bc8a1
Добавляю Псевдоклассы :host & :host() в CSS
DrakesBot12 Aug 4, 2025
d3d78ea
Исправляю ошибки линтера
DrakesBot12 Aug 4, 2025
441a62a
Исправляю ошибки линтера
DrakesBot12 Aug 4, 2025
e36fcbd
Исправляю ошибки линтера
DrakesBot12 Aug 4, 2025
d07abdb
Добавляю Псевдокласс :defined в CSS
DrakesBot12 Aug 4, 2025
728584b
Добавляю Псевдокласс :state() в CSS
DrakesBot12 Aug 4, 2025
3a4bcde
Добавляю Псевдоэлемент ::slotted() в CSS
DrakesBot12 Aug 4, 2025
ddb9411
Добавляю Глобальный объект window.customElements в JS
DrakesBot12 Aug 4, 2025
0a5de73
Исправляю ошибки линтера
DrakesBot12 Aug 4, 2025
3124b26
Исправляю ошибки линтера
DrakesBot12 Aug 4, 2025
43d3b7e
Добавляю Псевдоэлемент ::part() в CSS
DrakesBot12 Aug 4, 2025
5850b58
Исправляю ошибки линтера
DrakesBot12 Aug 4, 2025
c034746
Добавляю Element метод .attachShadow() в JS
DrakesBot12 Aug 4, 2025
5e1fb35
Добавляю Element свойство .shadowRootw в JS
DrakesBot12 Aug 4, 2025
841269b
Добавляю Element свойство .shadowRootw в JS
DrakesBot12 Aug 4, 2025
5ae6cbe
Добавляю Element свойство .shadowRoot в JS
DrakesBot12 Aug 4, 2025
fa45c15
Улучшаю доки
DrakesBot12 Aug 5, 2025
a3d6570
Добавляю Атрибут is в HTML
DrakesBot12 Aug 5, 2025
1e9c233
Добавляю Атрибут is в HTML
DrakesBot12 Aug 5, 2025
6b6fe5b
Улучшаю доки
DrakesBot12 Aug 5, 2025
ee05163
Улучшаю доки
DrakesBot12 Aug 5, 2025
45085d5
Добавляю Событие composed и Событие composedPth() в JS
DrakesBot12 Aug 5, 2025
06c2b9b
Добавляю Событие composed и Событие composedPath() в JS
DrakesBot12 Aug 5, 2025
36cc7d2
Улучшаю доки
DrakesBot12 Aug 5, 2025
7e862be
Улучшаю доки
DrakesBot12 Aug 5, 2025
31621b5
Добавляю Интерфейс CustomStateSet в JS
DrakesBot12 Aug 5, 2025
0f717fd
Улучшаю доки
DrakesBot12 Aug 5, 2025
b8d2c12
Улучшаю доки
DrakesBot12 Aug 5, 2025
b27a2a4
Улучшаю доки
DrakesBot12 Aug 5, 2025
254f8e5
Улучшаю доки
DrakesBot12 Aug 5, 2025
386b813
Улучшаю доки
DrakesBot12 Aug 5, 2025
994a5e3
Улучшаю доки
DrakesBot12 Aug 5, 2025
bf46801
Добавляю Интерфейс ShadowRoot в JS
DrakesBot12 Aug 5, 2025
5d34ac5
Добавляю Интерфейс ShadowRoot в JS
DrakesBot12 Aug 5, 2025
af7f178
Добавляю Интерфейс ShadowRoot в JS
DrakesBot12 Aug 5, 2025
5a46eb9
Исправляю ошибки линтера
DrakesBot12 Aug 5, 2025
7787215
Исправляю ошибки линтера
DrakesBot12 Aug 5, 2025
c749ed6
Исправляю ошибки линтера
DrakesBot12 Aug 5, 2025
3598b2c
Улучшаю доки
DrakesBot12 Aug 5, 2025
39570d1
Улучшаю доки
DrakesBot12 Aug 5, 2025
c1262d6
Добавляю Интерфейс ShadowDOM в JS
DrakesBot12 Aug 5, 2025
b9aa147
Добавляю Интерфейс ShadowDOM в JS
DrakesBot12 Aug 5, 2025
229b8e2
Улучшаю доки
DrakesBot12 Aug 5, 2025
470ab82
Улучшаю доки
DrakesBot12 Aug 5, 2025
aef1453
Улучшаю <template> в HTML
DrakesBot12 Aug 5, 2025
610d3fe
Добавляю Статью Web components в Веб-платформа
DrakesBot12 Aug 5, 2025
a2fc841
Улучшаю доки
DrakesBot12 Aug 5, 2025
cb49de9
Улучшаю доки
DrakesBot12 Aug 5, 2025
14a2010
Улучшаю доки
DrakesBot12 Aug 5, 2025
bbac1f3
Улучшаю доки
DrakesBot12 Aug 6, 2025
5c12efc
Улучшаю доки
DrakesBot12 Aug 6, 2025
65d398d
Добавляю Доку про :has-slotted в CSS
DrakesBot12 Aug 6, 2025
4431e0e
Добавляю Доку про :has-slotted в CSS
DrakesBot12 Aug 6, 2025
ddbd401
Исправляю ошибки линтера
DrakesBot12 Aug 6, 2025
cb738ec
Улучшаю доки
DrakesBot12 Aug 6, 2025
195226b
Улучшаю доки
DrakesBot12 Aug 6, 2025
344bdea
Улучшаю доки
DrakesBot12 Aug 6, 2025
2e51740
Делаем доку лучше :^
DrakesBot12 Aug 6, 2025
92fa79e
Улучшаю доки
DrakesBot12 Aug 6, 2025
9ed66e3
Делаем доку лучше
DrakesBot12 Aug 6, 2025
e54adc1
Делаем доку лучше :^
DrakesBot12 Aug 6, 2025
c246397
Добавляю baseline ко всем HTML и CSS докам
DrakesBot12 Aug 6, 2025
d12a3e2
Делаем доку лучше
DrakesBot12 Aug 6, 2025
d8527f7
Добавляю baseline ко всем JS докам (и чуть-чуть к HTML и CSS)
DrakesBot12 Aug 6, 2025
fca408c
Делаем доку лучше :^
DrakesBot12 Aug 6, 2025
e486b5f
Делаем доку лучше :^
DrakesBot12 Aug 6, 2025
70c4817
Делаю доки лучше
DrakesBot12 Aug 7, 2025
45d7d3d
Делаем доку лучше
DrakesBot12 Aug 7, 2025
5b9665f
Делаю доки лучше
DrakesBot12 Aug 7, 2025
5b6c626
Делаю доки лучше
DrakesBot12 Aug 7, 2025
4b2faad
Делаю доки лучше
DrakesBot12 Aug 7, 2025
85ef3e4
Делаю доки лучше
DrakesBot12 Aug 7, 2025
03e5b62
Делаю доки лучше
DrakesBot12 Aug 7, 2025
09ae0fc
Делаем доку лучше :^
DrakesBot12 Aug 8, 2025
dce6ef3
Делаю доки лучше
DrakesBot12 Aug 8, 2025
7a470b4
Merge branch 'main' into web-components
DrakesBot12 Aug 8, 2025
18e7c07
Делаем доку лучше
DrakesBot12 Aug 11, 2025
8c64ba2
Делаем доку лучше :^
DrakesBot12 Aug 12, 2025
86f057e
Merge branch 'main' into web-components
DrakesBot12 Aug 13, 2025
ac55488
Делаем доку лучше :^
DrakesBot12 Aug 13, 2025
b4d60ba
Небольшие правки :^
DrakesBot12 Aug 13, 2025
3966584
Делаем доку лучше :^
DrakesBot12 Sep 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 166 additions & 0 deletions css/defined/demos/basic/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<title>Демонстрация :defined — :defined — Дока</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap">
<style>
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}

html {
color-scheme: dark;
}

body {
min-height: 100vh;
padding: 50px;
display: flex;
align-items: center;
justify-content: center;
background-color: #18191C;
color: #FFFFFF;
font-family: "Roboto", sans-serif;
}

@media (max-width: 768px) {
body {
padding: 30px;
}
}

.container {
display: flex;
flex-direction: column;
gap: 2rem;
align-items: center;
}

custom-element, custom-element:not(:defined) {
display: block;
min-width: 320px;
min-height: 120px;
border: 2px solid;
border-radius: 1rem;
font-size: 1.2rem;
padding: 2rem 1.5rem;
position: relative;
background: none;
transition: all 0.3s;
}

custom-element:not(:defined) {
border-color: grey;
color: grey;
background: #222;
}

custom-element:defined {
background-color: wheat;
border-color: black;
color: black;
}

/* Показываем сообщение загрузки */
custom-element:not(:defined)::before {
content: "Загрузка…";
position: absolute;
inset: 0 0 0 0;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
font-size: 2rem;
background-color: #fff;
color: #222;
border-radius: 1rem;
z-index: 1;
pointer-events: none;
}

/* Убираем сообщение после определения */
custom-element:defined::before {
content: "";
display: none;
}

button {
font-family: inherit;
font-size: 1.1rem;
padding: 0.7em 1.5em;
border-radius: 0.7em;
border: none;
background: #ff8630;
color: #fff;
font-weight: 500;
cursor: pointer;
transition: background 0.2s;
}
button:hover, button:focus {
background: #ffb47f;
color: #222;
}
</style>
</head>
<body>
<div class="container">
<custom-element>
<h1 slot="title">Кастомный элемент</h1>
<p slot="content">Контент появился после инициализации</p>
</custom-element>
<button id="btn">Определить элемент</button>
</div>
<template id="custom-element-template">
<style>
.card {
border-radius: 16px;
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
padding: 24px 27px;
min-width: 320px;
max-width: 400px;
display: flex;
flex-direction: column;
gap: 16px;
background: #fffbe7;
}
::slotted(h1) {
font-weight: bold;
color: #FF8630;
margin-bottom: 8px;
font-size: 2rem;
}
::slotted(p) {
font-size: 1.2rem;
}
</style>
<div class="card">
<slot name="title">Пустой элемент 😔</slot>
<slot name="content"></slot>
</div>
</template>
<script>
const btn = document.querySelector("#btn");

btn.addEventListener("click", () => {
if (!customElements.get("custom-element")) {
class CustomElement extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: "open" });
const template = document.getElementById("custom-element-template");
shadow.appendChild(template.content.cloneNode(true));
}
}
customElements.define("custom-element", CustomElement);
}
btn.remove();
});
</script>
</body>
</html>
125 changes: 125 additions & 0 deletions css/defined/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
---
title: "`:defined`"
description: "Псевдокласс `:defined` позволяет применять стили только к тем элементам, которые уже зарегистрированы как кастомные компоненты."
authors:
- drakesbot12
keywords:
- кастомные
- элементы
- web-components
- custom-elements
- :defined
- shadow
- dom
related:
- css/host
- html/part
- js/element-attachshadow
tags:
- doka
---

## Кратко

Псевдокласс `:defined` выбирает только те элементы, которые уже зарегистрированы в браузере как кастомные. Это позволяет стилизовать только определённые компоненты и, например, задать разные стили до и после их инициализации.

## Пример

```html
<div class="container">
<custom-element>
<h1 slot="title">Кастомный элемент</h1>
<p slot="content">Контент появился после инициализации</p>
</custom-element>
<button id="btn">Определить элемент</button>
</div>

<template id="custom-element-template">
<style>
::slotted(h1) {
font-weight: bold;
color: #FF8630;
margin-bottom: 8px;
font-size: 2rem;
}

::slotted(p) {
font-size: 1.2rem;
}
</style>
<div class="card">
<slot name="title">Пустой элемент 😔</slot>
<slot name="content"></slot>
</div>
</template>
```

```css
custom-element:not(:defined) {
border-color: grey;
color: grey;
background: #222;
}

custom-element:defined {
background-color: wheat;
border-color: black;
color: black;
}
```

```js
const btn = document.querySelector("#btn");

btn.addEventListener("click", () => {
if (!customElements.get("custom-element")) {
class CustomElement extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: "open" });
const template = document.getElementById("custom-element-template");
shadow.appendChild(template.content.cloneNode(true));
}
}
customElements.define("custom-element", CustomElement);
}
btn.remove();
});
```

<iframe title="Демонстрация :defined" src="demos/basic/" height="320"></iframe>

## Как пишется

Псевдокласс используется как обычный селектор:

```css
web-component:defined {
/* стили, когда компонент зарегистрирован */
}
```

Можно комбинировать с другими селекторами:

```css
my-box:defined:hover {
box-shadow: 0 0 10px rgba(0,0,0,0.2);
}
```

## Как понять

Когда вы вставляете на страницу кастомный элемент вроде `<my-widget>`, он сначала появляется как неизвестный тег. До тех пор, пока скрипт не выполнится и не вызовет [`customElements.define('my-widget', ...)`](/js/window-customelements), он считается неопределённым.

Псевдокласс `:defined` позволяет разделить стили до и после определения. Это особенно удобно для:

- Плавной загрузки интерфейса
- Предотвращения странной отрисовки до инициализации
- Анимаций и переходов после готовности

## Подсказки

💡 Если компонент уже определён до вставки в [DOM](/js/dom/) — `:defined` сработает сразу.
💡 Полезно использовать `:not(:defined)`, чтобы стилизовать «заглушки» до загрузки компонентов.
💡 Работает только с кастомными тегами — вроде `<my-dialog>`. Не применимо к обычным HTML-тегам.
💡 Можно использовать как индикатор загрузки — например, показывать лоадер внутри неинициализированного компонента.
80 changes: 80 additions & 0 deletions css/has-slotted/demos/basic/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<title>:has-slotted — пример — :has-slotted — Дока</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap">
<style>
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}

html {
font-size: 16px;
color-scheme: dark;
}

body {
min-height: 100vh;
padding: 50px;
display: flex;
font-size: 2rem;
align-items: center;
justify-content: center;
background-color: #18191C;
color: #FFFFFF;
font-family: "Roboto", sans-serif;
}

@media (max-width: 768px) {
body {
padding: 30px;
}
}

.container {
display: flex;
align-items: center;
flex-direction: column;
gap: 1rem;
}
</style>
</head>
<body>
<template id="my-element-template">
<style>
:has-slotted {
color: green;
}
:not(:has-slotted) {
color: red;
}
</style>
<slot><code>:has-slotted</code> Не работает!</slot>
</template>
<div class="container">
<my-element>
<code>:has-slotted</code> Работает!
</my-element>
<my-element></my-element>
</div>

<script>
class MyElement extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
const template = document.getElementById('my-element-template');
shadow.appendChild(template.content.cloneNode(true));
}
}

customElements.define('my-element', MyElement);
</script>
</body>
</html>
Loading
Loading