Using rulesets in LESS for media queries - less

When using Sass I would do something global like this (which I got from CSS-tricks btw)
// Variables for MQ's
$mq-mobile-portrait : 320px !default;
$mq-mobile-landscape : 480px !default;
$mq-tablet-portrait : 768px !default;
$mq-tablet-landscape : 1024px !default;
$mq-desktop : 1382px !default;
Then I would create mixins for the media queries like this (I'll only include a few to give you an idea
// Mixins
// Both portrait and landscape
#mixin mobile-only {
#media (max-width : $mq-mobile-landscape) {
#content;
}
}
// Everything up to and including the portrait width of the phone
// Since it's the smallest query it doesn't need a min
#mixin mobile-portrait-only {
#media (max-width : $mq-mobile-portrait) {
#content;
}
}
So Sass has this #content which is great because it means that I don't have to declare the content within the mixin but can do an #include mixinName and it creates the parent wrapper for any CSS properties I need to put into it across different files. I discovered that this worked well for my work flow.
So here's an example of that in a partial .scss file:
section.footer {
height: 90px;
padding: 0 10px;
#include mobile-portrait-only {
padding-top: 10px;
background: $gum;
div.ftrLogo {
display: inline-block;
margin: 0;
height: 70px;
width: 45%;
div.smlLogo {
display: block;
background: url('../images/svg/small-logo2.svg');
width: 106px;
height: 49px;
margin: 0 auto;
padding: 0;
}
p.footer {
font-size: .375em;
color: $white;
text-align: center;
}
}
}
So as you can probably gather the #content allows you to just call an empty media query wrapper anywhere in your files (obviously you have to import all of your partials into one main file) but this is great.
Today I'm using LESS on a project and I like it a lot the problem is I can't seem to find an equivalent solution in LESS-land.
I was reading up on passing rulesets http://lesscss.org/features/#detached-rulesets-feature which looks like it's close to what I want but my brain is not understanding it today; I'm optimistic about tomorrow.
If anyone has tried anything like this or can immediately see the error in my ways; please provide your two cents. I really want to figure it out and thought to ask this gifted community of SO'ers.
Thank you in advance you're a baller!

// Variables for MQ's
#mq-mobile-portrait: 320px;
// Mixins
.mobile-portrait-only(#rules) {
#media (min-width: #mq-mobile-portrait) {
#rules();
}
}
Now you can use the following code:
div {
color: white;
.mobile-portrait-only({
color: white;
width: 100%;
max-width: 500px;
});
}
The above will compile into CSS code as follows:
div {
color: white;
}
#media (min-width: 320px) {
div {
color: white;
width: 100%;
max-width: 500px;
}
}
So detached rules are rules between {} assigned to a variable:
#detached: {};
Detached rules can be used as an argument for a mixin:
.mixin(#detached){}
You as call the above mixin with a detached rule as a parameter:
.mixin({color: red;});
or
#detached: {color: red;} // watch out for the last declaration wins rule for variables
.mixin(#detached);
Inside the mixin you should call the detached rules set to copy its properties and selectors (in fact you don't copy but insert them read for processing):
.mixin(#detached-rules) {
#detached-rules(); // parenthesis are required here
}
Finally for your example your code should look like that shown below:
#gum: url();
#white: white;
// Variables for MQ's
#mq-mobile-portrait: 320px;
// Mixins
.mobile-portrait-only(#rules) {
#media (min-width: #mq-mobile-portrait) {
#rules();
}
}
section.footer {
height: 90px;
padding: 0 10px;
.mobile-portrait-only( {
padding-top: 10px;
background: #gum;
div.ftrLogo {
display: inline-block;
margin: 0;
height: 70px;
width: 45%;
div.smlLogo {
display: block;
background: url('../images/svg/small-logo2.svg');
width: 106px;
height: 49px;
margin: 0 auto;
padding: 0;
}
p.footer {
font-size: .375em;
color: #white;
text-align: center;
}
}
});
}

I hadn't thought of doing it like Bass Jobsen suggested (although I've now seen that his approach is basically how the less docs do it), but I invented a mixin which I think is a bit more flexible. Though they are similar in result, I think the following solution allows for more customization and is easier to implement on the fly.
First I define the different sizes I want to use - to keep it simple, I'll just do two using a 'mobile first approach' (meaning if I don't include a media query, the rules will apply to all sizes and I should only include queries for sizes larger than mobile).
#tablet:~"(min-width:768px)";
#desktop:~"(min-width:1100px)";
Then the mixin:
.respond(#_size;#_rules){
#media #_size {
#_rules();
}
}
And Used Like the following:
.selector {
background:green;
.respond(#tablet,{
color:red;
background:blue;
});
}
And That Outputs:
.selector {
background:green;
}
#media (min-width:768px){
.selector{
color:red;
background:blue
}
}
With only two sizes to remember, it is easy enough just to do it the way Bass Jobsen suggested, but in practice, depending on how fine-grained I want my control to be, I may define up to 8 different media sizes (though I rarely use them all), and my approach above makes the process like calling one function rather than defining 8 different functions ( as I would do were I using the alternate approach ).
Hope this helps someone. It saves me a ton of time.

