How can I use media queries more efficiently with LESS? - css

I'm working with Bootstrap and LESS on a responsive webpage design.
One of the reasons I have enjoyed LESS in the past is because it can keep all attributes for HTML elements together.
What I have below is some rules to define a .sponsors block, and then one rule that applies to an element inside that block when the viewport is >= 768px
I don't like how that one rule requires a lot of extra code, and how that rule is apart from the rest of the rules. It also feels wrong.
What is a better way to do this / organize this? Do I need to start out by breaking everything down into top level #media groups?
.sponsors
{
li
{
.thumbnail
{
padding-top:20px;
padding-bottom:15px;
img
{
display:block;
margin:0 auto;
}
}
}
}
#media (min-width: 768px)
{
.sponsors
{
li
{
.thumbnail
{
padding-bottom:0px!important;
}
}
}
}
It would be pretty sweet if there was something like:
.thumbnail
{
&[#mediaWidth >=768]
{
padding-bottom:0px!important;
}
}

I think you can nest media queries and LESS (>1.3.0) will 'bubble' them to the root of your stylesheet during compilation.
.sponsors
{
li
{
.thumbnail
{
padding-top:20px;
padding-bottom:15px;
#media (min-width: 768px) {
padding-bottom:0px!important;
}
img
{
display:block;
margin:0 auto;
}
}
}
}

Related

CSS for module size (similar to #media)?

I have a Joomla Module that I'm trying to keep responsive for different screen sizes but displaying and hiding columns. This works well on full page displays.
#media (max-width: 800px) {
.team_name { display:none; }
.team_abbr { display:inline-block;}
.overall { display: inline-block;}
.divisional { display:inline-block;}
.wide { display:none;}
#btn_row { display:inline-block;}
#div_split { display:none;}
}
#media screen and (min-width: 800px) {
.team_name { display: inline-block; }
.team_abbr { display:none;}
.overall { display: inline-block;}
.divisional { display:inline-block;}
.wide { display:inline-block;}
#btn_row { display:none;}
#div_split ( display:inline-block;)
}
But now my challenge is that I want to have this same page/module used inside another page as a module position (which is only about 200 pixels wide).
Is there a CSS command similar to #media that will get the module width instead of the entire page width that the module is on?
Thanks in advance...
One way to do this is to add a class to your module, then size the elements inside the module relative to their parent (ie the module)
(1) Start by going to the module you want to work on > advanced tab > module class suffix
(2) Add a class and remember to include a space at the start, eg ' my-module-class'
(3) Finally, size your module elements relative to the module, eg
#media (max-width: 800px) {
.team_abbr {
...
width:50%;
}
}
Good luck, I hope this helps!

how to hide/show a div using a media query but not when it's within another div

I'm trying to hide a specific div using a media query which is working fine. However, I need it to show when that div is within another specific div. Is this possible. This is the CSS:
#media (min-width: 665px) {
.mrbcircle-ipad:not(.link-inside.mrbcircle-ipad) {
position:absolute;
display:none;
}
}
so .mrbcircle-ipad should be hidden over 665px unless it's within .link-inside.
Currently this is showing .mrbcircle everywhere so I know it's wrong. How can I fix this?
Thanks
Anthony
#media (min-width: 665px) {
.mrbcircle-ipad {
position:absolute;
display:none;
}
.link-inside .mrbcircle-ipad{
position relative;
display: block;
}
}
Use two rules inside the media query: The first to hide it when the viewport is wider than 665px, the second to make it visible if it's inside a certain parent:
#media (min-width: 666px) {
.mrbcircle-ipad {
position:absolute;
display:none;
}
.link-inside .mrbcircle-ipad{
display: block;
}
}

Deduplicating CSS rules when using #media queries

I've noticed more and more that my stylesheets generally have repeated rules as a normal selector as well as inside a #media ... {} query and generates quite a lot of CSS bloat.
Here's a simple use-case of the problem that I see popping up ad nauseam:
.big-red {
color:red;
font-size: 3em;
... lots of other stuff
}
.dynamic-uber-class {
color:green;
font-size:2em;
}
#media only screen and (min-width: 48em) {
.dynamic-uber-class {
color:red;
font-size: 3em;
... lots of other .big-red duplicated stuff
}
}
I notice that the problem becomes increasingly problematic when I use mixins in less or scss (because it's really easy to add), but what's really needed is mixins in CSS (for which I won't be holding my breath!). That said, I've noticed CSS-Properties, with some support and #apply that has no support.
Has anyone stumbled on a CSS only way of not having this duplication?
I'm aware that with a bit of Javascript I can simply add/remove classes, but I like my sites working properly with javascript disabled (as much as possible).
Edit:
For those struggling to understand the problem, take a real-world example from bootstrap's grid:
.col-xs-12 {
width: 100%;
}
.col-xs-11 {
width: 91.66666667%;
}
.col-xs-10 {
width: 83.33333333%;
}
...
#media (min-width: 768px) {
.col-sm-12 {
width: 100%;
}
.col-sm-11 {
width: 91.66666667%;
}
.col-sm-10 {
width: 83.33333333%;
}
}
If you've ever looked at the generated CSS of bootstrap it is very fat indeed due to the problem.
Why not something like this:
.uber-class, .dynamic-uber-class {
color:red;
font-size: 3em;
... lots of other duplicated stuff
}
#media only screen and (min-width: 48em) {
.dynamic-uber-class {
... only unique styles
}
}

less :extend() with media queries

