React component styling being overridden by global styling - css

Okay, just to state the problem right away, I have a situation where stylesheet B which is being loaded (or so I thought) AFTER stylesheet A, and should therefore be overriding A's styling because of cascading, is in fact being loaded into the browser BEFORE A. The order is wrong.
I have a simple React component structure as follows:
App
> Header
> Home
> Footer
In my 'index.js' I have the basic order of statements:
import './assets/theme/theme_specific/scss/style.scss';
render(
<Router history={browserHistory}>
<Route path="/" component={App}>
<IndexRoute getComponent={lazyLoadComponent(Home)} />
<Route path="/resume" getComponent={lazyLoadComponent(Resume)} />
</Router>,
document.getElementById("app")
);
Here's the structure in App.js:
class App extends React.Component {
render() {
return (
<div>
<Header />
{this.props.children}
<Footer />
</div>
);
}
}
And at the top of Header.js I have the following:
import './Header.scss';
The Webpack loader that's processing .scss files is:
test: /\.scss$/,
loader: 'style!css?sourceMap!resolve-url!sass?sourceMap',
I've confirmed that there is no !important being used anywhere, and the styling itself is exactly the same.
What's happening is that "Header.scss" is being loaded FIRST, and 'style.scss' SECOND. In other words 'style.scss' is overriding the styles in 'Header.scss', versus the other way around as they appear in the code. The 'Computed' tab in Chrome inspector confirms this is the case.
Anybody have any idea what's going on here?

The CSS is imported in the order you specify. If you'd like your custom styling to have the highest precedence, put import './Header.scss'; beneath all the other imports.

Feeling very stupid now. I answered my own question just a few minutes after posting. #David L. Walsh above is correct.
The problem was that in 'index.js' I was importing the React component files before the CSS files (including 'style.scss' mentioned above).

Related

Headless UI Transition.child errors to "Did you forget to passthrough the `ref` to the actual DOM node"

I'm building a sidebar with the Transition and Dialog Headless UI components.
Transition docs
When I break out the code that's passed between <Transition.Child> to it's own component. I get this error:
Unhandled Runtime Error
Error: Did you forget to passthrough the `ref` to the actual DOM node?
Call Stack
eval
node_modules/#headlessui/react/dist/components/transitions/transition.js (1:3632)
Failing code:
<Transition.Child as={Fragment}>
<Cart
cancelButtonReference={cancelButtonReference}
setCartOpen={setCartOpen}
checkoutUrl={checkoutUrl}
removeCartItem={removeCartItem}
clearCart={clearCart}
cartLoading={cartLoading}
incrementCartItem={incrementCartItem}
decrementCartItem={decrementCartItem}
cartTotal={cartTotal}
cart={cart}
/>
</Transition.Child>
Working code:
<Transition.Child as={Fragment}>
<div>
...
</div>
</Transition.Child>
I understand the error I believe, which is that when I break out the code to it's own component Transition.Child wants me to pass a ref so that React knows that it should render a component and not a fragment.
If I remove as={Fragment}, which makes the Transition default to a div the error goes away, but then I get an unneeded div..
What ref do I need to pass? This is what I don't get.
You don't need to pass a ref, but the component needs to accept one and set it on the actual element.
The div element will accept the ref, which is why that method works.
Try creating the Cart component using React.forwardRef and set the ref on the div.
const Cart = React.forwardRef((props, forwardedRef) => {
return (
<div ref={forwardedRef}>
...
</div>
)
})
I ran into the same issue, and just found a solution—which you basically already said, too.
Through some testing, as you pointed out, it works when surrounding the component with the <div>…</div> tags.
Although I don't really understand it, it's clear that Headless UI's <Transition> tag wants to pass a reference to it's immediate child. With normal HTML tags, like <div>, it does it automatically. When using a component, it can't do it in the same way.
Solution #1
(Broken*)
I'm sure there's a more "proper" solution to this, but I found that—as we don't want <Transition> to render any HTML tags—you can just surround your component with another React fragment:
<Transition.Child as={Fragment}>
<> {/* <— Our new Fragment */}
<Cart
cancelButtonReference={cancelButtonReference}
setCartOpen={setCartOpen}
checkoutUrl={checkoutUrl}
removeCartItem={removeCartItem}
clearCart={clearCart}
cartLoading={cartLoading}
incrementCartItem={incrementCartItem}
decrementCartItem={decrementCartItem}
cartTotal={cartTotal}
cart={cart}
/>
</>
</Transition.Child>
This was working for me for a bit, but then just stopped working.*
Solution #2
(This also appears to not function correctly*)
As a secondary option, if you don't mind having another element rendered on the DOM, you can set the <Transition> to render as={'div'} (this is the default, so you don't actually have to define the prop), and then set the CSS display to contents:
<Transition.Child style={{display: 'contents'}}> {/* <— display set to contents */}
<Cart
cancelButtonReference={cancelButtonReference}
setCartOpen={setCartOpen}
checkoutUrl={checkoutUrl}
removeCartItem={removeCartItem}
clearCart={clearCart}
cartLoading={cartLoading}
incrementCartItem={incrementCartItem}
decrementCartItem={decrementCartItem}
cartTotal={cartTotal}
cart={cart}
/>
</Transition.Child>
If you're not familiar with display: contents, Manuel Rego give this description:
display: contents makes that the div doesn’t generate any box, so its background, border and padding are not rendered. However the inherited properties like color and font have effect on the child (span element) as expected.
Source
It seems that this technically fixes the ref issue, but because of the way display: contents works, all other applied CSS doesn't render.*
As I just discovered, neither of these works, I am looking into other solutions.

