Le query multimediali possono ridimensionare in base a un elemento div anziché allo schermo?


317

Vorrei utilizzare le media query per ridimensionare gli elementi in base alla dimensione di un divelemento in cui si trovano. Non posso usare la dimensione dello schermo in quanto divviene utilizzata come un widget all'interno della pagina Web e la sua dimensione può variare.

Aggiornare

Sembra che ci sia del lavoro su questo ora: https://github.com/ResponsiveImagesCG/cq-demos


2
Penso che questa domanda sia troppo breve per ottenere una buona risposta. Forse potresti fornire un esempio di ciò che stai cercando di fare? Forse usi jsfiddle.net per testare la tua idea e consentire ad altri di aiutarti? Generalmente non ci dovrebbero essere motivi per quello che stai chiedendo, dovresti essere in grado di ottenere i risultati desiderati con CSS senza media query. È possibile utilizzare quote percentuali ed em per i caratteri per ridimensionare gli elementi nidificati. Ma forse ho solo bisogno di vedere un esempio del tuo codice HTML e CSS per capire meglio?
BenSwayne,

1
Come può variare la dimensione del tuo widget? La tua pagina ha una larghezza fissa (960 px per esempio) con finestre superiori a 1024 px o sono entrambe fluide? Non è chiaro e sarebbe utile sapere
FelipeAls

3
In realtà, il mio progetto attuale ha una situazione simile. Un elenco di elementi viene visualizzato in un layout a 2 col per dispositivi larghi o in un layout a 1 col per dispositivi stretti, ma un singolo elemento sarà in un layout a 1 col, non importa quale. Sia l'elenco che la versione singola hanno 2 elementi che sono abbastanza ampi e brevi. Su dispositivi più larghi, i 2 elementi sembrano affiancati. Idealmente, dispositivi stretti: sempre verticali, dispositivi ampi: sempre paralleli, a metà tra (a seconda di 1 o 2-col): verticali o paralleli. Il floating è la soluzione semplice, ma anche la larghezza deve variare a seconda del layout.
cimmanon,

1
LESS verrà compilato in CSS, quindi se CSS non lo supporta, LESS non può aiutarti.
jvannistelrooy,

3
Il link non è più attivo?
mix3d

Risposte:


228

No, le media query non sono progettate per funzionare in base agli elementi di una pagina. Sono progettati per funzionare in base a dispositivi o tipi di media (quindi perché vengono chiamati query multimediali ). width, heighte altre funzionalità multimediali basate sulla dimensione si riferiscono tutte alle dimensioni della finestra del viewport o dello schermo del dispositivo nei media basati sullo schermo. Non possono essere utilizzati per fare riferimento a un determinato elemento in una pagina.

Se è necessario applicare gli stili in base alla dimensione di un determinato divelemento nella pagina, è necessario utilizzare JavaScript per osservare le modifiche alle dimensioni di tale divelemento anziché le query multimediali.


Ho sentito di un modo in cui potrei essere in grado di utilizzare le funzioni con le query multimediali per ottenere le dimensioni da un elemento contenente. Esiste un modo per combinarlo con le query multimediali per ridimensionare gli elementi?
Yazz.com,

1
Dovresti usare JS per ottenere periodicamente la larghezza del tuo elemento e reagire di conseguenza (periodicamente = ogni secondo circa o rallenterà alcuni browser; di conseguenza = attivando le classi che disegnano il tuo widget se vuoi il metodo più veloce).
FelipeAls,

6
Per realizzare questo in modo nativo, avremmo bisogno di @elementdomande. Il W3C ha una buona documentazione sulla rima / motivo delle @mediaquery: w3.org/TR/css3-mediaqueries/#width (questo link ti porta alla sezione che discute le larghezze --- larghezze del tipo di supporto, non gli elementi contenuti all'interno)
Dawson,

Qualche possibilità di farlo funzionare nelle e-mail? Sto cercando di applicare lo stile mobile alle e-mail quando il div del contenitore è troppo piccolo (ad esempio quando lo spazio e-mail della versione desktop di Gmail è troppo piccolo per adattarsi a un design a 2 colonne, ad esempio a causa del ridimensionamento della finestra).
Lev

A proposito, le domande di @element renderebbero il CSS un linguaggio completo di Turing
Nick

117

Ho appena creato uno spessore javascript per raggiungere questo obiettivo. Dai un'occhiata se vuoi, è una prova di concetto, ma fai attenzione: è una versione iniziale e ha ancora bisogno di un po 'di lavoro.

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


