How to do breakpoints in scss file with vuetify? - vue.js

How to use media query breakpoints in my vuetify application but in scss file?
For example bootstrap enable me to do that in scss file:
#include media-breakpoint-up(sm) {
.custom-class {
display: block;
}
}
what is the equivalent in vuetify? I can't find any documention in vuetify website

You can do it in scss:
#import '~vuetify/src/styles/settings/_variables';
#media #{map-get($display-breakpoints, 'sm-and-down')} {
.custom-class {
display: block;
}
}
... and you're right there is very little docs regarding breakpoints within vuetify

I achieved this by attaching a class name corresponding to the breakpoint, which is available in the $vuetify.breakpoint object. Not a perfect solution, but I only needed to do it for once element in my app. Hope it helps!
Example:
<item :class="($vuetify.breakpoint.smAndDown) ? 'sm' : ''"></item>
...
<style scoped lang="scss">
#item{
right: 130px;
&.sm{
right: 35px;
}
}
</style>

Related

Why do SCSS variables imported from another file doesn't work in Vue 3?

I have installed sass loader in my vue 3 project, but the issue is that I want to import variables from another file, but doesn't work
my schema is:
src
assets
scss
styles.scss
_variables.scss
styles.scss
#import url('./_variables.scss');
body{
font-family: 'Montserrat';
background-color: $primary-black;
}
.sidebar{
width: 250px;
height: 100vh;
max-height: 100vh;
background-color: $primary-black;
}
_variables.scss
$primary-black: #222222;
App.vue
Some HTML
<script>
import Sidebar from './components/Sidebar';
export default {
components: { Sidebar },
setup() {
},
}
</script>
<style lang="scss" scope>
#import url('./assets/scss/styles.scss');
</style>
And the issue is that in the browser the $primary-black variable fails, it appears background-color: $primary-black literally, I mean doesn't take de "#222222" color instead, but if I change the variable, and put it inside the styles.scss file, it works, so I'm not sure what could be the problem
Do not use the url function while importing, try the below
<style lang="scss" scope>
#import './assets/scss/styles.scss'
</style>

Importing SASS variables into Vue component

I'm working on building a webpage using Vue, Typescript, Webpack, and Bulma. I got everything working and building correctly but I noticed that some of my bundles were massive (over 2mb in some cases). After a lot of confusion I figured out it was because I was importing my main SCCS file that included Bulma, Bulma Fluent, and Material Design Icons into my components so that I could use the variables, mixins, and extend some of the classes. From what I understand #import simply copies everything from the import, which would explain my massive bundles.
A close approximation of my working code:
main.scss
/*Color customizations*/
#import "bulma-fluent/bulma.sass";
#import "buefy/src/scss/buefy";
#import "#mdi/font/scss/materialdesignicons";
/*Some custom classes*/
MyComponent.vue
/*Template and Script here*/
<style scoped lang="scss">
#import "./main.scss";
.floating {
#extend .m-1;
position: fixed;
bottom: 0;
right: 0;
}
#include mobile {
.floating {
max-width: unset;
left: 0;
}
}
</style>
I want to be able to reference classes/variables/mixins from my main.scss without it ballooning the size of my modules. I thought about creating a separate variables.sass file but I couldn't get that to work plus it doesn't fix the issue of extending styles. I saw this question but I'm not using Nuxt.
How can I get this working?
P.S. I'm a bit of a noob when it comes to Webpack/Vue/SASS/SCSS so I apologize if I'm just being dumb here.
Edit
In the end I split out the variables to their own file and imported those globally. It doesn't solve the use case of extending styles but I think that's a lost cause. My code is below:
Variables.scss
/*Customization here*/
#import "bulma/sass/utilities/functions.sass";
#import "bulma-fluent/src/sass/color/_all.sass";
#import "bulma/sass/utilities/initial-variables.sass";
#import "bulma/sass/utilities/derived-variables.sass";
#import "bulma/sass/utilities/mixins.sass";
Main.scss
#import "./Variables.scss";
#import "bulma-fluent/bulma.sass";
#import "buefy/src/scss/buefy";
#import "#mdi/font/scss/materialdesignicons";
/*Some custom classes*/
webpack.js
/*Other irrelevant configurations*/
{
test: /\.s[ac]ss$/,
use: [
"vue-style-loader",
"css-loader",
{
loader: "sass-loader",
options: {
additionalData: `
#import "./Variables.scss";
`
}
}
]
},
MyComponent.vue
/*Template and Script here*/
<style scoped lang="scss">
.floating {
margin: $size-1;
position: fixed;
bottom: 0;
right: 0;
}
#include mobile {
.floating {
max-width: unset;
left: 0;
}
}
</style>
I use the same stack. I have variables.scss file with variables and bulma mixins and that variables.scss file is imported only in main.scss .
To make all variables and mixins available in all components without using #import in style section you should add loaderOptions section to vue.config.js file. Here is my vue.config.js file:
module.exports = {
css: {
loaderOptions: {
scss: {
prependData: '#import "~#/assets/scss/_variables.scss";'
}
}
}
}

background property not working in Vue.js

Background properties are somehow not working inside my scss file, all other properties do work.
when i use this for example
scss file:
body {
background: #202020;
font-size: 62.5%;
}
browser never returns background (i tested this with different elements and files):
body {
font-size: 62.5%;
}
I use the standard Vue installation which is suitable with scss/css/sass
I include my scss files inside my main.js file like this
import './assets/scss/main.scss'
I also tried using it inside a scoped tag
<style lang="scss" scoped>
.layout { background: red; height: 100vh; }
</style>
but only the height applied
import inside style tag doesn't work either
<style lang="scss">
#import "../assets/scss/main.scss";
</style>
I know it sounds like a stupid typo or something but i can assure you it's not.

