How to make font size responsive using vuetify? - vue.js

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%;
}
}

Related

Inconsistent Output between LESS Compilers

I have written some LESS code that resizes text based on browser width. Multiple different elements and their parameters can be sent to the reusable mixin.
All online LESS compilers output the desired result. But I am getting different output from Squarespace's LESS compiler.
Squarespace's compiler appears to "hang on" to the old variable values when called a second time.
Can you see how Squarespace's LESS compiler is reaching its output and, if so, share changes that can be made to make the output consistent with all other compilers?
Output from online compilers: (desired)
#media screen and (max-width: 1280px) {
.homesCommunitiesLayout #pageHeroWrapper {
font-size: 120px;
}
}
#media screen and (max-width: 640px) {
.homesCommunitiesLayout #pageHeroWrapper {
font-size: 60px;
}
}
#media screen and (max-width: 1280px) {
#divisionTitle {
font-size: 85px;
}
}
#media screen and (max-width: 853.3333333333334px) {
#divisionTitle {
font-size: 56.666666666666664px;
}
}
#media screen and (max-width: 426.6666666666667px) {
#divisionTitle {
font-size: 28.333333333333332px;
}
}
Output from Squarespace compiler: (undesirable)
#media screen and (max-width: 1280px) {
.homesCommunitiesLayout #pageHeroWrapper {
font-size: 120px;
}
}
#media screen and (max-width: 640px) {
.homesCommunitiesLayout #pageHeroWrapper {
font-size: 60px;
}
}
#media screen and (max-width: 1920px) { //<---Gone wrong! Continuing to use element1!
.homesCommunitiesLayout #pageHeroWrapper {
font-size: 180px;
}
}
#media screen and (max-width: 1280px) {
.homesCommunitiesLayout #pageHeroWrapper {
font-size: 120px;
}
}
#media screen and (max-width: 640px) {
.homesCommunitiesLayout #pageHeroWrapper {
font-size: 60px;
}
}
LESS Source Code and Link to code on Less2Css.org:
#maxSiteWidth: 1280px;
#fullWidth: #maxSiteWidth;
//Element 1 Parameters & Function Call
#fitTextElement1: ~".homesCommunitiesLayout #pageHeroWrapper";
#fitTextElement1Max: 120px;
#fitTextElement1Min: 50px;
#fitTextElement1BreakPoints: 2;
.fitText(#fitTextElement1; #fitTextElement1Max; #fitTextElement1Min; #fitTextElement1BreakPoints);
//Element 2 Parameters & Function Call
#fitTextElement2: ~"#divisionTitle";
#fitTextElement2Max: 85px;
#fitTextElement2Min: 26px;
#fitTextElement2BreakPoints: 3;
.fitText(#fitTextElement2; #fitTextElement2Max; #fitTextElement2Min; #fitTextElement2BreakPoints);
//Primary Looping Mixin
.fitText(#targetElement; #targetElementMaxSize; #targetElementMinSize; #targetElementBreakPoints) {
.mixin-loop (#loopIteration) when (#loopIteration > 0) {
#{targetElement} {
.setBreakPointWidth(#loopIteration; #targetElementBreakPoints);
#media screen and (max-width: #breakPointWidth) {
.setFontSize(#loopIteration; #targetElementMaxSize; #targetElementMinSize; #targetElementBreakPoints);
font-size: #targetElementFontSize;
}
}
.mixin-loop(#loopIteration - 1);
}
.mixin-loop(0){}
.mixin-loop(#targetElementBreakPoints);
}
//Function to set font size
.setFontSize(#loopNumber; #maxSize; #minSize; #breakPoints) {
#targetElementFontSize: (#maxSize/#breakPoints)*#loopNumber;
.resetFontSize(#targetElementFontSize; #minSize);
}
//Function to reset font size if below minimum desired
.resetFontSize(#calculatedSize; #minSize) when (#calculatedSize < #minSize) {
#targetElementFontSize: #minSize;
}
//Function to set break point
.setBreakPointWidth(#loopNumber; #breakPoints) {
#breakPointWidth: (#fullWidth/#breakPoints)*#loopNumber;
}
Note that Squarespace uses LESS 1.3.3 so you'll need to manually switch Less2Css to that version (though it doesn't seem to change anything if you don't).
Having put much more time into this, I've discovered there are a lot of issues with the code as I posted it. In older versions of LESS, variables would "leak" up to parent scopes, which is the only reason any of this code was working at all.
In the end, the solution was to abandon the old 1.3.3 version and write for the latest version, rewriting the entire code NOT to depend on such "leaks". Then to precompile using an online compiler until Squarespace updates their compiler someday. For now, I just have to precompile it before saving it to the file that is on the Squarespace Server.
Without getting in the specifics of exactly what went wrong, I'll just mention that the top reason I've had issues with LESS and Squarespace's compiler is because it's not the same as LESS. Squarespace previously used a Node implementation of Less.js, and then rebuilt the compiler in Java to gain performance over Node/Less.js.
So the key takeaway is that Squarespace's LESS compiler is based off of Less.js and not identical to the same LESS compilers a developer would use. You'll definitely find odd scenarios where things won't compile the same.
I would submit any bugs you find to the official repo here: https://github.com/Squarespace/less-compiler. Their engineers are pretty responsive!

Video.js Classes to Hide Video While Loading

I'm trying to hide a video while it's loading (e.g. the black window with just a loading spinner). The only class I've found that sort of made sense is the .vjs-has-started one but the loading screen still shows with the following CSS. I also didn't see anything in the javascript api that meets this need (sorry if I missed something).
.video-js {
display: none;
visibility: hidden;
}
.video-js.vjs-has-started {
display: block;
visibility: visible;
}
I've also tried adding .vjs-playing into the mix both in place of an in conjunction with .vjs-has-started. Any thoughts on getting this to work or a answer about why it won't currently would help. If I need to I can work on adding this to video.js if it's not already there but I first wanted to get your definitive answer on the current state of video.js for this functionality.
I added the vjs-waiting class to be able to accomplish this now vjs-waiting can be used in css to show and hide the content see the pull-request for more details.
Example:
.vjs-waiting {
visibility: hidden;
background: transparent;
}
.vjs-loading-spinner {
display: none !important;
}
Reference - https://github.com/videojs/video.js/pull/1351
You could use the vjs-waiting
.vjs-waiting {visibility: hidden;}
Hey I have been struggling with this too, Docs are not intuitive at all!
Im implementing Video JS in React Hooks, so I solved with loadingSpinner set to false;
useEffect(() => {
let player = videojs('my-player',{
autoplay: 'muted',
sources: [
{
src: videoUrl, // m3u8 format
type: "application/x-mpegURL"
}
],
controlBar: false,
loadingSpinner: false
});
player.play()
return () => {
player.dispose()
}
}, [])
Hope it helps! =)

In LESS, how to use a variable inside another?

Variable #screen-xs-max is a Bootstrap 3 variable. In my mixin, I'd like to use #class variable to get the Bootstrap variable, dynamically.
Here is a not working solution:
.make-btn-block (#class) {
#media (max-width: #screen-#{class}-min) {
// Code
}
}
.make-btn-block(xs);
Another not working solution:
~"#{#screen-#{class}-min}"
See referencing variables by name. E.g.:
.make-btn-block(#device) {
#max: "screen-#{device}-max";
#media (max-width: ##max) {
color: red;
}
}

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)).