I am trying to extend a simple class
.positionAbsolute {
position: absolute;
}
My issue here is that I can extend it like:
#something:extend(.positionAbsolute) {
something else
}
But from inside the media query itself, If i try from outside no rule is extended at all.
Is this the normal behaviour?, why is doing that?, In such case I will have to create like four equal classes to extend in each media query case, is there some workaround?
Thank you
I'm not sure I understand it right (it's always hard to guess w/o seeing an exact CSS output you need to achieve), but it looks like you need something like:
.positionAbsolute {
position: absolute;
}
#something:extend(.positionAbsolute) {
#media only screen and (min-width: 1024px) {
something: else;
}
}
The other way around is:
.positionAbsolute {
position: absolute;
}
#class-1,
#class-2 {
&:extend(.positionAbsolute);
}
#media only screen and (min-width: 1024px) {
#class-1 {
something: else;
}
#class-2 {
something-even: more else;
}
}
That way you will have to repeat selectors instead of media queries.
I was trying to do this, and was quite disappointed I couldn't put the extend within a media query. Fortunately I was able to use a mixin for what I wanted. This may work for some situations. I can't really tell what you're actually doing with your case.
.centerVertically()
{
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
margin-right: -0.25em;
border: 2px solid red;
.content
{
display: inline-block;
vertical-align: middle;
}
}
used in media query
#media screen and (min-width: #break_tablet)
{
/* doesn't work
&:before:extend(.centerVertically_wrapper){}
.content:extend(.centerVertically_child){}
*/
.centerVertically();
The best I came up with I turned into a GIST here. Basically, I created an externalized reference mixin for the query and imported all the possible contexts into it. LESS sees through the query when you are referencing a class to extend but it will export it.
Reference:
.narrow {
#media screen and (max-aspect-ratio: 1/1) {
#import "position";
#import "z";
}
}
Export:
#import (reference) "narrow";
.style-1:extend(.position .abs, .narrow .position .rel) {
}
.style-2:extend(.narrow .position .rel) {
}
.style-3:extend(.narrow .z .index-1) {
}

Can you create custom breakpoints with LESS mixins?

Most of the time, I use LESS variables with preset breakpoints for media queries like this:
#s-max : ~"screen and (max-width: 40em)";
#m-max : ~"screen and (max-width: 50em)";
#l-max : ~"screen and (max-width: 60em)";
USAGE
.some-class {
color: red;
#media #s-max {
color: blue;
}
}
But sometimes, I would like to be able to refer to an arbitrary breakpoint in my .less stylesheet without having to set a new preset value in my separate mixin file.
You can do this in SASS. The mixin looks like this:
#mixin bp-min($canvas) {
#media only screen and (min-width:$canvas) {#content;}
}
USAGE
#include bp-min(750px) {
//responsive styling for min-width of 750px
}
In LESS, I'm imagining the equivalent mixin would look something like this:
.bp-min(#min) {
#media only screen and (min-width:#min)...
}
The only problem is, the lack of the {#content} argument in LESS, which grabs the rest of the styling inputted by the developer. I love SASS, but I can't use it at work.
Does anyone know of a LESS-based solution to this problem?
It is now similar to SASS
As of 1.7.0 (2014-02-27) you can now use #rules in place of the sassy #content.
For example:
.breakpoint-small(#rules) {
#media screen and (min-width: 40em) { #rules(); }
}
ul {
width: 100%;
.breakpoint-small({
width: 50%;
});
}
outputs, as expected:
ul {
width: 100%;
#media screen and (min-width: 40em) {
width: 50%;
}
}
The differences being:
function takes #rules as an argument
additional parenthesis when invoking the function
'.' syntax as opposed to '#include'
This can be combined with an additional argument to provide syntax equivalent to a nice bit of sass:
.breakpoint(#size, #rules) {
#media screen and (min-width: #size) { #rules(); }
}
#large: 60em;
ul {
.breakpoint(#large, {
width: 50%;
});
}
edit: To be honest I prefer a way more simple approach in less:
#break-large: ~"screen and (min-width: 60em)";
ul {
#media #break-large {
width: 50%;
}
}
Source: I too use sass at home and less at work
Using Pattern Matching
I believe this achieves what you want:
LESS
/* generic caller */
.bp-min(#min) {
#media only screen and (min-width:#min) {
.bp-min(#min, set);
}
}
/* define them */
.bp-min(750px, set) {
test: (#min - 300px);
}
.bp-min(400px, set) {
test: (#min - 100px);
}
/* call them */
.bp-min(750px);
.bp-min(400px);
Output CSS
#media only screen and (min-width: 750px) {
test: 450px;
}
#media only screen and (min-width: 400px) {
test: 300px;
}
By defining a set pattern mixin for the various sizes, and then using that pattern within the generic .bp-min(#min) mixin, I believe we have the same abstraction in LESS that you have in SCSS, with slightly more code because I believe SCSS defines and calls in one #include statement, whereas here we need two.
(In addition to the prev. answer) Or something like this:
.bp-min(#canvas) {
#media only screen and
(min-width: #canvas) {.content}
}
// usage:
& { .bp-min(900px); .content() {
color: red;
}}
& { .bp-min(600px); .content() {
color: blue;
}}
// more usage examples:
.class-green {
.bp-min(450px); .content() {
color: green;
}}
& { .bp-min(300px); .content() {
.class-yellow {
color: yellow;
}
.class-aqua {
color: aqua;
}
}}
Replace .content with .- if you prefer shorter stuff.
In my case I needed my variables to reference other variables, so some of these solutions did not work. Here is what I went with.
#bp-xs: ~"screen and (max-width:"#screen-xs-max~")";
#bp-sm: ~"screen and (max-width:"#screen-sm-max~")";
#bp-md: ~"screen and (max-width:"#screen-md-max~")";
#bp-lg: ~"screen and (max-width:"#screen-lg-max~")";
and then use them like so
#media #bp-sm {
...
}

Resources