How to use CSS in vue.js apps? - css

I'm having trouble understanding how exactly I should build sites with CSS. I get that each component has it's own CSS, but should I do this with every component? What if the components are huge with a lot of CSS?
I've looked at some sites that were built with vue.js and they have external CSS files such as a app.css file with a ton of internal style blocks.
I'm use to building sites with Sass in it's own /styles directory and having compass.app compile those .scss files into .css files.
Here's an example of a component css block:
<style lang="scss">
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
a {
color: red;
}
}
</style>
What if that was a thousand+ lines? Would I move that into an external scss file and if so, how? How does this all work?
Thanks.

If you concern is about code separation you can have custom CSS code in a component and add a scoped attribute so the styles you are writing there would only apply to that component:
<style lang="scss" scoped>
/* your scoped css rules here will only apply to this component */
</style>
Now if you also want to compile the CSS from all of your components and merge them into a single final CSS file that you would link from your main HTML file then you need to add a bundler/compiler such as webpack
You can also take a look at vue css-loader to understand how to modularize and compose your CSS rules.

Related

Global css file won't override component css

I have a file global.css in assets folder, file is imported in main.js. Styles from this file works only if i dont have same style applied in component style. For example, in component i have this
h1 {
font-size: 50px;
}
then in global.css
h1 {
font-size: 35px
}
this won't work. Is there a way to override component styles with this global.css?
Make sure your style tag within component has scoped attribute otherwise it'll override global styles.
Review: https://codesandbox.io/s/vue-basic-demo-j87nz0?file=/src/components/HelloWorld.vue
You need to look into CSS specificity to solve this issue.
Here, it's happening because the global style is applied at first, then component style comes in second, you could inspect that in your devtools and see various declarations applied to your h1 element.
There are of course advanced possibilities in CSS but writing something more specific
h1.my-cool-class { /* or just .my-cool-class */
font-size: 50px;
}
should be enough here.
You can use h1 { font-size: 35px !important; }
Or with classes
For example:
.headline-h1 {
font-size: 35px
}
Thank you everyone for answering. I had to deal with some messy css, every component had its own css style for every heading and paragraph(sizes, colors, fonts, etc.). I deleted all of these and put them in global.css file and then changed html elements to be compatible with sizes. That's it.

Spartacus custom styling - order of SCSS imports

I am working on custom styles for my Spartacus application and struggling with the order of the CSS rendered. Despite the order of imports in my styles.scss, my custom CSS rules are rendered in the middle of Spartacus default styling, forcing me to bump up the specificity of my rules to achieve desired results.
This is my styles.scss:
$styleVersion: 4.3;
#import '~#spartacus/styles';
#import './styles/custom/_index';
/* custom/_index.scss contains further imports of the actual styling */
and this is the snippet of the rendered CSS:
/* Spartacus defaults
...
*/
cx-wish-list-item .cx-return-button .btn-link:hover {
text-decoration: underline;
}
/* My custom code */
header .SiteLogo {
width: auto;
max-width: 150px;
}
/* Spartacus defaults continued */
cx-bulk-pricing-table table {
text-align: center;
}
/*
...
*/
Working with Spartacus 4.3 and Angular 12. My objective is to:
keep my custom code as simple and low-specificity as possible
be able to leverage Bootstrap and Spartacus variables and mixins in my SCSS
Is there a way to ensure my custom styles are rendered last, according to the imports order?
In the documentation they mention wrapping custom styles in the body tag in style.scss.
link here
Try wrapping your scss in the body tag. This worked for me.
body {
cx-wish-list-item .cx-return-button .btn-link:hover {
text-decoration: underline;
}
/* My custom code */
header .SiteLogo {
// width: auto;
width: 150px;
}
/* Spartacus defaults continued */
cx-bulk-pricing-table table {
text-align: center;
}
}
In order to control the order of styles, it is better to import the styles by yourself.
First, check the angular.json file (as there might be other Spartacus related style files) and keep only one styles file there:
"styles": [
"src/styles.scss"
],
Then, in styles file import all other styles in required order, e.g.:
#import '~#spartacus/styles/index';
#import './styles/custom/_index';

How to make these scoped styles reusable for 3 pages only without affecting other pages in Vue.js