Related

Why can i not override the body overflow-y with a media query?

I might make a obvious mistake but somehow I am stuck with the following:
only for large screens i don't want the vertical scrollbar so i have this simple css:
#media (min-width : 2000px) {
// hacky
body {
overflow-y:hidden !important;
}
.mt-5{
margin-top: 80px !important;
}
.mb-5{
margin-bottom: 80px !important;
}
...more style definitions
but somehow this doesn't work
i am using chrome's toggle device bar tool to switch between different resolutions. All other css definitions for > 2000px are there, only body doesn't seem to be set??
#media (min-width : 2000px) {
body {
overflow-y:hidden !important;
}
.mt-5{
margin-top: 80px !important;
}
.mb-5{
margin-bottom: 80px !important;
}
}
Did you set 100% height for html and body, like this:
html, body {
height: 100%;
}
And also for possible other child elements inside body which span the whole height of body?
Otherwise one of them will get a scroll bar (not necessarily body, but it will look very similar)

Less preprocessor removes repeated properties [duplicate]

This question already has an answer here:
How to keep duplicate properties in compiled CSS file when use LESS?
(1 answer)
Closed 6 years ago.
I was unsetting a particular color by using initial, but IE doesnt support initial so I had to provide a specific color for it. So below was the format I used.
Initially:
a.link-ele {
color: initial;
&:hover {
text-decoration: none;
color: initial;
}
}
In order to support IE:
a.link-ele {
color: black;
color: initial;
&:hover {
text-decoration: none;
color: black;
color: initial;
}
}
Here black will be set in IE and initial in browsers which support it since initial comes later.
PROBLEM: Less, in-order to optimize the CSS uses only color:initial; since it thinks its quite obvious the second one will be used by browser.
Alright so for that I do the below:
a.link-ele {
color: initial;
&:hover {
text-decoration: none;
color: initial;
}
}
.link-ele {
color: black;
&:hover {
color: black;
}
}
I changed the specificity thinking Less would not remove it but it looks like Less still uses the higher specificity value.
Question: How do I make Less allow both values?
Note: I know to make it work using different class-names or other ways, I just want to know is there a flag or something I can set which makes Less to allow both colors.
I have already tested the above concept in IE and other browsers and it works fine
I use ember-cli and emberjs framework
As I had mentioned in my comment, the Less compiler does not remove any properties from the compiled output even if it is redundant information. The compiler would still give the below output with both the color: black and the color: initial settings. A demo is available here.
a.link-ele {
color: black;
color: initial;
}
a.link-ele:hover {
text-decoration: none;
color: black;
color: initial;
}
The removal of redundant properties should therefore be getting done by some CSS compressor or minifier because they are generally the ones which strip out all redundant and unwanted information. In you case it seems to by minifyCSS.

Changing size of Dojo Filtering Select via CSS in XPages

I just want to change the size of Dojo Filtering Select design element via CSS.
I tried manual or CSS File. It did not work.
<xe:djFilteringSelect id="djselect1" value="#{document1.Language}" style="min-height: 8px;height:8.px;"></xe:djFilteringSelect>
Any suggestion is important
Cumhur Ata
You just need to override the dijitTextBox CSS class.
You might need to use CSS specificity to make sure that the CSS is picked up (instead of using !important).
Here's a simple example:
.dijitTextBox {
width: 40px;
height: 8px;
}
As you are using Bootstrap theme you need to adjust the arrow button too.
This works for me:
.dbootstrap .dijitTextBox {
height: 24px;
}
.dbootstrap .dijitComboBox .dijitButtonNode.dijitArrowButton {
height: 22px;
}
.xsp.dbootstrap .dijitInputContainer {
padding-top: 0px;
}
.dbootstrap .dijitComboBox input.dijitArrowButtonInner {
margin-top: -3px;
margin-left: -5px;
}
.dbootstrap .dijitMenuItem {
padding: 0px 10px;
}

LESS function that builds a media query

