Pull to refresh
45
0
Andrew Fedoniouk @csmile

User

Send message
Это для примера.

В одном placeholder Grid Layout допускает несколько элементов. Как они будут подстраиваться? Или как грид их будет подстраивать? Как сказать
все элементы в этом placeholder должны иметь одинаковую ширину и эта ширина должна быть не меньше max-width самого широкого?

А вообще смыслов таблиц из одной ячейки может быть много.
Например иногда имеет смысл написать так:

pre { display:table-cell; }


тогда ширина pre будет равна самой широкой строки ибо table/cell фактически ведет себя как если бы он объявлен как width:max-content
Да? А как? Например есть #grid из одного столбца/колонки:

#grid1x1 { 
  grid-rows: 1gr
  grid-columns: 1gr
}


И у него пара-тройка children. Под какой контент и как оно будет подстраиваться?
Ну во первых by design элементы могут рисоваться поверх соседей.
А во вторых представим себе grid с такими вот columns:

grid-columns: 150px 1fr 200px;

и скажем в первой колонке оказался элемент с width:300px или min-width:300px.
Или юзер выставил шрифт поболее и content width стала больше чем 150px.
Результат будет не сильно привлекательный.

Основной недостаток(?) Grid Layout состит в том что он использует т.н. placeholder model — поверхность разбивается на placeholders — виртуальные прямоуголники в которых уже помещаются реальные элементы. Причем как-то совершенно грустно и не по CSS-овски. Скажем есть внутри элемент с width:100%. Этот width он отнсительно чего расчитывается? Про placeholder'ы CSS box model ничего не знает.

Таблицы же используют строго position:static layout. Вся поверхность конейнера заполнена реальными DOM элементами. При этом контент соседних ячеек друг на друга не залазит. Ибо каждая ячейка это BFC.

Мой flow:«template» использует table model. Собственно под капотом там table engine и используется. Т.е. layout и размеры определяются по правилам таблиц, это вот:

#container { 
  flow: "1 1"
        "2 3";
}
Описывает таблицу в которй первый child занимает полный ряд (первую и вторую колонку) а второй и третий соответсвенно живут во втором ряду.
Размеры как я уже сказал — по принципу tables — с учетом min/max-width и пр.

Это к сожалению никак не таблицы. И воспроизвести «резиновость» таблиц не удастся.
Уникальность таблиц состоит в том что каждая ячейка это устанавливает так называемый BFC — block formatting context. Т.е. в условиях overflow:visible сродержимое ячеек друг на друга «не залазит». Здесь же — легко.

Стоит бы отметить что grid layout это не position:static размещение, а вариация position:absolute|fixed.

Собственно grid layout можно воспрозвести руками и сейчас задав position:fixed всем элементам. Управляя left/top/right/bottom можно воспроизвести start/end/stretch позиционирование. Но position:fixed хотя бы можно управлять z-index.

D есть метрика глубины самого DOM и используемых descendant selectors.
Если система стилей не использует descendant selectors, а имеет только два правила (S=2):
#id {color:red}
.cls {color:blue}

то D в этом случае равно 1. Системе не требутеся просматривать parent chain на предмет ответа уволетворяет ли селектор или нет.

Если же мы имеем набор правил вида
.super #id {color:red}
.super .cls {color:blue}

то для проверки таких селекторов нам нужно просмотреть весь parent chain каждого элемента. В худшем случае на полную глубину вплоть до root (html) элемента включительно. В этом случае метрика D есть средняя глубина элементов в DOM.
Т.е. метрика D не точная — зависит от конфигурации дерева.

Давай представим такой документ
<div #n0>0</div>
<div #n1>1</div>
<div #n2>2</div>
<div #n3>3</div>
...
<div #n9>9</div>

И набор правил
div { background:gold; }
#n1 { color:red; }

Для определения полной картины нужно пройтись по всем N=10 элементам и последовательно проверить оба селектора  (S=2).
Итого строго по формуле O(N*S*D) -> 10*2*1 = 20 операций проверки селекторов.

