¿Pueden cambiar el tamaño de las consultas de medios en función de un elemento div en lugar de la pantalla?

317

Me gustaría usar consultas de medios para cambiar el tamaño de los elementos en función del tamaño de un divelemento en el que se encuentran. No puedo usar el tamaño de la pantalla, ya divque solo se usa como un widget dentro de la página web, y su tamaño puede variar.

Actualizar

Parece que ahora se está trabajando en esto: https://github.com/ResponsiveImagesCG/cq-demos

Yazz.com
fuente
2
Creo que esta pregunta es demasiado breve para obtener una buena respuesta. ¿Quizás podría dar un ejemplo de lo que está tratando de hacer? ¿Quizás use jsfiddle.net para probar su idea y permitir que otros lo ayuden? En general, no debería haber ninguna razón para lo que está preguntando, debería poder lograr los resultados deseados con CSS sin consultas de medios. Puede usar dimensiones porcentuales y ems para fuentes para escalar elementos anidados. Pero tal vez solo necesito ver un ejemplo de su código html y css para comprender mejor.
BenSwayne
1
¿Cómo puede variar el tamaño de tu widget? ¿Su página tiene un ancho fijo (960 px por ejemplo) con vistas superiores a 1024 px o ambas son fluidas? Eso no está claro y sería útil saberlo
FelipeAls
3
En realidad, mi proyecto actual tiene una situación similar. Se muestra una lista de elementos en un diseño de 2 col para dispositivos anchos o en un diseño de 1 col para dispositivos estrechos, pero un solo elemento estará en un diseño de 1 col sin importar qué. Tanto la lista como la versión individual tienen 2 elementos que son bastante amplios y cortos. En dispositivos más anchos, los 2 elementos se ven mejor uno al lado del otro. Idealmente, dispositivos estrechos: siempre verticales, dispositivos anchos: siempre paralelos, en algún punto intermedio (dependiendo de 1 o 2-col): verticales o paralelos. Flotar es la solución simple, pero el ancho también debe variar según el diseño.
cimmanon
1
LESS se compilará en CSS, por lo que si CSS no lo admite, LESS tampoco puede ayudarlo.
jvannistelrooy
3
¿El enlace ya no está activo?
mix3d

Respuestas:

228

No, las consultas de medios no están diseñadas para funcionar según los elementos de una página. Están diseñados para funcionar en función de dispositivos o tipos de medios (de ahí que se denominen consultas de medios ). width, heighty otras características de medios basadas en dimensiones, todas se refieren a las dimensiones de la ventana gráfica o de la pantalla del dispositivo en medios basados ​​en pantalla. No se pueden usar para referirse a un determinado elemento en una página.

Si necesita aplicar estilos según el tamaño de un determinado divelemento en su página, deberá usar JavaScript para observar los cambios en el tamaño de ese divelemento en lugar de las consultas de medios.

BoltClock
fuente
Escuché de alguna manera que podría usar funciones con consultas de medios para obtener el tamaño de un elemento contenedor. ¿Hay alguna forma de combinar esto con consultas de medios para cambiar el tamaño de los elementos?
Yazz.com
1
Tendría que usar JS para obtener periódicamente el ancho de su elemento y reaccionar en consecuencia (periódicamente = cada segundo más o menos o ralentizará algunos navegadores; en consecuencia = cambiando las clases al estilo de su widget si desea el método más rápido).
FelipeAls
66
Para lograr esto de forma nativa, necesitaríamos @elementconsultas. W3C tiene buena documentación sobre la rima / razón de las @mediaconsultas: w3.org/TR/css3-mediaqueries/#width (este enlace lo lleva a la sección que discute los anchos --- anchos del tipo de medio, no los elementos contenidos dentro)
Dawson
¿Alguna posibilidad de hacerlo funcionar en correos electrónicos? Estoy tratando de aplicar el estilo móvil a los correos electrónicos cuando el contenedor div es demasiado pequeño (es decir, cuando el espacio de correo electrónico de la versión de escritorio de Gmail es demasiado pequeño para un diseño de 2 columnas, debido al cambio de tamaño de la ventana, por ejemplo).
Lev
Por cierto, las consultas de @element harían de css un lenguaje completo de Turing
Nick
117

Acabo de crear un calce de JavaScript para lograr este objetivo. Eche un vistazo si lo desea, es una prueba de concepto, pero tenga cuidado: es una versión temprana y aún necesita algo de trabajo.

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

