React flexbox works with inline styles but not with css file - css

I'm trying to style my react frontend for a project, and want the Form and Display components to be next to each other in a flex container. It works when I do an inline style as below, but has no effect when I use the App.css file. Could somebody explain this to me? Here is the project: https://github.com/GeorgeCGarman/tip-calculator-react
<div className="container" style={{ display: "flex" }}>
<Form />
<Display />
</div>

Your CSS syntax in App.css is incorrect, but you're on the right track.
Instead of:
.selectTip {
display: "flex";
flex-direction: "column";
}
.container {
display: "flex";
}
.Form {
display: "flex";
}
You need to remove the quote marks:
.selectTip {
display: flex;
flex-direction: column;
}
.container {
display: flex;
}
.Form {
display: flex;
}
CSS uses keywords, meaning they do not require quotes, but in React, it must be given as a string (or for things like padding, it may be given as a number)
CSS can be a minefield, so make sure you check out some kind of tutorial

Related

Scss module (css modules): importing from other scss files

I'm currently converting my sass styles to use css modules to avoid style conflicts. My understanding is that it generates unique class names, which makes it hard if I want to target another component (e.g. a child component) defined in a different file.
Say I have a component Button, and it imports from a Button.module.scss file:
// Button.js
import styles from "./Button.module.scss";
export const Button () => <button className={styles.button} />;
// Button.module.scss
.button {
// relevant styles.
}
Now I have another component ButtonGroup. Say I want to make the button in the group have margin between them, I would have something like this:
// ButtonGroup.module.scss
.buttonGroup {
display: flex
&[class~=horizontal] {
& > .button:not(:first-child) { // still using the same class name
margin-left: 1rem;
}
}
&[class~=vertical] {
flex-direction: column;
& > .button:not(:first-child) { // still using the same class name
margin-top: 1rem;
}
}
}
Notice I'm still using the .button to target the individual buttons. But this won't work because the child component doesn't actually have .button as its class name since it's a generated unique class name.
I could use something like [class^=Button] but that feels hacky and hard to maintain once you have a lot of components. (Also realized it wouldn't work in production.)
css-modules is not related to SASS or SCSS and has its own set of supported features and keywords. Yes, they can be used together, which I actually do in most my projects. But I avoid having classname dependencies between different files. I'm aware of some features that could be used to share classnames, but avoiding the need for it is probably the best solution. I will in the following section list all potential solutions to your conundrum I can think of; choose what suits you best:
Solution #1: Never sharing classnames, co-locating styles that belong together and operate on the same classnames.
In your case this would mean that you only have one scss file relating to buttons buttons.modules.scss and both Button.js and ButtonGroup.js import it.
Solution #2: exempt shared classnames from the unique generated name mechanism by marking them as :global. This can be done thus:
// button.module.scss
// this will stay a global classname
:global(.button) {
// the button styles
}
// this will be treated as usual, generating a local name
.icon {
// some icon stuff
}
// buttongroup.module.scss
.buttonGroup {
display: flex;
// will be resolved as local classname
&.horizontal {
flex-direction: row;
// will be resolved as global classname
& > :global(.button):not(:first-child) { margin-left: 1rem; }
}
&.vertical {
flex-direction: column;
& > :global(.button):not(:first-child) { margin-top: 1rem; }
}
}
Solution #3: accept anonymous children. You can omit the classname of the children. no one places non-buttons in a button group (might even enforce it in your component code).
// buttongroup.module.scss
.buttonGroup {
display: flex;
&.horizontal {
flex-direction: row;
& > *:not(:first-child) { margin-left: 1rem; }
}
&.vertical {
flex-direction: column;
& > *:not(:first-child) { margin-top: 1rem; }
}
}
Solution #4: Reference content from another file. There seems to be some support for a syntax that can reference/import stuff from other files, but I perused the documentation and a few github issue discussions 'import className from fileName' 'more' 'and more' without getting any clear answer as to how one would import a local classname from another file. There might be something possible either along those lines see here:
#import button from './button.module.scss';
.buttonGroup {
display: flex;
&.horizontal {
flex-direction: row;
& > .button:not(:first-child) { margin-left: 1rem; }
}
&.vertical {
flex-direction: column;
& > .button:not(:first-child) { margin-top: 1rem; }
}
}
...or along those lines see here:
:import("./button.module.scss") {
imported-button: button;
}
.buttonGroup {
display: flex;
&.horizontal {
flex-direction: row;
& > .imported-button:not(:first-child) { margin-left: 1rem; }
}
&.vertical {
flex-direction: column;
& > .imported-button:not(:first-child) { margin-top: 1rem; }
}
}
Solution #5: Have your container component add a class .button-group-item to each child and use it to apply the margins instead of the .button class.

CSS Shorthand methods for Display Flex and Flex Direction

Is there a short hand method in CSS to combine
display:flex;
flex-direction: row / column?
into one line instead of two?
I know flex-flow, does flex-direction and flex wrap.
I don't know if you are versed in Sass, however if you are, this is a quick way on how to make your idea work, you could also polish this further whith #if statements and #error directives, but here's the quick and easy way:
Here's a Codepen to demonstrate.
The mixin:
#mixin fd($flex, $direction) {
display: $flex;
flex-direction: $direction;
}
This is how you include it:
#include fd([display], [direction]);
.flex-1 {
#include fd(flex, row);
// whatever goes next
}
.flex-2 {
#include fd(inline-flex, column);
// whatever goes next
}
This is what it compiles to:
.flex-1 {
display: flex;
flex-direction: row;
}
.flex-2 {
display: inline-flex;
flex-direction: column;
}

