I need my Vue components to inherit styling and variables from other "global" imports.
I do not want to import variables and bootstrap in every single component, this seems very redundant and not best practice.
It is basic usage so Vue must have made the functionality. I have already attempted to create a base component, an "app.vue" component if you will, that has its own styling that includes the variables and bootstrap, but my components can still not access it.
Any idea?
You can do this with webpack's sass loader options that name is 'prependData'. This code will be added top of every .vue file that consist of scss style. I know this is ugly but It works. As bootstrap documentation said. You have two choices about this. One of these is adding whole bootstrap files another one is this technique.
You can check here bootstrap documentation.
// webpack.config.js
loader: 'sass-loader',
options: {
prependData: "#import '~/node_modules/bootstrap/scss/_functions.scss'; #import '~/node_modules/bootstrap/scss/_variables.scss'; #import '~/node_modules/bootstrap/scss/_mixins.scss';"
}
I know of no other way than #import the variables file in each component. Much like we have to import/require the npm libs we use in each component.
Related
For example I am trying to import .navbar-nav from bootstrap's _navbar.scss and not the whole _navbar.scss file to my compiled css file. Is there a way to do it?
Sorry if this was asked before.
You can try doing an extend:
.your-class{
#extend .navbar-nav;
}
However, this would only work if you had imported the _navbar.scss somewhere else or the bootstrap.scss.
Additional
// main.scss
#import ../wherever bootstrap file is/_navbar.scss;
#import _custom.scss;
// _custom.scss
.your-class{
#extend .navbar-nav;
}
One of the way to import .scss in javascript is
import { navbar-nav } from '_navbar.scss'
When using in your component you can do.
<div className={navbar-nav} />
if you want to import it in your .scss file then you can do.
#import '_navbar.scss'
.class {
#extend .navbar-nav
}
As you are learning Sass here are some explanations which may help:
Better wording helps ...
At first some wording to get a correct understandable communication here and anywhere else you are talking about coding:
SASS don't minify a given CSS, it writes the CSS. Minify means the process that a given CSS code is compressed by a postprocessor to a shorter way to write it, - i.e. comments and spaces will be removed ... But yes: as SASS writes CSS it is able to write code in a minified format.
What you mean is to 'reduce code' or 'avoid not needed code' as you only try to import, use and write! the only needed parts of a given module which is a good practice.
.navbar is a CSS class. SASS don't load CSS classes, it writes CSS classes. It doesn't matter if you 'write the code on your own to a SCSS file' or 'get the code from a framework/module' ... SASS writes the however prepared CSS classes to your CSS file.
What you mean is the SASS includes/imports files with code from a framework/module to write that code/classes to css. So yes: maybe you can say you 'load' that module/scss-file ... but you don't load as css class. (This is as important as 'classes' in coding allways means a special construct of excutable code which does something in your programm. CSS classes don't execute anything, in SASS they are content you want to write/output to css.)
Please: these wordings are important to understand each other and to understand the mechanic of the process how SASS works is going on as well.
Reducing code by importing only selected file is good practice
So, I am not sure if I did understand your question right:
No. You are not able to include/import/load a part of the code of a single scss-file only. If you do #import 'somefile.scss' you always get the whole code of the whole file.
Yes. you are able to include/import/load parts of a given framework/module as you are able to load only the special FILES(!) of a framework/module you need for your project.
Yes. That is a really good practice.
As you mentioned Bootstrap indeed is developed and allows you to do that. But head up. If you import i.e. the part navbar.scss (or other selected elements) it only works if you also load the other files navbar.scss depends on. That are almost variables, functions, mixins and sometimes needed JS components to this element as well. Please note, that importing the files the elements are based on (i.e. vars, functions, mixins) has to be done BEFORE you load the element (i.e. like navbars, grid,...) itself.
A way to organize your project
Yes. A good way to organize your project is to have a single(!!!) file which brings all the code together you write in other partial files yourself or which you import from other framework/modules.
In case of Bootstrap this can be (simplified example):
// ###> file: your 'custom.scss'
// Note: file is without leading underscore
// as this files GENERATES/WRITE the css to custom.css
// Files with underscore as _partial-footer-styling.scss
// are not compiled to write css on their own
// that files are only compiled to css when they are imported to files without underscore
#import 'path/your-own-vars';
// Note: technique importing files
// you don't need to write underscore and '.scss'
// Note: function of this file
// the file '_your-own-vars.scss' is to organize you needed vars special to your project
// it includes your own vars and bootstrap vars as well
// --> the Bootstrap vars in this file will overwrite the vars of Bootstrap which will be included next
#import 'bootstrap-path/functions';
#import 'bootstrap-path/variables';
#import 'bootstrap-path/mixins';
#import 'bootstrap-path/your-selected-component-1';
#import 'bootstrap-path/your-selected-component-2';
#import 'bootstrap-path/your-selected-component-3';
...
#import 'path/partial-your-own-additional-css-special-section';
#import 'path/partial-your-own-additional-css-footer-settings';
....
A detailed explanation how to include and use Bootstrap (partly if you like to do so) to your project is here: https://getbootstrap.com/docs/4.6/getting-started/theming/
I want the capability to overwrite react-bootstrap (Sass) in a Next.js app. I have this working fine in React apps, but I've been unsuccessful getting it to work in Next.js. I don't want it set globally, set in _app.js, because I need it at the component level. Ideally, I'd like do something like this inside the somename.module.scss file:
#import '~bootstrap/scss/bootstrap';
And then below that, define my classnames to extend bootstrap classes, like this:
.goright {
#extend .text-right;
}
And if this isn't possible, is there another approach to achieve the same outcome with the Next framework?
As I learned more about the purpose of css modules, I realized that I was going about this all wrong. Next supports CSS-in-JS (styled-jsx), which provides most of the kind of customization I need to do.
I have a global CSS file that contains all generic CSS.
I want to be able to extend all the classes present in this global CSS file in any of my SCSS files.
Right now it throws an error .xyz class does not exist and build fails. I tried importing this file but still build fails.
Adding !options next to class is one way for the build to pass but is there any other better way?
Bit more context for Vue users. I use VueCli3. I use <style lang="scss"> for writing SCSS and want to use extend here. Vue documentation suggesting adding prependData for adding variables. I imported the global CSS in a SCSS file and imported that file in the prependData but Vue build still fails.
It sounds like you want to globally include a CSS file with content that the SCSS blocks in each component can read. (Variables, style definitions, etc).
#extend works like a variable, meaning SCSS needs the definition style to be available as part of its compilation. So that means getting "SCSS Global Variables" working should solve your Extend problem too.
In that case, you need to tweak how Webpack deals with your components. You can do it manually as described here. Or my preference is to use a Vue Cli plugin called vue-cli-plugin-sass-resources-loader. Make sure that your component <style> section contains lang="SCSS" though I assume you're already doing that.
Using #import CSS file into SCSS file not possible to #extend any class.
But you can follow below steps for extends class from your pure css code.
Convert .css file into .scss.
import that global.scss file into another .scss file.
Then after you can use #extend for extend class in new file.
If your file have more then 1k line of code then it will get trouble for extend class.
Is there any way available as part of Bootstrap4 scss based build to add prefix to each bootstrap class in css and js to avoid name collisions.
I have used https://github.com/faucamp/bootstrap_namespace_prefixer
But this only supports bootstrap3 based css and js files.
Assuming you make use of SCSS you can prefix the whole BS4 library like:
.myprefix {
#import '~bootstrap.scss';
}
Prefixing the javascript is a little harder. I have not tried this but it looks like you can specify the CONST variables in each js file to match your prefix:
https://github.com/twbs/bootstrap/blob/v4.5.0/js/src/button.js#L23-L25
After that create your own bootstrap index.js, define all variables there and import the classes you need. Or, create a plugin in your (webpack?) buildscript to dynamically replace all classes on build.
You would need to modify the bootstrap code directly, an example of how this could be achieved elegantly in less:
.prefixname {
&-row {
...
}
}
credit for #raygerrard in this question Add prefixes to CSS class names using LESS or SASS
I am using the latest Angular(4) with Angular CLI. I followed the advice found on SO for setting up global scss that is available to components.
Angular-CLI global scss vairables
My structure looks like this
/
styles.scss
/styles
variables.scss
mixins.scss
common.scss
/app
/component1
component1.scss
/component2
component2.scss
The main styles.scss file has the following code
#import './styles/variables.scss';
#import './styles/mixins.scss';
#import './styles/common.scss';
And in my components, I start each component scss file with the statement of
#import '~styles.scss';
I thought that this was the correct way to bring global variables/mixins/common into my component's scss. However, when I started to have components within components, I began to notice that Webpack was actually creating one block per component in the page, and each one of them had all of the global scss written out in them. So there would be one block for component1, with ALL of the variables,mixins,common stuff at the top, and then another block right below that one for the other component2 in the page, with all that information again.
Besides this being extremely inefficient, it means that the global styles are overwritting themselves (can see that in chrome debug) once for each time they are loaded.
Some direction would be very much appreciated.
The <style> tags are normal angular behaviour. Each components SCSS gets written into a <style> element, so there is nothing wrong with that.
The style.scss is for global styles that do not need encapsulation. It also gets written into a <style> element, if you imported it in your angular.json:
"styles": [
"styles.css"
],
What you are getting wrong is the question you linked (which is still not accepted).
You shouldn't import your already imported styles.scss (apart from variables or mixins) into your components, because this will lead to increasing bundle sizes, as you import the code over and over (which is also the reason for the GitHub issue you mentioned).
You can use the mixins, variables and common.scss simply by including them directly in your components SCSS, just as you need them.
This is basic sass behaviour, you should never import things that result in css several times (sass files imported into component should typically only contain variables, mixins and functions). If you need your import to happen only once, add it to the default styles file.
Look here