5
Grazie, sono impressionato
Yazz.com

5
Questo è incredibile. In combinazione con il bootstrap reattivo sto facendo alcune cose fantastiche che non è stato possibile ottenere con solo @media. Molto bene.
Aku,

3
Ci hai salvato la vita
Broda Noel il

Wow, davvero carino, rende le cose molto più facili
kaiser,

Freddo. Fai la domanda In che modo questo plugin rileva: quali elementi necessitano di min-widthrinnovare l'attributo; devo scrivere manualmente un elenco css-class, elementi contrassegnati, abilitati per il min-widthrinnovo?
Alexander Goncharov,

38

Una query media all'interno di un iframe può funzionare come una query elemento. Ho implementato con successo questo. L'idea è nata da un recente post su Responsive Ads di Zurb. Nessun Javascript!


penso che questa sia la soluzione migliore, perché le query multimediali funzionano all'interno dell'iframe.
emfi,

25

Questo al momento non è possibile solo con CSS come ha scritto @BoltClock nella risposta accettata, ma puoi aggirare il problema usando JavaScript.

Ho creato un prolyfill di query contenitore (aka element query) per risolvere questo tipo di problema. Funziona in modo leggermente diverso rispetto agli altri script, quindi non è necessario modificare il codice HTML dei tuoi elementi. Tutto quello che devi fare è includere lo script e usarlo nel tuo CSS in questo modo:

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

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


2
È pieno di JS. L'obiettivo è avere la funzionalità solo nei CSS.
Verde,

13
Prolyfill (e polyfill ) sono generalmente scritti in JS per abilitare una funzione che non è ancora supportata dal browser. L'obiettivo del prolyfill è diventare obsoleto una volta che questa funzione è supportata nei CSS.
ausi,

3
@ius non si fa menzione di "solo CSS" nella domanda. Come sei arrivato a quella conclusione?
ausi,

1
@ius tranne voi sopraelevazione forse farlo in CSS in modo da offrire una soluzione al di fuori del CSS è perfettamente ragionevole. Molto meglio di "no, non puoi" non pensi;)
Wesley Smith,

1
@ DelightedD0D dopo il mio commento ha cambiato la risposta e ho votato +1 per la modifica. La risposta attuale è OK per me perché sta dicendo che questo non è possibile solo con CSS.
ius

17

Ho riscontrato lo stesso problema un paio di anni fa e ho finanziato lo sviluppo di un plugin per aiutarmi nel mio lavoro. Ho rilasciato il plug-in come open-source in modo che anche altri possano trarne vantaggio e puoi scaricarlo su Github: https://github.com/eqcss/eqcss

Esistono alcuni modi in cui possiamo applicare diversi stili di risposta in base a ciò che possiamo sapere su un elemento nella pagina. Ecco alcune query sugli elementi che il plug-in EQCSS ti consentirà di scrivere in 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 */
  }
}

Quindi quali condizioni sono supportate per gli stili reattivi con EQCSS?

Domande sul peso

  • larghezza min in px
  • larghezza min in %
  • larghezza massima in px
  • larghezza massima in %

Query di altezza

  • altezza minima in px
  • altezza minima in %
  • altezza massima in px
  • altezza massima in %

Conteggio delle query

  • min-caratteri
  • max-caratteri
  • min-lines
  • max-linee
  • min-bambini
  • max-figli

Selettori speciali

