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!

Andre Zimpel
fuente
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. :)

Hai Nguyen
fuente
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).

Joseph Yancey
fuente
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;
    }
}
SunnyRed
fuente
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... 

}
picante kimchi
fuente
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.

M_Willett
fuente
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;
  }
}
Atul Gupta
fuente
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)";
Sanket Suthar
fuente
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;
      }
    }
Sunil Rajput
fuente