I'm using next.js and react.
I'm using sass for styling.
I want to use the after pseudo-element to make it look like the div tag and image are overlapping. (The image is in front and the pseudo-element is behind.)
However, the image is transparent and I can see the pseudo-elements behind the image.
I don't know why it's transparent when I'm not using opacity.
const Index: FunctionComponent = () => {
return (
<>
<div className="bg-index height-100vh">
<div className="frame">
<span className="absolute z-index-10 top-10 left-10 transform">
<Image
src="/peach.jpg"
alt="peach"
className="background-no-repeat absolute z-index-10"
width={200}
height={200}
/>
</span>
</div>
</div>
</>
);
};
export default Index;
// position
div,
img,
span {
&.absolute {
position: absolute;
}
&.top-200 {
top: 100px;
}
&.right-100 {
right: 160px;
}
&.transform {
transform: rotate(-15deg);
}
}
//
// z-index
div,
img {
&.z-index-10 {
z-index: 10;
}
}
//backgroundColor
div {
&.bg-index {
background-color: #ecd3e8;
}
&.background-no-repeat {
background-repeat: no-repeat;
}
}
// height
div {
&.height-100vh {
height: 100vh;
}
}
div {
&.frame::after {
position: absolute;
display: block;
content: '';
top: 10px;
left: 10px;
width: 200px;
height: 200px;
box-shadow: 0 4px 10px rgba(51, 51, 51, 0.3);
background: rgba(221, 221, 221, 0.25);
background-blend-mode: hard-light;
z-index: 1;
}
}
background-blend-mode: hard-light;
this is used to blend two items together and will make it semi-transparent. Remove it and it will no longer be transparent
https://www.w3schools.com/cssref/pr_background-blend-mode.asp
Related
I am making a form that expands when the user enters any character/key and gets back to its original width when there is no character left, for the plus point, I want to add animation to that expandable form so it gives a smooth look.
Here is the code and I want this action as follows
Not in React but I made an example in Vanilla JS hope it helps. I used CSS variables for changing width and making it smooth.
Instead of removing svg icons completely try scaling it down to 0 or changing it opacity to 0
const btns = Array.from(document.querySelectorAll('.btn'))
const input = document.querySelector('input')
btns.shift() // for leaving first button
input.addEventListener('input', (event) => {
btns.forEach((btn) => {
if (event.target.value.trim().length > 0) {
btn.classList.add('scale-0')
btn.parentElement.classList.add('width-50')
} else {
btn.classList.remove('scale-0')
if (btn.parentElement.classList.contains('width-50')) {
btn.parentElement.classList.remove('width-50')
}
}
})
})
#import 'https://cdn.jsdelivr.net/gh/KunalTanwar/normalize/css/normalize.inter.min.css';
body {
display: grid;
place-items: center;
}
.row {
--column-gap: 1rem; /* 8px */
width: 100%;
display: flex;
max-width: 525px;
column-gap: var(--column-gap);
}
.row input {
flex-grow: 1;
border-radius: 100vmax;
padding: 0.75rem 1.25rem;
border: 1px solid #c1c1c1;
}
.container {
--column-gap: 0.5rem; /* 16px */
--btn-size: 3.125rem; /* 50px */
flex-shrink: 0;
display: inherit;
column-gap: var(--column-gap);
width: calc(var(--column-gap) * 3 + var(--btn-size) * 4);
transition: width 250ms ease;
}
.container.width-50 {
width: var(--btn-size);
}
.container .btn {
width: var(--btn-size);
border-radius: 50%;
aspect-ratio: 1/1;
border: 1px solid #c1c1c1;
transition: transform 250ms ease;
}
.container .btn.scale-0 {
transform: scale(0);
}
<div class="row">
<div class="container">
<button class="btn">1</button>
<button class="btn">2</button>
<button class="btn">3</button>
<button class="btn">4</button>
</div>
<input type="text" />
</div>
I have come into a strange issue that has stopped me for a few hours. I have created a MERN app in which I have a page that I introduce members of a team. I also have a modal for each member triggered by click on member. The problem is that when I create a new member, the modals related to previous members is displayed behind the latter added members. I will attach pictures to more clearly demonstrate what happens.
enter image description here
enter image description here
Here is how I have defined the modal:
const Modal = ({ closeModal, children }) => {
const closeIcon = () => (
<FontAwesome
name='times'
onClick={closeModal}
className='modal-font-awesome'
/>
)
return (
<div id='overlay'>
<div className='content'>
{closeIcon()}
{children}
</div>
</div>
)
}
Here is my scss code for styling the modal:
#overlay {
position: fixed;
display: block;
overflow: hidden;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.content {
margin: 120px auto;
background-color: white;
border-radius: 0.25rem;
width: 70vw;
padding: 2rem;
position: relative;
border-left: 5px solid rgb(37, 153, 124);
}
Do you have any suggestions about what is happening?
Thank you in advance.
this is a typescript-next.js project. I have this Modal component:
interface ModalProps {
onCancelModal: () => void;
onAcceptModal: () => void;
acceptEnabled: boolean;
isLoading?: boolean;
title: string;
}
const Modal: React.FC<ModalProps> = (props) => {
let containerRef = useRef<HTMLDivElement | null>(null);
console.log("container", containerRef);
useEffect(() => {
const rootContainer = document.createElement("div");
const parentElem = document.querySelector("#__next");
parentElem?.insertAdjacentElement("afterend", rootContainer);
if (!containerRef.current) {
containerRef.current = rootContainer;
}
return () => rootContainer.remove();
}, []);
return containerRef.current
? ReactDOM.createPortal(
<div className="modal">
<header className="modal__header">
<h1>{props.title}</h1>
</header>
<div className="modal__content">{props.children}</div>
<div className="modal__actions">
<Button design="danger" mode="flat" onClick={props.onCancelModal}>
Cancel
</Button>
<Button
mode="raised"
onClick={props.onAcceptModal}
disabled={!props.acceptEnabled}
loading={props.isLoading}
>
Accept
</Button>
</div>
</div>,
containerRef.current
)
: null;
};
export default Modal;
I pass a custom error to ErrorHandler component:
const ErrorHandler: React.FC<ErrorHandlerProps> = (props) => (
<Fragment>
{props.error && <Backdrop onClick={props.onHandle} />}
{props.error && (
<Modal
title="An Error Occurred"
onCancelModal={props.onHandle}
onAcceptModal={props.onHandle}
acceptEnabled
>
<p>{props.error}</p>
</Modal>
)}
</Fragment>
);
However, Modal component is successfully mounted on the DOM but nothing displays on the screen.
EDIT
I have backdrop and modal components.
// css for backdrop
.backdrop {
width: 100%;
height: 100vh;
background: rgba(0, 0, 0, 0.75);
z-index: 100;
position: fixed;
left: 0;
top: 0;
transition: opacity 0.3s ease-out;
opacity: 1;
}
// css for Modal
.modal {
position: fixed;
width: 90%;
left: 5%;
top: 20vh;
background: white;
border-radius: 5px;
z-index: 200;// I changed this to 999999 but didnot solve the issue
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
}
.modal__header {
border-bottom: 2px solid #3b0062;
}
.modal__header h1 {
font-size: 1.5rem;
color: #3b0062;
margin: 1rem;
}
.modal__content {
padding: 1rem;
}
.modal__actions {
padding: 1rem;
text-align: right;
}
.modal__actions button {
margin: 0 0.5rem;
}
#media (min-width: 768px) {
.modal {
width: 40rem;
left: calc((100% - 40rem) / 2);
}
}
I found the answer after i refresh my memory. I realized that there is another .modal className on elements-styles tab. It points me to the /node_modules/bootstrap/scss/_modal.scss file which also has modal className and it was overriding my custom className.
.modal {
position: fixed;
top: 0;
left: 0;
z-index: $zindex-modal;
display: none;
width: 100%;
height: 100%;
overflow: hidden;
// Prevent Chrome on Windows from adding a focus outline. For details, see
// https://github.com/twbs/bootstrap/pull/10951.
outline: 0;
// We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a
// gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342
// See also https://github.com/twbs/bootstrap/issues/17695
}
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.
In Weather project, I have toggle button for Day/Night mode. When toggled it should change background color but it fills the entire page above the components which isn't desirable. Is there any appropriate solution?
Below is the reference
DayNightMode.js
const DayNightMode = () => {
return (
<div className="switch-box">
<div className="switch">
<label for="toggle">
<input id="toggle" className="toggle-switch" type="checkbox" />
<div className="sun-moon">
<div className="dots">
</div>
</div>
<div className="background">
<div className="stars1"></div>
<div className="stars2"></div>
</div>
<div className="fill"></div>
</label>
</div>
</div>
);
};
export default DayNightMode;
DayNightMode.css
* {
box-sizing: border-box;
}
.switch-box {
margin-left: 30%;
/* margin-top: -5%; */
}
.container {
/* height: calc(100% - 2.5rem); */
/* background: #f4f4f4; */
/* display: flex; */
/* justify-content: center; */
/* align-items: center;*/
}
.switch {
position: relative;
/* overflow: hidden; */
width: 8.6rem;
/* height: 2rem; */
}
.switch input {
position: absolute;
top: 0;
left: 0;
z-index: 2;
opacity: 0;
}
.switch label {
cursor: pointer;
}
.background {
z-index: 1;
position: absolute;
width: 6.5rem;
height: 1.8rem;
border-radius: 2.5rem;
border: 0.25rem solid #202020;
background: linear-gradient(to right, #484848 0%, #202020 100%);
transition: all 0.3s;
margin-top: -22px;
opacity: 0.8;
}
.fill {
/* background: #484848;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0; */
}
.switch input:checked ~ .fill {
background: #e9f8fd;
}
/* .fill {
position: fixed;
top: 0;
right: 0;
bottom: 2rem;
left: 0;
background: #484848;
transition: 0.75s all ease;
} */
/* .switch input:checked ~ .fill {
background: #E9F8FD;
} */
/* Stars */
.stars1,
.stars2 {
position: absolute;
height: 0.3rem;
width: 0.3rem;
background: #ffffff;
border-radius: 50%;
transition: 0.3s all ease;
}
.stars1 {
top: 2px;
right: 20px;
}
.stars2 {
top: 20px;
right: 35px;
}
.stars1:after,
.stars1:before,
.stars2:after,
.stars2:before {
position: absolute;
content: "";
display: block;
height: 0.25rem;
width: 0.25rem;
background: #ffffff;
border-radius: 50%;
transition: 0.2s all ease;
}
.stars1:after {
top: 2px;
right: 20px;
}
.stars1:before {
top: 12px;
right: -12px;
}
.stars2:after {
top: -20px;
right: -20px;
}
.stars2:before {
top: -24px;
right: -30px;
}
.sun-moon {
z-index: 2;
position: absolute;
left: 0;
display: inline-block;
height: 1.5rem;
width: 1.5rem;
margin: 0.12rem;
background: #fffdf2;
border-radius: 50%;
transition: all 0.5s ease;
margin-top: -20.5px;
/* Default to Moon */
border: 0.2rem solid #dee2c6;
}
.sun-moon .dots {
position: absolute;
top: 0.5px;
left: 42px;
height: 0.2rem;
width: 0.2rem;
background: #efeedb;
border: 0.25rem solid #dee2c6;
border-radius: 50%;
transition: 0.4s all ease;
}
.sun-moon .dots:after,
.sun-moon .dots:before {
position: absolute;
content: "";
display: block;
height: 0.25rem;
width: 0.25rem;
background: #efeedb;
border: 0.25rem solid #dee2c6;
border-radius: 50%;
transition: 0.4s all ease;
}
.sun-moon .dots:after {
top: -8px;
left: -26px;
}
.sun-moon .dots:before {
top: 10px;
left: -10px;
}
/* Transition to Sun */
.switch input:checked ~ .sun-moon {
left: calc(100% - 4rem);
background: #f5ec59;
border-color: #e7c65c;
transform: rotate(-25deg);
}
.switch input:checked ~ .sun-moon .dots,
.switch input:checked ~ .sun-moon .dots:after,
.switch input:checked ~ .sun-moon .dots:before {
background: #ffffff;
border-color: #ffffff;
}
.switch input:checked ~ .sun-moon .dots {
height: 1.2rem;
width: 1.2rem;
top: -10px;
left: -20px;
transform: rotate(25deg);
}
.switch input:checked ~ .sun-moon .dots:after {
height: 0.65rem;
width: 0.65rem;
top: 2px;
left: -12px;
}
.switch input:checked ~ .sun-moon .dots:before {
height: 0.4rem;
width: 0.4rem;
top: 6px;
left: 14px;
}
.switch input:checked ~ .background .stars1,
.switch input:checked ~ .background .stars2 {
opacity: 0;
transform: translateY(2rem);
}
.switch input:checked ~ .background {
border: 0.25rem solid #78c1d5;
background: linear-gradient(to right, #78c1d5 0%, #bbe7f5 100%);
}
Form.js (DayNight Toggle button defined here)
import React from 'react'
import { ArrowTooltip } from './ArrowTooltip'
import gps from '../images/gps.png'
import 'react-toastify/dist/ReactToastify.css';
import Autosuggest from 'react-autosuggest';
import { highlight } from './Helper'
import cities from 'cities.json';
import Button from 'react-bootstrap/Button'
import './Form.css';
import { MDBContainer,
MDBRow,
MDBCol,
MDBCard,
MDBCardBody,
MDBCardHeader,
MDBBtn} from 'mdbreact'
import DayNightMode from './DayNightMode';
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
value: '',
suggestions: [],
newsValue: '',
weatherValue: ''
};
}
onChange = (event, { newValue}) => {
this.setState({
value: newValue,
});
};
render(){
return (
<div>
<MDBContainer style={{height: '480px', marginTop: '25px'}}>
<MDBRow>
<MDBCol>
<MDBCard style={sectionStyle}></MDBCard>
<MDBCard style={{zIndex:'1', background: 'none'}}>
<MDBCardBody>
{/* Here Toggle button is defined */}
<DayNightMode/>
<form>
<div width="100%">
<ArrowTooltip title="Track Location" placement="top">
<span style={{width:'10%', display:'inline-block', cursor:'pointer'}}
onClick={this.props.fetchWeather}>
<img src={gps} width="25px" height="25px" />
</span>
</ArrowTooltip>
</div>
<br/>
<div className="text-center mt-4">
<Button variant="info"
className="mb-3 btn-block"
type="submit"
value={inputProps.value}
onClick={e => this.onClick(e)}
style={{background: '#e0f7fa', opacity:'0.6',
borderRadius: '10px',fontFamily: 'Josefin Sans',
boxShadow: '0 8px 6px -6px black'}}
>Search Weather</Button>
</div>
</form>
</MDBCardBody>
</MDBCard>
</MDBCol>
</MDBRow>
</MDBContainer>
</div>
)
}
}
export default Form;
App.js (Parent File)
import React from "react";
import "./App.css";
import Form from "./components/Form";
import { ToastContainer, toast, Bounce } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import WeatherAndNews from "./components/WeatherAndNews";
import moment from "moment-timezone";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
newsValue: "",
weatherValue: ""
};
}
handleNews = async (data) => {
this.setState({
newsValue: data
});
};
handleWeather = async (data) => {
this.setState({
weatherValue: data
});
};
render() {
return (
<React.Fragment>
<div className="main-container">
<div className="form-container">
<Form
newsValue={this.state.newsValue}
weatherValue={this.state.weatherValue}
/>
<ToastContainer transition={Bounce} className="toast-background" />
</div>
<div className="body-container">
<WeatherAndNews />
</div>
</div>
</React.Fragment>
);
}
}
export default App;
My intention is that background color of the page should be changed on toggle
Following is the Codesandbox link https://codesandbox.io/s/2huux
Steps you need to do to achieve this:
Create a variable named 'isDayMode' in App.js component
Create a function with the name 'handleDayNightToggle' in App.js which can update that value to true or false on the basis of the checkbox selected
Pass the reference of the function as props to the Form component
Again pass the reference of function 'handleDayNightToggle' from Form to DayNightMode component
There create an onClick function for the checkbox and make it call the 'handleDayNightToggle' passed as props. So any time the checkbox is clicked this function calls the 'handleDayNightToggle' of the App component.
Finally use the flag 'isDayMode' in App component to understand whether the day is selected or night and accordingly change the classes to update background color.
Updated your project with the above steps, take a look into it - https://codesandbox.io/s/async-cache-r1poy