Чи можуть медіа-запити змінювати розмір на основі елемента div, а не екрана?


317

Я хотів би використовувати медіа-запити для зміни розміру елементів залежно від розміру divелемента, в якому вони перебувають. Я не можу використовувати розмір екрана, оскільки divвін просто використовується як віджет на веб-сторінці, і його розмір може змінюватися.

Оновлення

Схоже, зараз над цим працює робота: https://github.com/ResponsiveImagesCG/cq-demos


2
Я думаю, що це запитання є занадто коротким, щоб отримати хорошу відповідь. Можливо, ви могли б навести приклад того, що ви намагаєтесь зробити? Можливо, скористайтеся jsfiddle.net, щоб перевірити свою ідею та дозволити іншим допомогти вам? Зазвичай у вас не повинно бути причин для того, що ви запитуєте, ви повинні мати можливість досягти бажаних результатів за допомогою CSS без медіа-запитів. Можна використовувати відсоткові розміри та ems для шрифтів для масштабування вкладених елементів. Але, можливо, мені просто потрібно побачити приклад вашого html-коду та css, щоб краще зрозуміти?
BenSwayne

1
Як може змінюватися розмір вашого віджета? Чи ваша сторінка фіксованої ширини (960 пікселів на прикладі) із вікнами перегляду вище 1024 пікселів або обидва є текучими? Це незрозуміло і було б корисно знати
FelipeAls

3
Власне, у мого поточного проекту є подібна ситуація. Перелік елементів відображається у двокольоровому макеті для широких пристроїв або в однокольоровому макеті для вузьких пристроїв, однак один елемент буде розміщений у макетці з одним колом, незалежно від того. Як у списку, так і в єдиній версії є 2 елемента, які є досить широкими та короткими. На більш широких пристроях два елементи найкраще виглядають поруч. В ідеалі вузькі пристрої: завжди вертикальні, широкі пристрої: завжди паралельні, десь між (залежно від 1 або 2-кол.): Вертикальні чи паралельні. Плаваючий - це просте рішення, але ширина також має змінюватися залежно від компонування.
cimmanon

1
Менше буде скомпільовано до CSS, тому якщо CSS не підтримує його, LESS також не зможе вам допомогти.
jvannistelrooy

3
Посилання більше не активне?
mix3d

Відповіді:


228

Ні, медіа-запити не розроблені на основі елементів на сторінці. Вони розроблені для роботи на основі пристроїв або типів носія (звідси їх називають медіа- запитами). width, heightта інші засоби носія, що базуються на вимірах, усі стосуються розмірів або області перегляду, або екрана пристрою на екрані носія. Їх не можна використовувати для позначення певного елемента на сторінці.

Якщо вам потрібно застосувати стилі залежно від розміру певного divелемента на своїй сторінці, вам доведеться використовувати JavaScript, щоб спостерігати за змінами розміру цього divелемента замість медіа-запитів.


Я чув про те, як я можу використовувати функції з медіа-запитами, щоб отримати розмір з елемента, що містить. Чи я можу поєднати це з медіа-запитами, щоб змінити розмір елементів?
Yazz.com

1
Вам доведеться використовувати JS, щоб періодично отримувати ширину вашого елемента і реагувати відповідно (періодично = щосекунди або близько того, або це сповільнить деякі браузери; відповідно = шляхом перемикання класів, що стилюють ваш віджет, якщо ви хочете найшвидший метод).
FelipeAls

6
Щоб виконати це спочатку, нам потрібні @elementзапити. W3C має хорошу документацію щодо рифми / причини @mediaзапитів: w3.org/TR/css3-mediaqueries/#width (це посилання переносить вас до розділу, де обговорюються ширини --- ширини типу носія, а не елементи, що містяться в ньому)
Доусон

Будь-який шанс змусити його працювати в електронних листах? Я намагаюся застосувати мобільний стиль для електронних листів, коли роздільник контейнерів занадто малий (тобто коли простір електронної пошти версії Gmail для робочого столу занадто малий, щоб підходити до дизайну з двома стовпцями, наприклад, через розмір вікна).
Лев

До речі, @element запити перетворили б css на повну мову Тюрінга
Nick

117

Я щойно створив тривогу javascript для досягнення цієї мети. Погляньте, якщо хочете, це підтвердження концепції, але будьте уважні: це рання версія і все ще потребує певної роботи.

https://github.com/marcj/css-element-queries


5
Дякую, я вражений
Yazz.com

5
Це неймовірно. У поєднанні з чуйним завантажувальним інструментом я роблю чудові речі, яких неможливо досягти за допомогою просто @media. Молодці.
Аку,

3
Ви врятували наше життя
Брода Ноель