Customizing Buefy with SASS in vue.js

I'm a beginner at this and I'm struggling with changing style for buefy elements. In particular the buefy tabs.
In my component, I've got this style:
<style lang="scss" scoped>
// Import Bulma's core
#import "~bulma/sass/utilities/_all";
// Set your own stuff
$my-primary: red;
$link: red;
$colors: (
"primary": ($min-primary, $primary-invert)
);
$tabs-toggle-link-border-color: red;
$tabs-toggle-link-border-style: red;
$tabs-toggle-link-hover-background-color: red;
$tabs-toggle-link-hover-border-color: red;
$tabs-toggle-link-active-background-color: red;
$tabs-toggle-link-active-border-color:red;
$tabs-toggle-link-active-color: $link-invert !default;
// Import Bulma and Buefy styles
#import "~bulma";
#import "~buefy/src/scss/buefy";
</style>
And my tab is formatted like this:
<b-tabs type="is-toggle" size="is-medium" expanded>
The link color and the primary color are changed like expected. But the tabs remain in their original color.
There are two things I find strange:
If I move this styling to App.vue and remove the "scoped" - the styling does
not work. However - the primary color and the link color changes to purple (not turquoise like I'd expected and which it does if I just remove the $colors from within the component). I thought all styling added to App.vue would work in all components?
Why does not the tabs change color? Have I got the wrong variables? How do I find the right variables? The variables used here is found in bulma/sass/components/tabs.sass.
Both node-sass and sass-loader are installed.
Hope somebody can make me feel a bit more enlightened.
Edit: it turns out, there is a way how to get it working with scoped styles. For that all you need is to wrap #import statements into /deep/ selector:
<style lang="scss" scoped>
... // everything else remains the same
/deep/ {
// Import Bulma and Buefy styles
#import "~bulma";
#import "~buefy/src/scss/buefy";
}
Original answer
Even though this it's a bit old question, I faced the same problem recently with dropdown component.
Variables in original code are correct, but it does not work due to scoped styles. Since #import is called in scoped context, it will be also scoped and thus CSS will not match HTML.
Assuming that original code in tab component is something like this:
$tabs-border-bottom-color: $border !default
$tabs-border-bottom-style: solid !default
$tabs-border-bottom-width: 1px !default
.tabs
#extend %block
+overflow-touch
#extend %unselectable
align-items: stretch
display: flex
font-size: $size-normal
justify-content: space-between
overflow: hidden
overflow-x: auto
white-space: nowrap
a
align-items: center
border-bottom-color: $tabs-border-bottom-color
border-bottom-style: $tabs-border-bottom-style
border-bottom-width: $tabs-border-bottom-width
....
After compiling Vue loader will add [data-v-xxxxxxx] so it will look:
.tabs[data-v-xxxxxx] {
// styles go here
}
but html for tabs is not scoped and this is the reason why it does not work.
One way to get it working would be to remove scoped, but wrap all your styles
into some class name to keep all css private for the component. Assuming that template root element has class my-component-wrapper, scss will be following:
<style lang="scss" scoped>
.my-component-wrapper {
// Import Bulma's core
#import "~bulma/sass/utilities/_all";
// Set your own stuff
$my-primary: red;
$link: red;
$colors: (
"primary": ($min-primary, $primary-invert)
);
$tabs-toggle-link-border-color: red;
$tabs-toggle-link-border-style: red;
$tabs-toggle-link-hover-background-color: red;
$tabs-toggle-link-hover-border-color: red;
$tabs-toggle-link-active-background-color: red;
$tabs-toggle-link-active-border-color:red;
$tabs-toggle-link-active-color: $link-invert !default;
// Import Bulma and Buefy styles
#import "~bulma";
#import "~buefy/src/scss/buefy";
}
</style>
Worth noting that you do not have to import bulma and buefy for each component, it's better to import main/general styles in main file and then import only necessary components (#import "~bulma/sass/components/tabs";).

Vue.js style v-html with scoped css

How can I style v-html content with scoped css using vue-loader?
Simple example:
component.vue
<template>
<div class="icon" v-html="icon"></icon>
</template>
<script>
export default {
data () {
return {icon: '<svg>...</svg>'}
}
}
</script>
<style scoped>
.icon svg {
fill: red;
}
</style>
generate html
<div data-v-9b8ff292="" class="icon"><svg>...</svg></div>
generate css
.info svg[data-v-9b8ff292] { fill: red; }
As you can see v-html content don't have data-v attribute, but generate css have data-v attribute for svg.
I know this is expected behavior for vue-loader (https://github.com/vuejs/vue-loader/issues/359). And in this issue descendent selectors mentioned. But as you can see I use it in my css and it's not worked.
How can I style v-html content?
I am using vue-loader 15.9.1. The >>> solution did not work for me (no effect) whereas the /deep/method resulted in building errors...
Here is what worked instead:
.foo ::v-deep .bar { color: red; }
As stated in my answer here:
New version of vue-loader (from version 12.2.0) allows you to use "deep scoped" css. You need to use it that way:
<style scoped> now support "deep" selectors that can affect child
components using the >>> combinator:
.foo >>> .bar { color: red; } will be compiled into:
.foo[data-v-xxxxxxx] .bar { color: red; }
More informations on the release page of vue-loader
AS Sarumanatee said if the accepted answer doesn't work try:
.foo /deep/ .bar { color: red; }
Using /deep/ selector with SCSS didn't work for me but then I tried using ::v-deep selector
e.g
::v-deep a {
color: red;
}
See this answer