Concat less files into single less file - less

Is this possible?
file1.less
#import "file2.less"
#import "file3.less"
.caller {
.mixin();
width: #width;
height: #height;
}
.something-with-a-background {
background: url("#{images}/other-thing.png");
}
file2.less
#import "file3.less"
.mixin() {
#width: 100%;
#height: 200px;
background: url("#{images}/white-sand.png");
}
file3.less
#images: "../img";
And have these compile to:
allFiles.less
// file3.less
#images: "../img";
// file2.less
.mixin() {
#width: 100%;
#height: 200px;
background: url("#{images}/white-sand.png");
}
// file1.less
.caller {
.mixin();
width: #width;
height: #height;
}
.something-with-a-background {
background: url("#{images}/other-thing.png");
}
I just want the output to be the files concatenated together in the right order depending on the #import statements.
What I'm trying to do: I want to be able to add a less file in my dist directory so people can use mixins/vars/etc. by importing my less file. But in development I don't want them to all be in a single file. So I need a build that'll resolve the imports for me.

This is not necessary because you can simply do:
allFiles.less
#import "file3.less"
#import "file2.less"
#import "file1.less"
and that would have the same impact for anyone trying to do:
#import "allFiles.less"
as if they were all in that file. Thanks #JeffWhelpley!

Related

How to make font size responsive using vuetify?

In vuetify they have helper classes for typography.
for example, .display-4 goods for h1. here the full list.
When I choose display-1 for some element, In all resolutions the class gets the same font size (34px).
I was expecting to:
.display-4 will have font size of 34px in screen wide of 1024px.
.display-4 will have font size of 18px in screen wide of 300px.
According to this I have two questions, why is that? and how to make my font size elements be responsive using vuetify?
Update
Vuetify version 1.5
Take a look at display helpers example to see how to use a class when hitting a breakpoint. That being said, you can use dynamic class binding and breakpoint object in Vuetify.
Example:
:class="{'subheading': $vuetify.breakpoint. smAndDown, 'display-2': $vuetify.breakpoint. mdAndUp}"
Vuetify version 2
breakpoint object
Display
My solution changes font-sizes globally in the variables.scss file:
This is assuming you're using Vuetify 2 and #vue/cli-service 3.11 or later.
Step 1:
In src/scss/ create _emptyfile.sass and _font-size-overrides.scss.
In the _emptyfile.sass you can add this comment:
// empty file to workaround this issue: https://github.com/vuetifyjs/vuetify/issues/7795
Step 2:
In the _font-size-overrides.scss file:
/**
* define font-sizes with css custom properties.
* you can change the values of these properties in a media query
*/
:root {
--headings-size-h1: 28px;
--headings-size-h2: 22px;
#media #{map-get($display-breakpoints, 'lg-and-up')} {
--headings-size-h1: 32px;
--headings-size-h2: 26px;
}
}
Step 3:
In the variables.scss file (where you override the Vuetify variables):
/**
* Override Vuetify variables as you normally would
* NOTE: remember to provide a fallback for browsers that don't support Custom Properties
* In my case, I've used the mobile font-sizes as a fallback
*/
$headings: (
'h1': (
'size': var(--headings-size-h1, 28px),
),
'h2': (
'size': var(--headings-size-h2, 22px),
)
);
Step 3:
In the vue.config.js file:
module.exports = {
css: {
loaderOptions: {
sass: {
prependData: `#import "#/scss/_emptyfile.sass"` // empty file to workaround this issue: https://github.com/vuetifyjs/vuetify/issues/7795
},
scss: {
prependData: `#import "#/scss/variables.scss"; #import "#/scss/_font-size-overrides.scss";`,
}
}
},
};
font-sizes globally in the variables.scss file
html {
font-size: 90%;
#media only screen and (min-width: 600px) {
font-size: 94%;
}
#media only screen and (min-width: 1000px) {
font-size: 98%;
}
#media only screen and (min-width: 1200px) {
font-size: 100%;
}
}

How to achieve '.class1.class2' in CSS output with no space in between