Нічого собі, по-справжньому приємно, все набагато простіше
кайзер

Класно. Поставте питання. Зараз цей плагін виявляє - які елементи потребують min-widthвідновлення атрибута; чи потрібно вручну писати список класів css, позначені елементи, увімкнено для min-widthоновлення?
Олександр Гончаров

38

Медіа-запит всередині iframe може функціонувати як елемент запиту. Я успішно реалізую це. Ідея виникла з недавнього допису про чуйну рекламу Zurb. Немає Javascript!


Я думаю, що це найкраще рішення, тому що медіа-запити працюють у рамках iframe.
емфі

25

Наразі це неможливо лише для CSS, як @BoltClock писав у прийнятій відповіді, але ви можете обійти це за допомогою JavaScript.

Я створив запит на контейнер (ака-елемент запит) для заповнення такого роду проблем. Він працює трохи інакше, ніж інші сценарії, тому вам не доведеться редагувати HTML-код своїх елементів. Все, що вам потрібно зробити, це включити скрипт і використовувати його у своєму CSS так:

.element:container(width > 99px) {
    /* If its container is at least 100px wide */
}

https://github.com/ausi/cq-prolyfill


2
Це повно JS. Мета - функціональність лише у CSS.
Зелений

13
Проліфілі (та поліфіли ) зазвичай записуються у JS, щоб увімкнути функцію, яка ще не підтримується браузером. Завдання prolyfill - застаріти після підтримки цієї функції в CSS.
ausi

3
@ius в запитанні не згадується "лише CSS". Як ти дійшов такого висновку?
ausi

1
@ius крім вас не може , можливо , зробити це в CSS так пропонує рішення поза CSS цілком розумно. Набагато краще, ніж "ні ти не можеш", ти не думаєш;)
Веслі Сміт

1
@ В захваті від мого коментаря, він змінив відповідь, і я проголосував +1 за зміну. Поточна відповідь, що для мене це нормально, оскільки говорить, що це неможливо лише для CSS.
ius

17

Я зіткнувся з тією ж проблемою пару років тому і фінансував розробку плагіна, щоб допомогти мені в роботі. Я випустив плагін як відкритий код, щоб і інші могли отримати з нього користь, і ви можете схопити його на Github: https://github.com/eqcss/eqcss

Є декілька способів, як ми могли застосувати різні стилі, що реагують на основі того, що ми можемо знати про елемент на сторінці. Ось кілька запитів елементів, завдяки яким плагін EQCSS дозволить вам писати в CSS:

@element 'div' and (condition) {
  $this {
    /* Do something to the 'div' that meets the condition */
  }
  .other {
    /* Also apply this CSS to .other when 'div' meets this condition */
  }
}

Отже, які умови підтримуються для чуйних стилів з EQCSS?

Вага запитів

  • міні-ширина в px
  • міні-ширина в %
  • Максимальна ширина дюйма px
  • Максимальна ширина дюйма %

Висота запитів

  • мінімальна висота в px
  • мінімальна висота в %
  • Макс-висота в px
  • Макс-висота в %

Підрахунок запитів

  • міні-символи
  • макс-символів
  • міні-рядки
  • макс-лінії
  • міні-діти
  • макс-діти

Спеціальні селектори

Всередині запитів елементів EQCSS ви також можете використовувати три спеціальні селектори, які дозволяють більш конкретно застосовувати ваші стилі:

  • $this (елемент (и), що відповідають запиту)
  • $parent (батьківський елемент (и) елемента (и), що відповідає запиту)
  • $root(кореневий елемент документа, <html>)

Запити елементів дозволяють складати ваш макет із індивідуально реагуючих модулів дизайну, кожен з яких має трохи «усвідомлення себе» того, як вони відображаються на сторінці.

Завдяки EQCSS ви можете розробити один віджет, щоб він виглядав добре від 150 пікселів в ширину до ширини 1000 пікселів, тоді ви можете впевнено скинути цей віджет на будь-яку бічну панель будь-якої сторінки, використовуючи будь-який шаблон (на будь-якому сайті) і


1
Гарний проект! Я подивився на те, що ви зробили
Yazz.com

@innovati Я знайшов цю публікацію, шукаючи спосіб робити запити по елементах. Я не можу, здається, змусити його працювати. Чи не проти заглянути мій квиток? github.com/eqcss/eqcss/isissue/96
Ендрю Ньюбі

10

З точки зору компонування, це можливо з використанням сучасних методик.

Його склав (я вважаю) Гейдон Пікерінг. Він детально описує процес тут: http://www.heydonworks.com/article/the-flexbox-holy-albatross

Кріс Койєр підбирає його і працює через демонстрацію цього тут: https://css-tricks.com/putting-the-flexbox-albatross-to-real-use/