Marc J. Schmidt
fuente
55
Gracias, estoy impresionado
Yazz.com
55
Esto es increíble. Combinado con bootstrap receptivo, estoy haciendo algunas cosas increíbles que no se podrían lograr con solo @media. Bien hecho.
Aku
3
Nos salvaste la vida
Broda Noel
Wow, realmente agradable, hace las cosas mucho más fáciles
kaiser
Frio. Ten la pregunta. Ahora, este complemento detecta: qué elementos necesitan min-widthrenovación de atributo; ¿necesito escribir manualmente la lista de clase css, elementos marcados, habilitados para la min-widthrenovación?
Alexander Goncharov
38

Una consulta de medios dentro de un iframe puede funcionar como una consulta de elemento. He implementado con éxito esto. La idea surgió de una publicación reciente sobre Responsive Ads de Zurb. ¡Sin Javascript!

haddnin
fuente
Creo que esta es la mejor solución, porque las consultas de los medios funcionan dentro del iframe.
emfi
25

Actualmente, esto no es posible solo con CSS, ya que @BoltClock escribió en la respuesta aceptada, pero puede solucionarlo utilizando JavaScript.

Creé una consulta de contenedor (también conocida como consulta de elemento) prolyfill para resolver este tipo de problema. Funciona un poco diferente a otros scripts, por lo que no tiene que editar el código HTML de sus elementos. Todo lo que tiene que hacer es incluir el script y usarlo en su CSS de la siguiente manera:

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

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

ausi
fuente
2
Está lleno de JS. El objetivo es tener la funcionalidad solo en CSS.
Verde
13
Los Prolyfills (y los polyfills ) generalmente se escriben en JS para habilitar una función que aún no es compatible con el navegador. El objetivo de prolyfill es volverse obsoleto una vez que esta característica sea compatible con CSS.
ausi
3
@ius no hay mención de "CSS solamente" en la pregunta. ¿Cómo llegaste a esa conclusión?
ausi
1
@ius, excepto que posiblemente no pueda hacerlo en CSS, por lo que ofrecer una solución fuera de CSS es perfectamente razonable. Mucho mejor que "no, no puedes" no crees;)
Wesley Smith
1
@ DelightedD0D después de mi comentario cambió la respuesta y voté +1 por el cambio. La respuesta actual está bien para mí porque dice que esto no es posible solo con CSS.
ius
17

Me encontré con el mismo problema hace un par de años y financié el desarrollo de un complemento para ayudarme en mi trabajo. He lanzado el complemento como código abierto para que otros también puedan beneficiarse de él, y puedes obtenerlo en Github: https://github.com/eqcss/eqcss

Hay algunas maneras en que podríamos aplicar diferentes estilos de respuesta basados ​​en lo que podemos saber sobre un elemento en la página. Aquí hay algunas consultas de elementos que el complemento EQCSS le permitirá escribir en 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 */
  }
}

Entonces, ¿qué condiciones son compatibles con los estilos receptivos con EQCSS?

Consultas de peso

  • ancho min en px
  • ancho min en %
  • ancho máximo en px
  • ancho máximo en %

Consultas de altura

  • altura mínima en px
  • altura mínima en %
  • altura máxima en px
  • altura máxima en %

Contar consultas

  • min-caracteres
  • max-caracteres
  • líneas mínimas
  • lineas maximas
  • min-niños
  • max-children

Selectores especiales

Dentro de las consultas de elementos EQCSS, también puede usar tres selectores especiales que le permiten aplicar más específicamente sus estilos:

  • $this (los elementos que coinciden con la consulta)
  • $parent (los elementos primarios de los elementos que coinciden con la consulta)
  • $root(el elemento raíz del documento <html>)

Las consultas de elementos le permiten componer su diseño a partir de módulos de diseño que responden individualmente, cada uno con un poco de "autoconciencia" de cómo se muestran en la página.

Con EQCSS puede diseñar un widget para que se vea bien desde 150 px de ancho hasta 1000 px de ancho, luego puede colocar ese widget con confianza en cualquier barra lateral en cualquier página usando cualquier plantilla (en cualquier sitio) y

innovati
fuente
1
Buen proyecto!
Eché
@innovati Encontré esta publicación mientras buscaba una forma de hacer consultas sobre elementos. Parece que no puedo hacer que funcione. ¿Te importaría mirar mi boleto? github.com/eqcss/eqcss/issues/96
Andrew Newby
10

