#css
Вопрос:
Это довольно специфическая проблема, и я не удивлюсь, если ее невозможно решить. Допустим, у меня есть следующий html-код, который я вообще не могу изменить:
lt;boxgt; lt;tab class="A" id="A1"gt;...lt;/tabgt; lt;tab class="A" id="A2"gt;...lt;/tabgt; lt;tab class="A" id="A3"gt;...lt;/tabgt; ... lt;tab class="B" id="B1"gt;...lt;/tabgt; lt;tab class="B" id="B2"gt;...lt;/tabgt; lt;tab class="B" id="B3"gt;...lt;/tabgt; ... lt;/boxgt;
Количество вкладок A и B варьируется. Используя только CSS, я хотел бы добиться следующего поведения:
1: Вкладки должны располагаться рядами и переноситься в следующую строку, как только они превысят ширину поля (которая ограничена только шириной экрана). (Это самая легкая часть. Я уже знаю, как это сделать с помощью flex, но я не привержен одному конкретному методу.)
|A1 A2 A3 B1| |B2 B3 |
2: Но что я хотел бы видеть, так это то, что все элементы B переносятся на следующую строку сразу, как если бы они были одним элементом. Я также нашел способ сделать это, вставив невидимый элемент разрыва строки с ::before и присвоив ему значение «порядок», которое помещает его между A3 и B1.
|A1 A2 A3 | |B1 B2 B3 |
3: Однако это означает, что для каждого типа элемента всегда есть минимум 2 строки. Поведение, которого я пытаюсь добиться, заключается в том, что если все элементы помещаются внутри ширины поля, все они должны оставаться на одной линии и переноситься только способом, описанным в 2, как только ширина будет превышена. Подобный этому:
|A1 A2 B1 B2|
Добавлена новая вкладка:
|A1 A2 | |B1 B2 B3 |
Комментарии:
1. Привет:) что такое
tab
?2. Это слишком сложно для CSS. Используйте для этого JS
3. Html-элемент @Azu с именем tagname
tab
:lt;tab class="b"gt;
Ответ №1:
Без переформатирования HTML реализация нескольких условных if-операторов Javascript может упростить задачу, поскольку вы все еще можете напрямую ориентироваться на имя класса.
Если вы можете каким-то образом переформатировать HTML, возможно, будет проще управлять, создав 2 новых элемента HTML div в элементе box (по 1 для каждого типа класса), чтобы упростить управление с помощью flex-box.
Ответ №2:
Я нашел решение. Предполагая, что ширина коробки соответствует ровно 4 вкладкам (это, конечно, должно быть математически обобщаемо для других случаев. Мой реальный случай намного сложнее, так как ширина коробки составляет примерно 10 B-вкладок, а B-вкладки в 4 раза шире, чем A-вкладки. Я упрощаю здесь для понятности.):
Коробка выполнена в виде гибкой коробки:
box { display: flex; flex-wrap: wrap; overflow-y: auto; }
При этом вставляется разрыв строки со значением заказа 1 (по умолчанию он сортируется после элементов без свойства order):
box::after { display: flow-root list-item; order: 1; content: ""; flex-basis: -moz-available; height: 0px; }
Это говорит о том, что каждый элемент B сразу после элемента A, подлежащего сортировке после разрыва строки, если элементы A и B вместе превышают строку (для этого потребуется как минимум столько селекторов, разделенных запятыми, сколько количество вкладок B, которые могут поместиться в ширину поля).:
.A:nth-child(n 4) .B:nth-last-of-type(n 1), .A:nth-child(n 3) .B:nth-last-of-type(n 2), .A:nth-child(n 2) .B:nth-last-of-type(n 3), .A:nth-child(n 1) .B:nth-last-of-type(n 4) { order: 2; }
Это говорит последующим элементам сделать то же самое:
.A:nth-child(n 4) .B:nth-last-of-type(n 1) ~ *, .A:nth-child(n 3) .B:nth-last-of-type(n 2) ~ *, .A:nth-child(n 2) .B:nth-last-of-type(n 3) ~ *, .A:nth-child(n 1) .B:nth-last-of-type(n 4) ~ * { order: 2; }
Теоретически должно быть возможно объединить эти два блока с помощью вложенности:
.A:nth-child(n 4) .B:nth-last-of-type(n 1), .A:nth-child(n 3) .B:nth-last-of-type(n 2), .A:nth-child(n 2) .B:nth-last-of-type(n 3), .A:nth-child(n 1) .B:nth-last-of-type(n 4) { order: 2; ~ * { order: 2; } }
Однако в моем случае это не сработало. Я пытаюсь изменить стиль пользовательского интерфейса браузера, и, по-видимому, он не принимает вложенность.
Если у кого-нибудь есть предложения о том, как это еще больше упростить, это более чем приветствуется.