Tailwindcss CSS and fonts are not working on production

I am using NextJS and TailwindCSS. For deployment i am using vercel. CSS and fonts are working if I use them directly in index.js file. CSS and fonts are not working if I use different component and import them in index.js file. But they are working fine on localhost. I dont really understand what I am doing wrong here. Here's my code.
// index.js
import Head from 'next/head'
import styles from '../styles/Home.module.css'
import NameList from "../designs/NameList"
export default function Home() {
return (
<>
<NameList />
</>
)
}
// NameList.js
const NameList = () => {
return (
<div>
<div className="border-gray-400 border-2">
<h5 className="max-w-md mb-2 text-3xl font-heading font-extrabold leading-none sm:text-4xl">
<div className="flex">Name</div>
</h5>
</div>
</div>
)
}
export default NameList
If i return NameList divs in Home, everything is working perfectly on both local and production.
Yes, Moving all the necessary files to /components work. Simple tailwind comes with a 5Mb package. In order to minimize the file size it will remove all the unused CSS in the package in build time. And it will keep CSS included in the folders mentioned in tailwind.config.js. That's what happens in your code. You got two options.
You can move files to /components
Create a dedicated folder and include all the necessary files and then include the folder in tailwind.config.js
I moved my NameList.js file into /components folder. And everything is working as expected.

Is there a way to import scss without the need of style?

I have a Gatsby app with scss.
At the moment I have the following :
import React from "react";
import styles from "./mosaic.module.scss";
import Tile from '../tile/tile';
const Mosaic = (): JSX.Element => (
<section className="wrapper style1">
<div className="inner">
<h2 className="major">Smaller Projects</h2>
<p>Here under follow minor projects, often unfinished; I show them anyway because they helped me widen my experience. :)</p>
<section className={`${styles["features"]}`}>
{[0,1,2,3,4,5,6].map(e => <Tile key={e}></Tile>)}
</section>
</div>
</section>
)
export default Mosaic;
If I do not import class from the module like this className={${styles["features"]}} it will not work.
But as you can see some className still work with className="inner"
This is because under gatsby-browser.js I imported some global css like this
import "./src/styles/global.css"
The problem is, it's really confusing to know when a class should be called with styles or in the normal way.
Is there a way to just use the default way for everything ? or opposite ?
If you want regular global CSS, rename your file to mosaic.scss, import the file, and then apply your classNames as usual.
import "./mosaic.scss";
...
<section className='features'>...</section>
When you use the *.module.scss extension, you are actually telling gatsby-plugin-sass that you wish to use CSS Modules.
If you wish to use CSS Modules, then you have to do:
import styles from "./mosaic.css";
...
<section className={styles.features}>...</section>
or
import {features} from "./mosaic.css";
...
<section className={features}>...</section>
Edit: After your clarification in the comments, I don't think gatsby-plugin-sass or CSS Modules do what you want. You might have better luck looking for another tool to handle your css (eg stylable.io)

