Custom Bootstrap SCSS with React Components - javascript

I am building a react-app, created with create-react-app, using bootstrap and react-bootstrap
I have a custom theme that is an npm package, and really just defines some variables.
#myorg/theme/lib/scss/_variables.scss:
$theme-colors: (
primary: #FFFF,
// etc...
)
Then I import this in my "site" theme before importing bootstrap:
./src/index.scss:
#import "~#myorg/theme/lib/scss/_variables.scss";
#import '~bootstrap/scss/bootstrap.scss';
Now I'd like to have components with their own specific styles, that build on bootstrap:
./src/components/MainLayout.scss:
#import "~bootstrap/scss/_functions";
#import "~bootstrap/scss/_variables";
#sidebar {
border-right: 1px solid $gray-400
}
However when I do this, it gets rid of my theme colors, so I have to do this -
./src/components/MainLayout.scss:
#import "../../index.scss";
#sidebar {
border-right: 1px solid $gray-400
}
Is this the correct way to do this? It seems to write the entire contents to the document (bootstrap and all) every time I do this, and I would be doing it a lot for many components. For instance, I have another component where I'd like to customize CardColumns (I actually can't get this to work no matter the import):
//#import ???? I need, functions, mixins, and variables from bootstrap
.card-columns {
#include media-breakpoint-only(lg) {
column-count: 10;
}
#include media-breakpoint-only(xl) {
column-count: 10;
}
}
What is the correct way to use bootstrap 4's scss files in modular react components? Without bloating the download size.

I would create 1 lib.scss file to contain all my import from library
like this name lib.scss
#import "~bootstrap/scss/bootstrap";
#import "~font-awesome/scss/font-awesome";
then when I create new module like admin module i will simply import like this
#import "./lib";
...

Related

How do i change the secondary button text color with bootstrap?

Im fairly new to CSS styling, and currently loading bootstrap into my scss main file, where im setting some colors (primary, secondary, danger, etc.) as a theme.
However, it seems that my button text gets distorted as a result of the color-contrast function in the bootstrap/functions.scss.
I would like to keep using this function for all colors except the "secondary". Is it possible to override this and define the btn-secondary-color without going through the color-contrast function?
Currently my main.scss looks like this:
$primary: #44698E;
$secondary: #90A1BC;
$danger: #D3745F;
$hoverblue: #edf6ff;
$darkblue: #103E67;
$dragoverGreen: #bfe3bf;
$dragoverRed: #e8a09e;
#import "../../node_modules/bootstrap/scss/bootstrap";
$btn-secondary-color: white;
Override bootstrap variables
First you have to import bootstrap, then you can define custom styling for every bootstrap component.
for example:
#import 'node_modules/bootstrap/scss/bootstrap';
.btn-secondary {
color: white;
}
More info here

Cannot import google fonts with Stylus on Vue

I created a project using Vue 2 with the webpack template. In the meantime I'm also working on a "component library" that I'm using locally in the project above (using npm link).
I'm using Stylus in both projects.
Now in App.vue, to be able to customize the appearance of the library, I'm importing the separate stylus files from the linked package like this:
<template>
<...>
</template>
<script>
...
</script>
<style lang="stylus">
#import "~snue/src/stylus/vars"
/*
Override default variables
*/
fontSans = "Ubuntu"
fontMono = "Ubuntu Mono"
fontNumber = "Dosis"
lighter = lighten(light, 5)
lightish = darken(light, 5)
darker = darken(dark, 5)
darkish = lighten(dark, 5)
primary = crimson
secondary = darkcyan
// Import components and style
#import "~snue/src/stylus/components"
#import "~snue/src/stylus/styles"
// Custom styles
#import url("https://fonts.googleapis.com/css?family=Dosis:400,700");
.f-number
font-family: fontNumber, Courier New, Courier, monospace
body
html
margin: 0
padding: 0
html
background-color: darkish
body
background-color: dark
color: light
</style>
Everything works fine, except for the fact that #import url(...) rules with google fonts don't seem to work.
When I run npm run dev the browser uses the fallback fonts I specified and I cannot see any request made in the network panel of the chrome inspector.
When I build the library with webpack and the extract plugin instead, I can clearly see the #import url() rules in the generated css file.
Has this something to do with some Vue setting?
It turns out the problem was postcss-import complaining about #import rules:
#import must precede all other statements (besides #charset)
I reverted back to version 7.* and now it's working fine. If you cannot switch to an older version below is a workaround that initially worked for me.
Workaround for postccs-import > 11.*
It's not a real solution, but I found a way to avoid this problem: I wrapped #import inside a #css rule, and now it works:
// Custom styles
#css
#import url("https://fonts.googleapis.com/css?family=Dosis:400,700");
To my surprise, I can even use stylus variables inside the #css literal block:
// Custom styles
fontNumberSource = replace(" ", "\+", fontNumber)
#css
#import url("https://fonts.googleapis.com/css?family="+fontNumberSource+":400,700");
So I'm ok with this for now