There are global classes for components that we are using all around the project.
<style lang="scss" scoped>
.specialPages {
padding: 0 10px 30px 10px;
}
/deep/ .SelectorLabel {
white-space: nowrap;
align-items: center;
display: flex;
}
.Selector {
width: 350px;
white-space: nowrap;
}
.HitButton {
width: 250px;
}
We are using scoped for not effecting the these global classes and simply customize them in scope of the component if needed. However, currently, there are 3 pages are needing these styles and we don't want to affect the rest pages by making these styles global which is used only in 3 pages. How can we overcome this challenge and make these styles reusable only for these 3 pages?
After seeing your comment about having multiple usage of the classes, I did some research and came up with a simpler way to help you with this. I think you should have the styles in a separate .scss file(as earlier suggested) and just import in App.vue. This way you can easily use the classes in the components you want to use them in. So in App.vue, add the below import of the styles(It could live alongside other style rules you may have in the <style /> block in App.vue. Hope this helps.
// App.vue
<style lang="scss" scoped>
#import "path/to/myStyles.scss";
</style>

Does using #import more than once duplicate css?

I have an Angular CLI app and I'm using #import '~#angular/material/theming'; in the global styles.scss. I also have a component where I would like to define a css class in that component's .scss file that uses some of the Angular Material typography:
#import '~#angular/material/theming';
$config: mat-typography-config();
.myClass {
font-size: mat-font-size($config, title);
font-weight: bold;
}
By importing ~#angular/material/theming more than once in my application, will it include that css more than once and bloat my payload? Or is the Angular CLI compiler smart enough to handle this?
If you're importing the same CSS into multiple components, then yes the CSS will be duplicated, but each time it will be scoped to that component.
For example if you have the following...
product-list.component.css:
#import '../../foo.css';
...
top-bar.component.css:
#import '../../foo.css';
...
../../foo.css:
a { color: red; }
Your css output in the tag will look something like this:
<style>
a[_ngcontent-gna-c48] { color: red; }
...
</style>
<style>
a[_ngcontent-gna-c50] { color: red; }
...
</style>
Here's a full StackBlitz based on Angular's Getting Started example project.

How do I organize imports in Compass/Blueprint?

I have researched SASS and Blueprint seperately, and think I understand how they work, and I have set up my project directory using the compass CLI tool, but I am at a loss as to the correct way to organize my project.
After initializing my project with
$ compass create my_project --using blueprint/semantic
...I was told to link the generated CSS files in my HTML with these lines
<link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css" />
<link href="/stylesheets/print.css" media="print" rel="stylesheet" type="text/css" />
...but where should I put my own application-specific .scssfiles and how should I include the appropriate blueprint files?
It seems to me that I should not be including the generated print.css and screen.css directly into my HTML but instead doing something like:
#import "screen";
body {
#include container;
}
...and then using only the file generated from the above in my HTML. Otherwise why would we have a line like this in screen.scss?:
// Import all the default blueprint modules so that we can access their mixins.
#import "blueprint";
I can't use mixins in my HTML.
I'm finding the docs to be very vague and contradictory, and any sort of short example illustrating the combination of:
HTML
SCSS files generated from compass command above
SCSS files containing site-specific styling
would be very helpful for me and probably others.
The "screen.scss" and "print.scss" files are nothing magical. These are just example filenames given to the output which you can link from your HTML, but you don't have to: just delete them and create your own files if you prefer, or add your own styles to them. The intent with these 2 files is to keep the style concerns organized separately: you could add a "mobile.scss" and then link all these in your HTML, or import them together into one master file under #media blocks.
I can't use mixins in my HTML.
Mixins don't apply to your HTML. They are a helpful technique used for writing your SCSS source code: the compiled CSS output or the HTML doesn't know anything about them. You should be using mixins to take advantage of Sass.
I have researched SASS and Blueprint seperately
It's important to understand what the Blueprint classes do first, but when you use Compass there are different approaches for how you apply frameworks like Blueprint:
1. Use Blueprint's original non-semantic class names throughout your HTML
This is not considered best-practice, but it's a way to get started especially when wireframing/scaffolding:
screen.scss
#import "blueprint";
// This outputs Blueprint's classes into your stylesheet:
#include blueprint;
#sidebar { background: $blue; }
#main { background: $yellow; }
screen.css (compiled)
.column { float: ... }
.span-6 { width: ... }
.span-12 {width: ... }
/* ...etc., all of Blueprint's classes ... */
#sidebar { background: #ccf; }
#main { background: #ffc; }
index.html
<div id="sidebar" class="column span-6">sidebar content</div>
<div id="main" class="column span-12">main content</div>
The result is the same as using Blueprint without Sass/Compass. Your HTML would contain the presentational classes, which are really not too different from just using style="width:120px" on your elements: it's just done using classes instead.
2. Use Blueprint as mixins into your own semantic class names:
screen.scss
#import "blueprint";
// Do not output Blueprint's classes into your stylesheet.
// Instead, write your own classes and mixin the functionality:
#sidebar {
#extend .column;
#include span(6);
background: $blue; }
#main {
#extend .column;
#include span(12);
background: $yellow; }
screen.css (compiled)
.column, #sidebar, #main { float: left; ... }
#sidebar { width: 240px; background: #ccf; }
#main { width: 480px; background: #ffc; }
index.html
<div id="sidebar">sidebar content</div>
<div id="main">main content</div>
As you can see, the second method moves Blueprint's presentation logic out of the HTML and into the stylesheet.
The judicious use of #extend (instead of #include) is an optimization that lets you group common styles together, e.g. all the elements that are "columns" are defined once as a list of selectors; only their different widths are included directly into each element.

Resources