Can you write a function in LESS that outputs a media query when you pass in values for it's breakpoints?
I'd like to be able to create them on the fly like this:
// Something like this
.media(#min, #max) {
#query: ~"#media (min-width: #{min}) and (max-width: #{max})";
}
.class {
.media(100px, 400px) {
color: red;
}
.media(401px, 500px) {
color: green;
}
}
// Outputs this:
#media (min-width: 100px) and (max-width: 400px) {
.class {
color: red;
}
}
#media (min-width: 401px) and (max-width: 500px) {
.class {
color: green;
}
}
I thought I had this working, but because the mixins are called within the same scope, the variable isn't being assigned in the second call:
.media (#min, #max) {
#query: ~"(min-width: #{min}) and (max-width: #{max})";
}
.class {
width: 100%;
max-width: 300px;
.media(100px, 400px);
#media #query {
color: red;
}
.media(401px, 800px);
#media #query {
color: green;
}
}
The main problem of your first snippet is that you can't use mixin call to set an identifier for a {...} block. In the snippet the following:
.media(100px, 400px) {
color: red;
}
is actually a new mixin definition and not really a previously defined .media mixin call (so it simply outputs nothing since this new mixin is never invoked).
And proper mixin call syntax:
.media(100px, 400px); {
color: red;
}
in such context would be an equivalent to:
#query: ~"#media (min-width: 100px) and (max-width: 400px)"; {
color: red;
}
which of course does not make any sense for Less at all and it would throw a error.
-------
Your second snippet is more correct, but yes, since both mixin calls share the same scope there's only one #query variable. It's possible to isolate them by putting each into unnamed namespace (which is simply a ruleset with & name so it creates a new scope but then is output as part of the outer ruleset):
.class {
& {.media(100px, 400px);
#media #query {
color: red;
}}
& {.media(401px, 800px);
#media #query {
color: green;
}}
}
This does the trick but obviously it does not look like something really useful (too verbose and unreadable) so for the sake of reference it would make sense to mention other approaches:
-------
Today, the most clean solution for the particular case would be to use ruleset as mixin parameter:
.media(#min, #max, #styles) {
#media (min-width: #min)
and (max-width: #max) {
#styles();
}
}
.class {
.media(100px, 400px, {
color: red;
});
.media(401px, 800px, {
color: green;
});
}
Though I doubt that in a practical project you'd want to explicitly repeat pixel values every time you need the corresponding media so most likely eventually you end with more semantic mixins, e.g.:
.media(#min, #max, #styles) {
#media (min-width: #min)
and (max-width: #max) {
#styles();
}
}
.tiny-screen(#styles) {.media(100px, 400px, #styles)}
.not-so-tiny-screen(#styles) {.media(401px, 800px, #styles)}
.class {
.tiny-screen({
color: red;
});
.not-so-tiny-screen({
color: green;
});
}
------
Passing rulesets to mixins is not the only method to achieve the goal, there're other methods with various pros and cons (some of those can look even more readable if you go the "semantic media blocks" way). See for example https://stackoverflow.com/a/15842048/2712740 (obviously search for [less] media here at SO will point to more inspirations).

Bootstrap & LESS: importing mixins only as reference

I am using Bootstrap 3.0 & LESS 1.5. I'll be using the same bootstrap.css for many sites (or use their CDN). So I am using
#import (reference) "bootstrap-3.0.0/less/bootstrap.less";
#import (reference) "bootstrap-3.0.0/less/mixins.less";
to import only as reference.
My app.less has (among otherthings)
.herocontainer{
.make-row();
.iphoneblock{
.make-sm-column-offset(1);
.make-sm-column(4);
text-align: center;
}
.copyblock{
.make-sm-column(5);
text-align: center;
.copytext{
#media(min-width: #screen-sm) {
padding-top: 100px;
}
}
.buybutton{
.btn-lg;
.btn-primary;
background-color: #d6822f;
}
}
}
The resulting site is just single column output. But if I remove (reference) from the mixins, like:
#import (reference) "bootstrap-3.0.0/less/mixins.less";
then I get a two column responsive output, but the resulting css also has classes that I don't need.
So,
a) how do I get classes in css only for the ones that I write in app.less and not bloated with bootstrap classes
b) how do I go about debugging such css issues? (I do use Google chrome tools but this issue is more than I can understand/debug)
Thank you,
Joseph
Also see: https://stackoverflow.com/a/14463540/1596547. Which says:
No actual code will output from that file as CSS, but all becomes available to use as mixins.
In you case their will be a difference with for example make-sm-column() this mixin contains a media query definition. If you use (reference) when importing mixins.less this media query part is NOT include in your CSS.
// Generate the small columns
.make-sm-column(#columns; #gutter: #grid-gutter-width) {
position: relative;
// Prevent columns from collapsing when empty
min-height: 1px;
// Inner gutter via padding
padding-left: (#gutter / 2);
padding-right: (#gutter / 2);
// Calculate width based on number of columns available
#media (min-width: #screen-sm-min) {
float: left;
width: percentage((#columns / #grid-columns));
}
}
Will give:
.herocontainer {
position: relative;
min-height: 1px;
padding-left: 15px;
padding-right: 15px;
}
#media (min-width: 768px) {
.herocontainer {
float: left;
width: 33.33333333333333%;
}
}
With using (reference) you will only got:
.herocontainer {
position: relative;
min-height: 1px;
padding-left: 15px;
padding-right: 15px;
}
NOTE you also use btn-lg with came from buttons.less. For me it seems the best solution to reference button.less but not mixins.less (theoretical mixins should contain mixins only, so referencing should make any difference). Otherwise create a mixins.less with only the mixins you will need.
UPDATE
there is a bug Reference import not importing media queries
when a class in a referenced import calls a mixin from a not referenced import, the output of this mixin will be (unexpected) shown in your css. So in the answer above not using reference for mixins.less will indeed give a lot of unwanted classes