In CSS '.class1.class2' with no space between classes means:
'Select only those elements that have AT LEAST those 2 classes';
How can I declare that in LESS?
What I am getting at is:
Class featureCheckbox is declared below ...
.featureCheckbox
{
float: left;
margin-bottom: 6px;
height: 30px;
width: 300px;
font-size: 16px;
}
I wish to override 'width: 300px' with 'width: 150px' for elements that only have class="featureCheckbox class2" whilst picking up the other non-width rules associated with class featureCheckbox.
Use & to reference the current selector.
.featureCheckbox {
// styles
&.class2 {
// overrides
}
}
This will compile to:
.featureCheckbox {
/* styles */
}
.featureCheckbox.class2 {
/* overrides */
}
You can use & character for this as below:
.featureCheckbox{
&.class2 {}
}
Less is backwards compatible to CSS, basic CSS selectors work identically in LESS.
Just write
.featureCheckbox.class2 {
...
like you would in CSS.

Less, multiple imports

I thought within Less you could do imports at the rule level?
e.g. given two Less files with identical variable names but different values
#import (reference) 'file1.less'
.myrule1
{
#import (reference) 'file2.less'
// use varA from file2
}
.myrule2
{
// use varA from file1
}
Is this not allowed, it doesn't seem to be in the latest Less version
Failing that can you do this
#import (reference) 'file2.less'
.myrule1
{
// use varA from file2
}
#import (reference) 'file1.less'
.myrule2
{
// use varA from file1
}
#import (reference) 'file2.less'
.myrule3
{
// use varA from file2 again
}
What am I trying to accomplish here? Kendo UI has multiple themes with colours for grids, headers, etc. Within my less file I want to make something like this
.BlackBasedThemes
{
#import one of the black themes
.MyDiv
{
background-color: #tooltipBackgroundColor;
}
// whole bunch of other stuff
}
.NonBlackBasedThemes
{
#import one of the not black themes
.MyDiv
{
background-color: #tooltipBackgroundColor;
}
// whole bunch of other stuff
}
And then within my code the body gets the NonBlackBasedThemes or NonBlackBasedThemes class. I can just add a MyDiv, etc class to a div and get the theme appropriate colour.
I thought within Less you could do imports at the rule level?
e.g. given two Less files with identical variable names but different values
When using lessc 2.4.0 (Less Compiler) [JavaScript] i can do:
black.less:
#tooltipBackgroundColor: black;
white.less:
#tooltipBackgroundColor: white;
Then the following code:
.BlackBasedThemes
{
#import "black";
.MyDiv
{
background-color: #tooltipBackgroundColor;
}
// whole bunch of other stuff
}
.NonBlackBasedThemes
{
#import "white";
.MyDiv
{
background-color: #tooltipBackgroundColor;
}
// whole bunch of other stuff
}
compiles into:
.BlackBasedThemes .MyDiv {
background-color: black;
}
.NonBlackBasedThemes .MyDiv {
background-color: white;
}
Indeed you do not need the reference keyword (but it should also work when using it). It is not easy to see what your problem is.
Notice that you can also import one of the files into the global scope:
#import "black"; // sets `#tooltipBackgroundColor` for the global scope
.BlackBasedThemes
{
.MyDiv
{
background-color: #tooltipBackgroundColor; // uses `#tooltipBackgroundColor` from the global scope
}
// whole bunch of other stuff
}
.NonBlackBasedThemes
{
#import "white";// sets `#tooltipBackgroundColor` for only the local scope
.MyDiv
{
background-color: #tooltipBackgroundColor;// uses `#tooltipBackgroundColor` from the local scope
}
// whole bunch of other stuff
}

Variables undefined when compiling bootstrap 2.3.2 using dotless

I'm using dotless to compile an older version of Boostrap (2.3.2)
my main.less file looks like this
#import "less/variables.less";
.bootstrap {
#import url("less/bootstrap.less");
#import url("less/responsive.less");
}
When compiling it i get the error
.box-sizing is undefined on line 158 in file 'mixins.less': [157]:
min-height: #inputHeight; // Make inputs at least the height of their
button counterpart (base line-height + padding + border) [158]:
.box-sizing(border-box); // Makes inputs behave like true block-level
elements
--^ [159]: } [Done - Failed]
But if I do this it works,
#import "less/variables.less";
.bootstrap {
background-color: #white
}
Any ideas of whats wrong?
Thanks
== EDIT ==
It seems to be the enclosing of .boostrap that is the issue, when simply having
#import url("bootstrap.less");
#import url("responsive.less");
in my main.less everything works fine
consider:
mixin() {
#color: red;
}
p {
color: #color;
}
outputs:
NameError: variable #color is undefined
but:
.mixin() {
#color: red;
}
p {
.mixin();
color: #color;
}
outputs:
p {
color: red;
}
the .mixin call leaks #color inside the scope of p, see also: http://lesscss.org/features/#mixins-as-functions-feature
Solved this using winless (http://winless.org/) instead of dotless, didn't need to change anything in my less definition.

Is there any (good) way to extend a class within a mixin, and then use that mixin within a media query, using Less?

I've been working on building out some Less files to help speed up my CSS workflow, and also to help produce more efficient, cleaner CSS.
The way I see it:
Mixins are a great way to help speed up the workflow, but they have the drawback of potentially making the outputted CSS longer than necessary.
Extending classes is the ideal solution for ensuring the amount of duplicate style declarations is minimized, helping clean that up...
So, to help balance things out I wrote out a set of standard, commonly used styles, using dummy classes (they are stored in a file which is imported by reference, so the styles are only output if they get extended).
I set all of my Mixins to extend these classes wherever possible, which worked great for the most part.
However, I realized my pitfall once I got to my media queries... I can't extend those classes within the media query, which would be fine normally, I would just remember not to do so.. But since the Mixins also now use my extends, I can now no longer use them inside media queries either.
I'm not willing to avoid using the Mixins inside of the media queries because of this, but I'd really love to be able to find a way to keep extending classes within them to keep my output as clean as possible.
The only idea I've thought of so far is to add an extra parameter to every Mixin to specify wether it should extend or not, but that's less than ideal.
My hope is that someone can come up with a much more clever solution, that would allow me to maintain the benefit of Mixins which extend base style classes, but also maintain easy usability, without over complicating things. Might be a tall order, but here's hoping.
In case my explanation was hard to follow, this is what I would have hoped to be able to do, but is not currently possible:
Ideal Input
// extensions.less
.block {
display: block;
}
// mixins.less
#import (reference) "extensions";
.mixin {
&:extend(.block);
margin: auto;
}
// styles.less
#import "mixins";
.element1 {
.mixin();
}
.element2 {
.mixin();
}
#media only screen and (max-width: 768px) {
.element3 {
.mixin();
}
.element4 {
.mixin();
}
}
Ideal Output
// styles.css
.element1, .element2 {
display: block;
}
.element1 {
margin: auto;
}
.element2 {
margin: auto;
}
#media only screen and (max-width: 768px) {
.element3, .element4 {
display: block;
}
.element3 {
margin: auto;
}
.element4 {
margin: auto;
}
}
In short, yes, currently it is somewhat possible but requires some additional wrapping for a top level classes:
// extensions.less
.block {
display: block;
}
// mixins.less
#import (reference) "extensions";
.mixin() {
&:extend(.block);
margin: auto;
}
// styles.less
#media all { // !
#import "mixins";
.element1 {
.mixin();
}
.element2 {
.mixin();
}
}
#media only screen and (max-width: 768px) {
#import (multiple) "mixins";
.element3 {
.mixin();
}
.element4 {
.mixin();
}
}
.element1 and .element2 (and any other class to extend .block) have to be put into #media all because currently:
Top level extend matches everything including selectors inside nested media
So if .element1 and .element2 stay in the global scope they leak into every other #media .block declaration.
(Hmm, actually for me this "top level extend matches everything" thing looks questionable and contradicts another "extend inside a media declaration should match only selectors inside the same media declaration" rule (obviously because global scope = #media all thus they should work identically)).