All'interno delle query sugli elementi EQCSS puoi anche utilizzare tre selettori speciali che ti consentono di applicare in modo più specifico i tuoi stili:

  • $this (gli elementi che corrispondono alla query)
  • $parent (gli elementi principali dell'elemento / i corrispondenti alla query)
  • $root(l'elemento radice del documento, <html>)

Le query sugli elementi ti consentono di comporre il tuo layout in moduli di progettazione rispondenti individualmente, ognuno con un po 'di "autocoscienza" su come vengono visualizzati sulla pagina.

Con EQCSS puoi progettare un widget per avere un bell'aspetto da 150 pixel fino a 1000 pixel, quindi puoi tranquillamente rilasciare quel widget in qualsiasi barra laterale in qualsiasi pagina utilizzando qualsiasi modello (su qualsiasi sito) e


1
Bel progetto! Ho dato un'occhiata a quello che hai fatto
Yazz.com il

@innovati Ho trovato questo post mentre cercavo un modo per fare domande sugli elementi. Non riesco a farlo funzionare. Ti dispiacerebbe guardare il mio biglietto? github.com/eqcss/eqcss/issues/96
Andrew Newby

10

Dal punto di vista del layout, è possibile utilizzare tecniche moderne.

È composto (credo) da Heydon Pickering. Descrive in dettaglio il processo qui: http://www.heydonworks.com/article/the-flexbox-holy-albatross

Chris Coyier lo raccoglie e lavora attraverso una demo qui: https://css-tricks.com/putting-the-flexbox-albatross-to-real-use/

Per ribadire il problema, di seguito vediamo 3 dello stesso componente, ciascuna composta da tre div arancio etichettati a, be c.

I blocchi dei secondi due vengono visualizzati verticalmente, poiché sono limitati nella stanza orizzontale, mentre i componenti superiori 3 blocchi sono disposti orizzontalmente.

Usa la flex-basisproprietà CSS e le variabili CSS per creare questo effetto.

Esempio finale

.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 );
  }
}

dimostrazione

L'articolo di Heydon è di 1000 parole che lo spiegano in dettaglio, e consiglio vivamente di leggerlo.


Quella cosa dall'articolo di Heydon ... Sembra e funziona come per magia! Grazie per la tua risposta, è fantastico.
ptyskju,

2
Questa è la risposta che tutti cercano su questa domanda
TehShrike,

7

La domanda è molto vaga. Come dice BoltClock, le query multimediali conoscono solo le dimensioni del dispositivo. Tuttavia, è possibile utilizzare le query multimediali in combinazione con i selettori di discensore per eseguire le regolazioni.

.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;
    }
}

L'unica altra soluzione richiede JS.


47
La domanda non è affatto vaga. In effetti, è un'ottima domanda. Sfortunatamente, non esiste una buona risposta per questo.
stepanian

2
Terribile manutenzione con questo approccio.
Totty.js il

4

L'unico modo in cui riesco a pensare che puoi realizzare ciò che vuoi solo con css è usare un contenitore fluido per il tuo widget. Se la larghezza del tuo contenitore è una percentuale dello schermo, puoi utilizzare le media query per modellare in base alla larghezza del tuo contenitore, poiché ora saprai per le dimensioni di ogni schermo quali sono le dimensioni del tuo contenitore. Ad esempio, supponiamo che tu decida di rendere il 50% della larghezza dello schermo del tuo contenitore. Quindi per una larghezza dello schermo di 1200 px sai che il tuo contenitore è 600 px

.myContainer {
  width: 50%;
}

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

No, sembra brutto su uno schermo. Le dimensioni dello schermo cambiano più velocemente, ma l'elemento appare su uno schermo più tardi e più piccolo.
Verde,

3

Stavo anche pensando alle domande dei media, ma poi ho trovato questo:

Basta creare un wrapper <div>con un valore percentuale per padding-bottom, in questo modo:

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

Ne risulterà <div>un'altezza pari al 75% della larghezza del suo contenitore (proporzioni 4: 3).

Questa tecnica può anche essere abbinata a query multimediali e un po 'di conoscenza ad hoc sul layout di pagina per un controllo ancora più preciso.

È abbastanza per le mie esigenze. Che potrebbe essere sufficiente anche per le tue esigenze.


2

È possibile utilizzare l' API ResizeObserver . È ancora agli inizi, quindi non è ancora supportato da tutti i browser (ma ci sono molti polyfill che possono aiutarti in questo).

Fondamentalmente questa API consente di collegare un listener di eventi al ridimensionamento di un elemento DOM.

Demo 1 - Demo 2


Esiste un polifill per la bozza di specifica. github.com/juggle/resize-observer
Trevor Karjanis

L'articolo di Heydon fornisce un esempio di implementazione di questo. Cerca "ResizeObserver" nella pagina: heydonworks.com/article/the-flexbox-holy-albatross
Gabe Rogan

0

Per me l'ho fatto impostando la larghezza massima del div, quindi per i widget di piccole dimensioni non ne risentiremo e il widget di grandi dimensioni viene ridimensionato a causa dello stile di larghezza massima.

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

La domanda diceva che la dimensione del widget potrebbe variare, l'impostazione della larghezza massima non cambierà la dimensione del widget quando il contenitore è largo. .widgetè solo un esempio come classe per il div del widget.
Jacky Choo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.