ReactJS styles 'leaking' to other components

So I have two components... a Navbar component, and an AboutPage component.
They are both in the same directory, 'App'
App
-- Navbar --> Navbar.css, Navbar.js
-- AboutPage --> Aboutpage.css, Aboutpage.js
So as you can see, they have two separate stylesheets.
In the JS pages the correct CSS file is being imported as well.
When I do a style like this for example:
Navbar Component
p { background: red }
^^ this style also applies to the p's in the Aboutpage. I even tried to give the P in Aboutpage its on id and style it that way and it still failed.
That's the expected behaviour.
No matter which file you specify a rule like p { background: red }, it's going to be applied to all DOM.
Specifying and id attribute to won't work either. The above rule is general enough to apply to all <p>s.
If you want to specify css files for each component, you should also create component specific css classes. Like the following example.
import React from 'react';
import './DottedBox.css';
const DottedBox = () => (
<div className="DottedBox">
<p className="DottedBox_content">Get started with CSS styling</p>
</div>
);
export default DottedBox;
and its css file:
.DottedBox {
margin: 40px;
border: 5px dotted pink;
}
.DottedBox_content {
font-size: 15px;
text-align: center;
}
If you want different ways of defining css for React, this resource adds 3 more ways of doing so, in addition to the above way.
You can also use css modules. They scope your CSS locally and are awesome
Scoping styles to a component requires WebComponents which relies on several newer browser features, particularly shadowRoot "shadownDOM" which supports this separation directly. These are most easily used with lit-element and/or Polymer 3.
Sometimes we need a global CSS which could affect another component even if we use module import, I didn't find anything to answer that in the official documentation, so my workaround is to use something like the following code in the component itself, and, it works fine :)
<style>
{
`
#page {
padding:0;
margin-top:0;
margin-bottom: 0;
margin-left: 0;
margin-right:0;
}
#media print {
#page {
size: 80mm 21cm;
}
}
`
}
</style>

Angular 4 style overriding addons

while developping an angular 4 app using angular-cli + sass, i have this problem with multiple plugins. so here is the scenario:
I have a main style.scss file that import other styles files ..., so if i want to modify a plugin style, let say a slider component styles, i will create a slider.scss and import it into my main style.scss file, the problem is that the imported component css is injected into the browser after my main css file. so when i want to modify something i need to add !important to the rule.
here is a snapshot of chrome inspect css tool:
element.style {
left: 100%;
}
<style>…</style>
.noUi-marker-horizontal.noUi-marker-large {
height: 15px;
}
<style>…</style>
.noUi-marker-horizontal.noUi-marker {
margin-left: -1px;
width: 2px;
height: 5px;
}
<style>…</style>
.noUi-marker-horizontal.noUi-marker-large {
height: 10px !important;
}
my custom css is the last one.
I want to know if there is a way to load my css style file after the components css file, i can use precedence rule to make it work, but i want to know if there is a more clean way.

ReactJS and classNames

I'm very new to ReactJS and currently using the MERN stack to create a new application.
I know, that I can use external stylesheets, by importing them:
import styles from ./Header.css
Usage:
<div className={styles["logo-home"]}>
test
</div>
.css file:
.logo-home {
background-color: #eee;
}
This is working fine, but I just can't find out, how to access something like:
.logo-home .inner {
background-color: #000;
}
I thought, this would work, when I write something like styles["logo-home"].inner or styles.inner, but it did not...
Whats the right / best way to solve this problem?
If you're cloning the MERN starter repo, you probably are using CSS modules (through webpack's setup).
The idea here is that you have your styles in a modular way with their own scope. This is achieved by adding some hashing to each classname. Like in this example:
So assuming you have
<div className={styles["logo-home"]}>
<div className={styles["inner"]}>
bla bla bla
</div>
</div>
Your imported .css file can look like this:
.logo-home { /* ... */ }
.inner { /* ... */ }
As you see, there is no need for CSS selectors as you would use in traditional CSS. You just map each container with one class name and CSSModules will make sure your class names don't collide among all your modules.
You can read more about CSSModules here

Categories

Resources