Use variables to update internal CSS inside an angular component?

I would like to modify quite a large amount of styles on a page through a customisable panel. When a user clicks an option, the content on the page will completely change based on whatever was clicked.
This cannot be a scenario where a class is appended to a parent element and use CSS/LESS to adjust accordingly. For this scenario (for requirement reasons) the CSS needs to be internal on the angular component HTML.
Is it possible to have a value in the component TS like this:
myNewColour: "red"
That can then be used in an internal style sheet that's inside my angular component.html like this?:
<style>
.myContainer { background: myNewColour }
</style>
<!-- HTML Content -->
<div class="myContainer"> Stuff </div>
Any help with this would be appreciated! :)
"Internal in the HTML template" is called inline style ;) Apart from that, you can use ngStyle like so
<tag [ngStyle]="{'background': myNewColour}"></tag>
EDIT if it makes your code too long, what you can do is simply
let customStyle = {
'background': this.myNewColour
};
And in your tag, simply
<tag [ngStyle]="customStyle"></tag>

No CSS applied to reactJs components

In my app.js:
[import React, {PropTypes} from 'react';
import { Navbar, NavbarBrand, Nav, NavItem, NavLink } from 'reactstrap';
const TopHeader = (props) => {
return(
<div>
<Navbar color="faded" light>
<NavbarBrand href="/">reactstrap</NavbarBrand>
<Nav className="pull-xs-right" navbar>
<NavItem>
<NavLink href="/components/">Components</NavLink>
</NavItem>
<NavItem>
<NavLink href="https://github.com/reactstrap/reactstrap">Github</NavLink>
</NavItem>
</Nav>
</Navbar>
</div>
);
}][1]
It renders the elements but without any CSS. I have tried this in firefox and chrom.When I go to inspect element, there aren't any CSS classes. I don't have any custom CSS either. What could be the reason for plain HTML elements getting rendered without any CSS?
Edit:
As suggested, I added :
import 'grommet/scss/vanilla/index';
for gommet components in my js file.
and get this error:
gommet scss file import error snapshot
Edit:
ERROR in ./~/css-loader!./~/sass-loader!./~/grommet/scss/vanilla/index.scss
Module build failed:
#import "inuit-defaults/settings.defaults";
^
File to import not found or unreadable: inuit-defaults/settings.defaults
Parent style sheet: /home/simran/webocity_POS_react/node_modules/grommet/scss/grommet-core/_settings.scss
in /home/simran/webocity_POS_react/node_modules/grommet/scss/grommet-core/_settings.scss (line 2, column 1)
# ./~/grommet/scss/vanilla/index.scss 4:14-102 13:2-17:4 14:20-108
Looking at the source code of Reactstrap, Reactstrap is just a thin layer of abstraction over Bootstrap 4 elements that helps you render markup that conforms to Bootstrap 4 class names and styles. It does not include any CSS by default.
You will have to include Bootstrap 4 CSS on your own either by installing Bootstrap 4's npm package or using their CDN-hosted CSS.
If you are using Webpack for your project, you can refer to my example on the version to install and the importing instructions in this repository: https://github.com/yangshun/react-redux-starter/blob/master/package.json#L46
The library you are using only provides the components themselves, it doesn't import the bootstrap css library for you. You would need to include bootstrap 4 css stylesheet.
If you have an index.html you can just add this in the head of the document.
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css" integrity="sha384-2hfp1SzUoho7/TsGGGDaFdsuuDL0LX2hnUp6VkX3CUQ2K4K+xjboZdsXyp4oUHZj" crossorigin="anonymous">

Resources