Consultas de medios elegantes con un poco de magia MENOS


81

Sería bueno envolver estilos css para diferentes resoluciones dentro de algunas clases css usando less.

Me gustaría hacer algo como:

footer {
  width: 100%;
}

.tablet {
  footer {
    width: 768px;
  }
}

.desktop {
  footer {
    width: 940px;
  }
}

Al final, algo como esto debería ser el resultado:

footer {
  width: 100%;
}

@media screen and (min-width: 768px) {
  footer {
    width: 768px;
  }
}

@media screen and (min-width: 992px) {
  footer {
    width: 940px;
  }
}

.tablet podría verse de alguna manera así:

@media screen and (min-width: 768px) {
  .tablet {

  }
}

¡Espero que alguien tenga una buena idea!


posible duplicado de la agrupación
ScottS

Según la conversación en los comentarios a @zzzzBov, tal vez necesitemos un poco más de claridad en su pregunta sobre lo que está tratando de lograr y cómo desea lograrlo.
ScottS

Respuestas:


234

Esto es lo que hice en mis proyectos:

@desktop:   ~"only screen and (min-width: 960px) and (max-width: 1199px)";
@tablet:    ~"only screen and (min-width: 720px) and (max-width: 959px)";

@media @desktop {
  footer {
    width: 940px;
  }
}

@media @tablet {
  footer {
    width: 768px;
  }
}

Esto le permite definir sus consultas de medios solo una vez y puede usarlo en sus menos archivos. También un poco más fácil de leer. :)


2
¡Esto es increíble, gracias @Hai! Un problema menor en Visual Studio es que este mensaje de advertencia se genera sobre el uso de @mediaen un archivo .less: " Bloque '@' inesperado en la regla de estilo ". Sin embargo, no parece ser un problema.
Ian Campbell