why does css displays in style tag in the head of react rendred html when i inspect

my component :
import React from "react";
import "./homepage.styles.scss";
const Hompage = () => {
return (
<div className="homepage">
.......
</div>
);
};
export default Hompage;
Style file:
.homepage {
display: flex;
flex-direction: column;
align-items: center;
padding: 20px 80px;
}
.directory-menu {
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
when i inspect my code it displays as <style> my css </style> int the head
here is a picture of what displays in chrome devtools:
This is the normal or general or common way that the react /angular apps are bunduled into. Where you get all the css and js put into a single index.html page.
You can't avoid it i assume.
But try with lazy loading components but still i think the css would be appended previously into your page.
The css and js are compiled and appended into a main html file so that the browser doesn't have to make a request and wait until it finishes.
1) This way your page will load fast.
2) A server request would be saved.
3) No blocking css or js.
4) and many more ....
Benefits you get using webpack to do this
Even the css library that you are going to use all are appended into a style tag in your page

Override CSS in React

I am using Wolox's chat widget
https://github.com/Wolox/react-chat-widget
And I am trying to make a horizontal row of multiple chat widgets along the bottom of the screen. I am trying to override the class .rcw-widget-container
.rcw-widget-container {
bottom: 0;
display: -ms-flexbox;
display: flex;
-ms-flex-direction: column;
flex-direction: column;
margin: 0 20px 20px 0;
max-width: 370px;
position: fixed;
right: 0;
z-index: 1;
}
I have two chat Widget's that I want to put side by side, but I want to do it inline with React. Because my number of widgets will grow depending on how many user chats I open. So the right positioning needs to be dynamic. I just don't know how to accomplish this. Or if it's possible
https://codesandbox.io/s/vvnjyr9r30
EDIT
Something like this may work, but I don't think I am getting the syntax right.
.chat1 .rcw-widget-container {
right: 350px;
}
.chat2 .rcw-widget-container {
right: 400px;
}
Component
<Widget className="chat1" handleNewUserMessage={(e) => this.handleNewUserMessage(e, new Date().getTime())} />
<Widget className="chat2" handleNewUserMessage={(e) => this.handleNewUserMessage(e, new Date().getTime())} />
as I can understand probably you are looking for something like this:
In this case you can try:
.App {
font-family: sans-serif;
text-align: center;
display: flex;
flex-direction: row;
}
.rcw-widget-container {
border: 2px red solid;
position: initial;
}
Also, try to reorder the imports in index.js to override the styles.
import "react-chat-widget/lib/styles.css";
import "./styles.css";
While not inherently possible in CSS modules alone, the author of the react-toolbox library has actually solved this particular problem very nicely
Read their github docs which are more in depth on the subject at https://github.com/react-toolbox/react-toolbox#customizing-components
A list of the themeable classes for a particular component is given on the component demo page on their site too

CSS Validator doesn't recognize flex-wrap: wrap;

I am trying to validate a css file at w3c css validator. When it is tested it returns an error stating that "Property flex-wrap- doesn't exist : wrap". This is my part that css validator sees wrong.
.row {
width: 100%;
display: flex;
flex-wrap-: wrap;
}
Any suggestion how to solve this problem?
Thanks
flex-wrap- indeed doesn't exist...but flex-wrap exists. See documentation on Mozilla Developer Network
Replace your CSS with the following :
.row {
width: 100%;
display: flex;
flex-wrap: wrap;
}

Resources