Desde una perspectiva de diseño, es posible utilizando técnicas modernas.

Está hecho (creo) por Heydon Pickering. Detalla el proceso aquí: http://www.heydonworks.com/article/the-flexbox-holy-albatross

Chris Coyier lo recoge y trabaja a través de una demostración aquí: https://css-tricks.com/putting-the-flexbox-albatross-to-real-use/

Para volver a plantear el problema, a continuación vemos 3 del mismo componente, cada uno compuesto por tres divs naranjas etiquetados a, by c.

Los bloques del segundo dos se muestran verticalmente, ya que están limitados en el espacio horizontal, mientras que los componentes superiores 3 bloques están dispuestos horizontalmente.

Utiliza la flex-basispropiedad CSS y las variables CSS para crear este efecto.

Ejemplo final

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

Manifestación

El artículo de Heydon tiene 1000 palabras que lo explican en detalle, y recomiendo leerlo.

Djave
fuente
Esa cosa del artículo de Heydon ... ¡Parece y funciona como magia! Gracias por tu respuesta, es genial.
ptyskju
2
Esta es la respuesta que todos los que se topan con esta pregunta están buscando
TehShrike
7

La pregunta es muy vaga. Como dice BoltClock, las consultas de los medios solo conocen las dimensiones del dispositivo. Sin embargo, puede usar consultas de medios en combinación con selectores descendentes para realizar ajustes.

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

La única otra solución requiere JS.

cimmanon
fuente
47
La pregunta no es vaga en absoluto. De hecho, es una muy buena pregunta. Desafortunadamente, no hay una buena respuesta para eso.
Stepanian
2
Terrible mantenimiento con este enfoque.
Totty.js
4

La única forma en que puedo pensar que puedes lograr lo que quieres con CSS, es usar un contenedor de fluido para tu widget. Si el ancho de su contenedor es un porcentaje de la pantalla, entonces puede usar consultas de medios para diseñar dependiendo del ancho de su contenedor, ya que ahora sabrá para las dimensiones de cada pantalla cuáles son las dimensiones de su contenedor. Por ejemplo, supongamos que decide hacer que su contenedor tenga el 50% del ancho de la pantalla. Luego, para un ancho de pantalla de 1200px, sabe que su contenedor es de 600px

.myContainer {
  width: 50%;
}

/* you know know that your container is 600px 
 * so you style accordingly
*/
@media (max-width: 1200px) { 
  /* your css for 600px container */
}
Roumelis George
fuente
No, se ve feo en una pantalla. El tamaño de la pantalla cambia más rápido, pero el elemento aparece en una pantalla más tarde y más pequeño.
Verde
3

También estaba pensando en las consultas de los medios, pero luego encontré esto:

Simplemente cree un contenedor <div>con un valor de porcentaje para padding-bottom, como este:

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

El resultado será una <div>altura igual al 75% del ancho de su contenedor (una relación de aspecto de 4: 3).

Esta técnica también se puede combinar con consultas de medios y un poco de conocimiento ad hoc sobre el diseño de la página para un control aún más detallado.

Es suficiente para mis necesidades. Lo cual podría ser suficiente para sus necesidades también.

Hendy Irawan
fuente
2

Puedes usar el ResizeObserver API . Todavía está en sus primeros días, por lo que todavía no es compatible con todos los navegadores (pero hay varios polyfills que pueden ayudarlo con eso).

Básicamente, esta API le permite adjuntar un detector de eventos al cambio de tamaño de un elemento DOM.

Demo 1 - Demo 2

José Salgado
fuente
Hay un polyfill para el borrador de la especificación. github.com/juggle/resize-observer
Trevor Karjanis
El artículo de Heydon proporciona un ejemplo de implementación de esto. Buscar "ResizeObserver" en la página: heydonworks.com/article/the-flexbox-holy-albatross
Gabe Rogan
0

Para el mío lo hice estableciendo el ancho máximo del div, por lo tanto, para el widget pequeño no se verá afectado y el widget grande se redimensionará debido al estilo de ancho máximo.

  // assuming your widget class is "widget"
  .widget {
    max-width: 100%;
    height: auto;
  }
Jacky Choo
fuente
La pregunta mencionó que el tamaño del widget podría variar, establecer max-width no cambiará el tamaño del widget cuando el contenedor es ancho. .widgetes solo una muestra como la clase para el div del widget.
Jacky Choo