¿Por qué no puedo @mediaintroducir el en las variables definidas en la línea 1 + 2? ➪ lamentable, un puro @tablet { ...no se resuelve entonces, mientras que un @media @tablet {...(resulta en un doble, @mediapor supuesto, si se
incluye

116

Estoy completamente de acuerdo con la respuesta de Hai Nguyen (que ha sido aceptada) pero puedes limpiarla un poco más haciendo algo como esto:

@desktop:   ~"only screen and (min-width: 960px) and (max-width: 1199px)";
@tablet:    ~"only screen and (min-width: 720px) and (max-width: 959px)";

footer{
  width: 100%;
  @media @tablet {
    width: 768px;
  }
  @media @desktop {
    width: 940px;
  }
}

Es esencialmente lo mismo, pero le permite anidar sus consultas de medios dentro del selector original. Mantiene todos los CSS de un elemento específico juntos y hace que sus estilos sean mucho más modulares (en comparación con el enfoque de punto de interrupción dividido).


Después de leer esto, encontré esta tarea de Grunt para agrupar los MQ después de que se compilen los MQ anidados: github.com/buildingblocks/grunt-combine-media-queries Elimina la hinchazón.
Jazzy

Esto es lindo y limpio. ¿Puedo preguntar, por qué el ~ delante de "sólo ...?
Anthony_Z

En LESS, una tilde ~ antes de una cadena "" literal genera la cadena como está, porque puede ser un error de sintaxis en LESS puro.
Joseph Yancey

1
¿Qué pasa si intenta realizar una operación dentro de esa "cadena literal"? Digamos que quiero usar una variable para contener la resolución de la pantalla, por ejemplo: ¿Puedo hacer algo como: ~ "solo pantalla y (ancho mínimo: @mySize - 20px)". Sé que no funciona, pero ¿cuál es la forma correcta de hacerlo?
Fablexis

44

+1 para Nguyen y Yancey, y una adición más.

Si desea una definición explícita de los anchos, puede lograrlo con string interpolationvariables y para sus puntos de interrupción. Aquí, por ejemplo, con los de bootstrap, las reglas estrictas son para evitar la superposición de definiciones.

@screen-xs-min:     480px;
@screen-sm-min:     768px;
@screen-md-min:     992px;
@screen-lg-min:     1200px;

@screen-xs-max:     (@screen-sm-min - 1);
@screen-sm-max:     (@screen-md-min - 1);
@screen-md-max:     (@screen-lg-min - 1);

@phone:             ~"only screen and (max-width: @{screen-xs-min})";
@phone-strict:      ~"only screen and (min-width: @{screen-xs-min}) and (max-width: @{screen-xs-max})";
@tablet:            ~"only screen and (min-width: @{screen-sm-min})";
@tablet-strict:     ~"only screen and (min-width: @{screen-sm-min}) and (max-width: @{screen-sm-max})";
@desktop:           ~"only screen and (min-width: @{screen-md-min})";
@desktop-strict:    ~"only screen and (min-width: @{screen-md-min}) and (max-width: @{screen-md-max})";
@large:             ~"only screen and (min-width: @{screen-lg-min})";

footer{
    width: 100%;
    @media @tablet {
        width: 768px;
    }
    @media @desktop {
        width: 940px;
    }
}

De qué se trata exactamente este "-estricto", por lo que ha escrito, no soy capaz de comprender el constructo. ¿Hay alguna fuente a la que pueda señalarme para leer más sobre este tema?
Kevkong

1
En realidad, las "consultas estrictas" son por conveniencia y solo deben usarse si desea que su CSS se aplique a un solo rango de pantalla exclusivamente. Al usar el móvil primero (por ejemplo, ver: zellwk.com/blog/how-to-write-mobile-first-css ), diría que su uso es posiblemente un olor a diseño y normalmente trataría de evitarlos. . Pero dependiendo de las circunstancias, es posible que desee que se dirija algún CSS (pesado), digamos @tabletexclusivamente, y no desea anularlo en, digamos @desktopy / o @large. En estos casos, puede utilizar una consulta estricta (aquí @tablet-strict).
SunnyRed

9

Y también puede combinar consultas de medios como esta

@media @desktop, @tablet, @ipad{ 

//common styles... 

}

7

Usamos una configuración como esta:

@vp_desktop:    801px;
@vp_tablet:     800px;
@vp_mobile:     400px;

.OnDesktop(@rules) { @media screen and (min-width:@vp_desktop){ @rules(); } };
.OnTablet(@rules) { @media screen and (max-width:@vp_tablet){ @rules(); } };
.OnMobile(@rules) { @media screen and (max-width:@vp_mobile){ @rules(); } };

Solo necesita establecer variables, los mixins manejan el resto, por lo que es muy fácil de mantener pero aún flexible:

div {
  display: inline-block;
  .OnTablet({
    display: block;
  });
}

Vale la pena mencionar que si bien esta técnica es muy fácil, si se usa mal, la salida de CSS estará llena de consultas de medios. Intento limitar mis consultas de medios a 1 por punto de interrupción, por archivo. Donde un archivo sería header.less o search.less.

NB: Este método probablemente no se compilará a menos que esté usando el compilador javascript.


4

Estoy usando estos mixins y variables

.max(@max; @rules){@media only screen and (max-width: (@max - 1)){@rules();}}
.min(@min; @rules){@media only screen and (min-width: @min){@rules();}}
.bw(@min; @max; @rules){@media only screen and (min-width: @min) and (max-width: (@max - 1)){@rules();}}

@pad: 480px;
@tab: 800px;
@desktop: 992px;
@hd: 1200px;

Así que esto

footer{
    width: 100%;
    .bw(@tab,@desktop,{
        width: 768px;
    });
    .min(@desktop,{
        width: 940px;
    });
}

se convierte en

footer {
  width: 100%;
}
@media only screen and (min-width: 800px) and (max-width: 991px) {
  footer {
    width: 768px;
  }
}
@media only screen and (min-width: 992px) {
  footer {
    width: 940px;
  }
}

0
@highdensity:  ~"only screen and (-webkit-min-device-pixel-ratio: 1.5)",
               ~"only screen and (min--moz-device-pixel-ratio: 1.5)",
               ~"only screen and (-o-min-device-pixel-ratio: 3/2)",
               ~"only screen and (min-device-pixel-ratio: 1.5)";

@mobile:        ~"only screen and (max-width: 750px)";
@tab:       ~"only screen and (min-width: 751px) and (max-width: 900px)";
@regular:        ~"only screen and (min-width: 901px) and (max-width: 1280px)";
@extra-large:  ~"only screen and (min-width: 1281px)";

0

Y esto es lo que he usado para mi proyecto:

    @mobile:   ~"only screen and (min-width: 320px) and (max-width: 767px)";
    @tablet:    ~"only screen and (min-width: 768px) and (max-width: 991px)";
    @ipad:    ~"only screen and (min-width: 992px) and (max-width: 1024px)";

    @media @mobile {
      .banner{
        width: auto;
      }
    }

    @media @tablet {
      .banner{
        width: 720px;
      }
    }

  @media @ipad {
      .banner{
        width: 920px;
      }
    }
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.