I have nested selectors in my css file. I'm new to React and trying to make it work with my js file. Does anyone have any tips?
I found: https://blog.logrocket.com/the-best-styling-in-react-tutorial-youve-ever-seen-676f1284b945
It seems to be helpful but does not mention how to deal with nested css. For example, I have &:before and &:after, #include signUpActive, among others. This is really some confusing stuff.
.img {
overflow: hidden;
z-index: 2;
position: absolute;
&:before {
content: '';
position: absolute;
transition: transform 1.2s ease-in-out;
}
&:after {
content: '';
position: absolute;
}
#include signUpActive {
&:before {
transform: translate3d(640px,0,0);
}
}
&__text {
z-index: 2;
position: absolute;
transition: transform 1.2s ease-in-out;
&.m--up {
#include signUpActive {
transform: translateX(260px*2);
}
}
&.m--in {
transform: translateX(260px * -2);
#include signUpActive {
transform: translateX(0);
}
}
}
&__btn {
overflow: hidden;
z-index: 2;
position: relative;
&:after {
content: '';
z-index: 2;
position: absolute;
}
&.m--in {
transform: translateY(36px*-2);
#include signUpActive {
transform: translateY(0);
}
}
&.m--up {
#include signUpActive {
transform: translateY(36px*2);
}
}
}
}
}
It is actually not "nested CSS". But it is a SASS/SCSS code. Both SASS and SCSS have similar purposes, with several slight differences. Please check here for more detail: https://www.geeksforgeeks.org/what-is-the-difference-between-scss-and-sass/ . Personally, I would suggest SCSS over SASS by considering it is less strict than SASS.
If you like to use just normal CSS, then just write and import CSS scripts to your react. It will be no problem. You should not follow that "nested CSS" way which is SASS/SCSS ( I would not recommend that actually ).
Let assume you stick with SASS/SCSS. If you are using "CRA" ( create react application ), it is just as simple as import your .scss file to react component like the following:
import React from "react";
import ReactDOM from "react-dom";
import "./styles.scss";
function App() {
return (
<div className="App">
<div className="panel">
<h2>Panel</h2>
<div className="panel__inner">
<h3>Inner panel</h3>
</div>
</div>
</div>
);
}
While the styles.scss is just a normal SCSS code at same directory, like follow:
#import "./scss-mixins/mixins.scss"; //Using relative path to the .scss file
.App {
font-family: sans-serif;
text-align: center;
.panel {
padding: 15px;
background: #f9f9f9;
&__inner {
padding: 10px;
background: green;
}
}
}
Just ensure that you have node-sass in your package. Otherwise you should do npm install node-sass --save. Please read more at official documentation here: https://facebook.github.io/create-react-app/docs/adding-a-sass-stylesheet.
You can check working example at: https://codesandbox.io/s/x2z4ly6y2z
Related
I am trying to render a styled react calendar (see here https://blog.logrocket.com/react-calendar-tutorial-build-customize-calendar/#styling-your-calendar) in Symfony. I am following the tutorial found here: https://symfony.com/bundles/ux-react/current/index.html.
The calendar component itself appears to render fine. See below.
However, there is no css styling present.
Here is the code for the calendar:
// assets/react/controllers/MyComponent.jsx
import React, { useState } from 'react';
import Calendar from 'react-calendar';
import './calendar.css'
export default function () {
const [date, setDate] = useState(new Date());
return (
<div className='app'>
<div className='calendar-container'>
<Calendar
onChange={setDate}
value={date}
locale="en-EN"
/>
</div>
<p className='text-center'>
<span className='bold'>Selected Date:</span>{' '}
{date.toDateString()}
</p>
</div>
);
}
Here is the css code:
.react-calendar {
width: 400px;
max-width: 100%;
background-color: #fff;
color: #222;
border-radius: 8px;
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.2);
font-family: Arial, Helvetica, sans-serif;
line-height: 1.125em;
}
.react-calendar__navigation button {
color: #6f48eb;
min-width: 44px;
background: none;
font-size: 16px;
margin-top: 8px;
}
.react-calendar__navigation button:enabled:hover,
.react-calendar__navigation button:enabled:focus {
background-color: #f8f8fa;
}
.react-calendar__navigation button[disabled] {
background-color: #f0f0f0;
}
abbr[title] {
text-decoration: none;
}
/* .react-calendar__month-view__days__day--weekend {
color: #d10000;
} */
.react-calendar__tile:enabled:hover,
.react-calendar__tile:enabled:focus {
background: #f8f8fa;
color: #6f48eb;
border-radius: 6px;
}
.react-calendar__tile--now {
background: #6f48eb33;
border-radius: 6px;
font-weight: bold;
color: #6f48eb;
}
.react-calendar__tile--now:enabled:hover,
.react-calendar__tile--now:enabled:focus {
background: #6f48eb33;
border-radius: 6px;
font-weight: bold;
color: #6f48eb;
}
.react-calendar__tile--hasActive:enabled:hover,
.react-calendar__tile--hasActive:enabled:focus {
background: #f8f8fa;
}
.react-calendar__tile--active {
background: #6f48eb;
border-radius: 6px;
font-weight: bold;
color: white;
}
.react-calendar__tile--active:enabled:hover,
.react-calendar__tile--active:enabled:focus {
background: #6f48eb;
color: white;
}
.react-calendar--selectRange .react-calendar__tile--hover {
background-color: #f8f8fa;
}
.react-calendar__tile--range {
background: #f8f8fa;
color: #6f48eb;
border-radius: 0;
}
.react-calendar__tile--rangeStart {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
background: #6f48eb;
color: white;
}
.react-calendar__tile--rangeEnd {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
background: #6f48eb;
color: white;
}
Here is a screenshot of the folder/file structure:
Here is my webpack.config.js
const Encore = require('#symfony/webpack-encore');
// Manually configure the runtime environment if not already configured yet by the "encore" command.
// It's useful when you use tools that rely on webpack.config.js file.
if (!Encore.isRuntimeEnvironmentConfigured()) {
Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev');
}
Encore
// directory where compiled assets will be stored
.setOutputPath('public/build/')
// public path used by the web server to access the output path
.setPublicPath('/build')
// only needed for CDN's or subdirectory deploy
//.setManifestKeyPrefix('build/')
/*
* ENTRY CONFIG
*
* Each entry will result in one JavaScript file (e.g. app.js)
* and one CSS file (e.g. app.css) if your JavaScript imports CSS.
*/
.addEntry('app', './assets/app.js')
// enables the Symfony UX Stimulus bridge (used in assets/bootstrap.js)
.enableStimulusBridge('./assets/controllers.json')
// When enabled, Webpack "splits" your files into smaller pieces for greater optimization.
.splitEntryChunks()
// will require an extra script tag for runtime.js
// but, you probably want this, unless you're building a single-page app
.enableSingleRuntimeChunk()
/*
* FEATURE CONFIG
*
* Enable & configure other features below. For a full
* list of features, see:
* https://symfony.com/doc/current/frontend.html#adding-more-features
*/
.cleanupOutputBeforeBuild()
.enableBuildNotifications()
.enableSourceMaps(!Encore.isProduction())
// enables hashed filenames (e.g. app.abc123.css)
// .enableVersioning(Encore.isProduction())
.enableVersioning()
// configure Babel
// .configureBabel((config) => {
// config.presets.push('#babel/preset-react');
// })
// enables and configure #babel/preset-env polyfills
.configureBabelPresetEnv((config) => {
config.useBuiltIns = 'usage';
config.corejs = '3.23';
})
// enables Sass/SCSS support
//.enableSassLoader()
// uncomment if you use TypeScript
//.enableTypeScriptLoader()
// uncomment if you use React
.enableReactPreset()
// uncomment to get integrity="..." attributes on your script & link tags
// requires WebpackEncoreBundle 1.4 or higher
//.enableIntegrityHashes(Encore.isProduction())
// uncomment if you're having problems with a jQuery plugin
//.autoProvidejQuery()
;
module.exports = Encore.getWebpackConfig();
And here is my app.js:
/*
* Welcome to your app's main JavaScript file!
*
* We recommend including the built version of this JavaScript file
* (and its CSS file) in your base layout (base.html.twig).
*/
////////////////////////////////////////
//
// FOR REACT
//
// https://symfony.com/bundles/ux-react/current/index.html
import { registerReactControllerComponents } from '#symfony/ux-react';
// Registers React controller components to allow loading them from Twig
//
// React controller components are components that are meant to be rendered
// from Twig. These component then rely on other components that won't be called
// directly from Twig.
//
// By putting only controller components in `react/controllers`, you ensure that
// internal components won't be automatically included in your JS built file if
// they are not necessary.
registerReactControllerComponents(require.context('./react/controllers', true, /\.(j|t)sx?$/));
//
////////////////////////////////////////
// any CSS you import will output into a single css file (app.css in this case)
import './styles/app.css';
// compile new js file
// import './javascript/method1.js';
// start the Stimulus application
import './bootstrap';
Please let me know if there is anything else I can do to help. When running npm run dev, it does seem to recognize the import './calendar.css' as valid. I am not sure what to do here and haven't found anything similar online yet. Thank you.
I have this .button rule in Cta.module.scss-
.button {
$bg-color: white;
$text-color: variables.$color-text-cta;
background-color: $bg-color;
color: $text-color;
display: inline-block;
padding: variables.$padding-block-sm variables.$padding-inline-sm;
border: 0.056rem solid transparent;
border-radius: 0.278rem;
box-shadow: rgba(0, 0, 0, 0.239) 0 0.111rem 0.556rem;
#include mixins.cta-hover($bg-color, $text-color);
}
I want to override some properties for this .button class in IntroSection/index.module.scss, which I could do pretty easily if I was using styled-components; something like-
import {Button} from 'Cta/Cta.styles.js';
const Section = styled.section`
${Button} {
...
}
`;
I have no idea how (or if) we can achieve such a thing using scss modules. I tried a similar approach in index.module.scss-
#use '../../comps/Cta/Cta.module';
.section {
Cta.button {
padding: variables.$padding-block-md variables.$padding-inline-md !important;
&:first-of-type {
margin-right: variables.$margin-sm;
}
}
But it doesn't seem to work. What's the correct approach to achieve the result I want?
Below is what Cta.jsx contains in it-
import React from 'react';
import styles from './Cta.module.scss';
export default function Cta({ children, backgroundColor }) {
const classForBgColor = styles['button--' + backgroundColor];
return (
<button className={`${styles.button} ${classForBgColor || ''}`}>
{children}
</button>
);
}
I used to use CSS for a React project, but for the implementation of a "dark mode" functionality I decided to move to SASS.
I also use bootstrap so I organize my files according to the documentation.
/* App.scss */
#import "~bootstrap/scss/bootstrap.scss";
#import './styles/_themes';
#import './styles/_fonts';
h1, h2, h3, h4, h5, h6 {
font-family: $font-family-secondary;
#include themed() {
color: t($title-color)
}
}
p {
font-family: $font-family-primary;
#include themed() {
color: t($text-color)
}
}
hr, .nav-tabs {
#include themed() {
border-color: t($text-secondary-color)
}
}
.base {
height: 100%;
width: 100%;
#include themed() {
background-color: t($background-color)
}
}
.main {
width: 750px;
#include themed() {
background-color: t($background-color)
}
}
First, I thought it was a bootstrap problem, but the breakpoints are also being disregarding in my own files.
/* Footer.scss */
#media (max-width: 767px){
#footer h5 {
padding-left: 0;
border-left: transparent;
padding-bottom: 0px;
margin-bottom: 10px;
}
}
I made a minimal reproducible example and posted it to codesandbox: https://codesandbox.io/s/immutable-fire-qu9oe
Please, try to decrease the screen size and check the media breakpoints being disregarded.
What am I doing wrong?
Thank you very much!
EDIT:
Thanks to robertp's answer I could fix my custom media breakpoints.
But how can I fix bootstrap ones?
For example, in my navbar I have a media breakpoint for a bootstrap class:
/* Navbar.scss */
#media (max-width: 571px) {
.collapsing {
#include themed() {
position: absolute !important;
z-index: 3;
width: 100%;
top: 75px;
}
}
.collapse.show {
#include themed() {
display: block;
position: absolute;
z-index: 3;
width: 100%;
top: 75px;
}
}
.navbar.open {
#include themed() {
transform: translate(0, 0)
}
}
.overlay.open {
#include themed() {
height: 100%;
opacity: 1;
}
}
}
But it didn't work. Also, how I could fix all bootstrap grid system classes?
EDIT 2:
The problem was the import order. If I put the bootstrap import at the end of the file everythings works as expected!
It seems to be due to specificity in the theme. Your footer H5 element is styled as per the theme, so you need to override the themed version of it.
Screenshot of the themed styling overriding your mediaquery based styling:
This should work:
#media (max-width: 767px){
#footer h5 {
#include themed() {
padding-left: 0;
border-left: transparent;
padding-bottom: 0px;
margin-bottom: 10px;
}
}
}
I think is just something very simple, but I can't think of anything;
import React, { useState } from "react"
import "./header.scss"
export default function(){
let [curtain, setCurtain] = useState(false);
return (
<div className="header"
onMouseEnter={() => setCurtain(true)}
onMouseLeave={() => setCurtain(false)}
>
{ curtain && <div className="header__curtain__black header__curtain"/> }
</div>
)
}
And here is SCSS
.header{
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 70px;
&__curtain{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: black;
animation: slide_down 0.2s linear;
}
}
#keyframes slide_down {
0%{
transform: translateY(-100%);
}
100%{
transform: translateY(0);
}
}
Code is super simple and task is super simple too, I want to make a reverse on closing but what do I do ?
You can assign different class names to the curtain div according to curtain state value. I would also suggest to use transition property in your css styles instead of keyframe animations.
Here is the edited code.
It looks like that when it is supposed to be a button that you press to open.
I am using react-leaflet with mapzen's leaflet-geocoder.
import { MapControl } from 'react-leaflet'
import L from 'leaflet'
import 'leaflet-geocoder-mapzen'
export default class SearchBox extends MapControl {
componentWillMount() {
const searchBox = L.control.geocoder(<API-KEY>)
this.leafletElement = searchBox
}
}
I added some styling in my CSS that made the search box look somewhat better — that's my fix for now, at least.
.leaflet-touch .leaflet-bar {
background-color: white;
}
.leaflet-pelias-control, .leaflet-pelias-input {
width: 100%;
max-width: 200px;
}
.leaflet-pelias-search-icon {
display: block;
visibility: hidden;
}
.leaflet-pelias-close {
visibility: hidden;
}
.leaflet-pelias-close::after {
content:'Clear search';
visibility: visible;
display: block;
width: 100%;
padding: 5px;
top: 2px;
}
.leaflet-top, .leaflet-left {
width: 200px;
}
For leaflet-control-geocoder, what worked for me, was to add the following to index.css:
#import "~leaflet-control-geocoder/dist/Control.Geocoder.css";
So for leaflet-geocoder-mapzen I'm guessing (untested):
#import "~leaflet-geocoder-mapzen/1.9.4/leaflet-geocoder-mapzen.css";
or similar
FYI
Tilde (~) used in conjunction with webpack means that a lookup is performed against node_modules to resolve the path.
see stackoverflow explanation here