Никакие индексы тут не помогут.
N2 с точки зрения computational complexity theory есть точная оценка сложности :has(...) селектора.

Представим себе такой документ:

<div>
  <div>
    <div>
      <a>...</a>
    </div> 
  </div> 
</div>

и правило  
div:has(a) { color:red }

Количество элементов внутри root элемента здесь N=3
Назначаем стили:
Для первого DIV (root) элемента требуется просмотр n=3 детей (пока найдем <a>).
Для второго DIV элемента  n=2
Для третьего n=1
Итого 6 просмотров, что для данного случая  N * (N + 1) / 2  
Что и есть O(N2) сложность с точки зрения теории.

См. сообщение выше «Вот баг про это: bugs.webkit.org/show_bug.cgi?id=60752 ....»
Индекс по ID нужен для эффективного исполнения функции getElementByID().

Если же у тебя есть, скажем, такие CSS правила

body.mode1 #one { color:red }
body.mode2 #one { color:green }
body.mode1 a { color:blue }
body.mode2 a { color:orange }


и ты меняешь класс у body c mode1 на mode2 то ты просто обязан пересчитать все стили внутри body. При этом есть у элемента ID или нет — не важно абсолютно.
Для того чтобы проверить элемент body на предмет соответствия body:has(a.cool) селектору нужно просмотреть все N-1 его детей. Т.е. не просто сам элемент и его D parents, а еще и детей.
Т.е. в общем случае сложность выражается как O(N*S*D*N) -> O(N2).
Ну во первых никто не гарантирует что элемент с данным id он один. Уникальность id это рекомендация. Не более.

С точки зрения CSS id это такой же атрибут как и любой другой. Просто #id селектор имеет больший вес. Все CSS имплементации раcсчитанны на «неуникальность» ID.

Про скорость. Представь себе документ в начальном состоянии. Расчет стилей в этом случае это все те же O(N*S*D). id никак не помогают.

td { color:red } и #id { color:red } имеют в принципе одну и ту же сложность. Если представить что DOM элемент внутри выглядит как-то так:
struct  Element {
  symbol_t tag;
  symbol_t id;
  ...
}

(symbol_t это int) то сравнение с id и сравнение с tag идентично.

Честно говоря не знаю откуда эта «мулечка» про "#id < .class < tag" появилась.
Извиняюсь. Отвык от писания по русски.
«Может быть, в каких-то случаях наоборот все же?»

А наоборот это как? Что имеется ввиду?
Ну тест там простой и безхитростный.
Если FAILED то это значит что Safari пытается использовать некую оптимизацию которая ломает селекторы.
Алгоритм прост и изложен здесь www.w3.org/TR/CSS2/cascade.html#cascade

Есть набор из S правил (selector/properties). Этот набор сортируется по selector specificity.
И для каждого DOM элемента n просматриваются все S правил в указаном порядке.

Для составных селекторов сначала проверяется самый правый селектор и далее справа налево по цепочке parents.

С точки зрения CPU эти вот два селектора:

td { color:red }
#id { color:red }


имеют одинаковую сложность (у меня это сравнение двух int).

А селектор:
.cls1 { color:red }
несколько более сложен для определения(у меня это — поиск int в массиве int)

Что такое «скорость работы самого селектора» и это вот "#id < .class < tag"?
Нет, она не обязательно выражается именно так.

Именно так selector complexity и выражается если следовать спецификации.

По поводу оптимизаций… да они могут уменьшить нагрузку в некоторых случаях.
Скажем есть эвристика которая неким магическим образом исключает из просмотра половину style rules т.е.
можно записать O( N * (S*0.5) * D ) что c точки зрения теории равно всё тем же
O( N * S * D ). Если есть сомнения то вот en.wikipedia.org/wiki/Big_O_notation

Собственно это проблема и есть основная причина по которой в CSS никогда не будет селекторов типа:

body:has(a.cool) { color:red }

Ибо в таком случае (has-something-inside selectors) сложность скачком возрастает до квадратичной — O(N2). Это вообще убьет Web.

Information

Rating
Does not participate
Location
Richmond, British Columbia, Канада
Date of birth
Registered
Activity