Щоб відновити проблему, нижче ми бачимо 3 одного і того ж компонента, кожен з яких складається з трьох помаранчевих символів, що позначаються a, bі c.

Блоки другого блоку відображаються вертикально, оскільки вони обмежені горизонтальним приміщенням, тоді як верхні компоненти 3 блоків розташовані горизонтально.

flex-basisДля створення цього ефекту використовується властивість CSS та змінні CSS.

Заключний приклад

.panel{
  display: flex;
  flex-wrap: wrap;
  border: 1px solid #f00;
  $breakpoint: 600px;
  --multiplier: calc( #{$breakpoint} - 100%);
  .element{
    min-width: 33%;
    max-width: 100%;
    flex-grow: 1;
    flex-basis: calc( var(--multiplier) * 999 );
  }
}

Демо

Стаття Гейдона - це 1000 слів, де це детально пояснюється, і я дуже рекомендую її прочитати.


Це з статті Гейдона ... Виглядає і працює як магія! Дякую за вашу відповідь, це приголомшливо.
ptyskju

2
Це відповідь, яку шукають усі, хто
стикається

7

Питання дуже розпливчасте. Як каже BoltClock, медіа-запити знають лише розміри пристрою. Однак ви можете використовувати медіа-запити в поєднанні з селектором для зменшення настрою для виконання налаштувань.

.wide_container { width: 50em }

.narrow_container { width: 20em }

.my_element { border: 1px solid }

@media (max-width: 30em) {
    .wide_container .my_element {
        color: blue;
    }

    .narrow_container .my_element {
        color: red;
    }
}

@media (max-width: 50em) {
    .wide_container .my_element {
        color: orange;
    }

    .narrow_container .my_element {
        color: green;
    }
}

Єдине інше рішення вимагає JS.


47
Питання зовсім не розпливчасте. Насправді це дуже гарне питання. На жаль, немає гарної відповіді на це.
степанець

2
Жахливе обслуговування за допомогою такого підходу.
Totty.js

4

Єдиний спосіб, коли я можу подумати, що ви можете досягти всього, що ви хочете, лише за допомогою css, - це використовувати контейнер з рідиною для свого віджета. Якщо ширина контейнера становить відсоток від екрана, ви можете використовувати медіа-запити для стилю залежно від ширини вашого контейнера, оскільки тепер ви будете знати для розмірів кожного екрана, які є розміри вашого контейнера. Наприклад, скажімо, ви вирішили зробити 50% ширини екрана вашого контейнера. Тоді для ширини екрана 1200 пікселів ви знаєте, що ваш контейнер становить 600 пікселів

.myContainer {
  width: 50%;
}

/* you know know that your container is 600px 
 * so you style accordingly
*/
@media (max-width: 1200px) { 
  /* your css for 600px container */
}

Ні, на екрані це виглядає негарно. Розмір екрана змінюється швидше, але елемент з’являється на екрані пізніше і менше.
Зелений

3

Я також думав про медіа-запити, але потім знайшов таке:

Просто створіть обгортку <div>із відсотковим значенням для padding-bottom, наприклад, цього:

div {
  width: 100%;
  padding-bottom: 75%;
  background:gold; /** <-- For the demo **/
}
<div></div>

Це призведе <div>до висоти, що дорівнює 75% ширини контейнера (співвідношення сторін 4: 3).

Цей прийом також може поєднуватися з медіа-запитами та трохи спеціальних знань про макет сторінки для ще більш тонкого контролю.

Досить для моїх потреб. Що може бути достатньо і для ваших потреб.


2

Ви можете використовувати API ResizeObserver . Це ще в перші дні, тому його ще не підтримують усі браузери (але є кілька поліфілів, які можуть вам у цьому допомогти).

В основному цей API дозволяє вам приєднати слухача подій до зміни розміру елемента DOM.

Демо 1 - Демо 2


Для проекту специфікації є полісистема. github.com/juggle/resize-observer
Тревор Каряніс

У статті Гейдона наведено приклад реалізації цього. Пошук "ResizeObserver" на сторінці: heydonworks.com/article/the-flexbox-holy-albatross
Гейб Роган

0

Для моєї я це зробив, встановивши максимальну ширину div, отже, для невеликого віджета це не вплине, а великий віджет змінить розмір завдяки стилю max-width.

  // assuming your widget class is "widget"
  .widget {
    max-width: 100%;
    height: auto;
  }

У запитанні було зазначено, що розмір віджета може змінюватися, якщо встановити максимальну ширину, він не змінить розмір віджета, коли контейнер буде широким. .widget- лише зразок як клас для діва віджета.
Jacky Choo
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.