LESS condition based on CSS class to set a LESS variable

I need to set a Less variable to match the website's active theme, ie, each theme has a different color.
I'd like to set #themeColor to the right color, based on the HTML's body CSS class that defines the theme.
For example:
body.themeBlue { #themeColor: blue; }
body.themeRed { #themeColor: red; }
This way I'd only need to use the #themeColor variable inside the other Less files.
Can anyone help?
According to this (http://www.lesscss.org/#-scope) it is possible to do something like that, but I can't make it work. what is going on here?
The LESS file cannot read the actual class applied to the html body element at run time (you would probably need to implement a javascript solution to do something like that).
If you just want to have all themed css ready for use based on the body class, the best way to implement this to have all the necessary theme based css in a mixin, then apply it under the theme classes. This reduces code duplication. For example:
LESS
//mixin with all css that depends on your color
.mainThemeDependentCss() {
#contrast: lighten(#themeColor, 20%);
h1 {color: #themeColor;}
p {background-color: #contrast;}
}
//use the mixin in the themes
body.themeBlue {
#themeColor: blue;
.mainThemeDependentCss();
}
body.themeRed {
#themeColor: red;
.mainThemeDependentCss();
}
CSS Output
body.themeBlue h1 {
color: #0000ff;
}
body.themeBlue p {
background-color: #6666ff;
}
body.themeRed h1 {
color: #ff0000;
}
body.themeRed p {
background-color: #ff6666;
}
For some other answers that deal with aspects or ways of theming, see:
LESS CSS - Change variable value for theme colors depending on body class
LESS.css variable depending on class
LESS CSS: abusing the & Operator when nesting?
Variables in Less are actually constants and will only be defined once.
Scope works within its code braces, so you would need to nest your CSS within each theme you want (which means duplication).
This is not ideal as you would need to do this:
body.themeBlue {
#color: blue;
/* your css here */
}
body.themeRed {
#color: red;
/* your css here AGAIN :( */
}
You could, however, try to use variables like this:
#color: black;
#colorRed: red;
#colorBlue: blue;
h1 {
color: #color; // black
body.themeRed & {
color: #colorRed; // red
}
body.themeBlue & {
color: #colorBlue; // blue
}
}
You would only need to declare the colours once, but you would need to constantly do the "body.themeRed" etc. prefixes where the colour varies depending on the theme.
You could actually use #import to load your theme! So common.less would contain all your default styles and #themeColor will be applied to it.
.mainThemeDependentCss() {
//file with all themed styles
#import 'common.less';
}
//use the mixin in the themes
body.themeBlue {
#themeColor: blue;
.mainThemeDependentCss();
}
body.themeRed {
#themeColor: red;
.mainThemeDependentCss();
}
BTW you should avoid using body selector in your common.less, because it wouldn't work.