Using CSS attr() with styled components in react Hooks - css

I am trying to use attribute of SkillPer component pers={80} in css content attr function like so:
content: attr(pers) "%";
But content: attr() cannot get the attributes of <SkillPer pers={80}></SkillPer>
Am I missing something there? please help!
<SkillBar className="skill-bar">
<SkillPer
className="skill-per"
pers={80}
style={{ maxWidth: "80%" }}
></SkillPer>
</SkillBar>
export const SkillPer = styled.div`
height: 12px;
border-radius: 8px;
background-color: var(--color-green);
animation: ${fillBars} 2.5s 1;
position: relative;
&::before {
content: attr(pers) "%"; // here
position: absolute;
padding: 4px 6px;
background-color: #333;
color: var(--color-white);
font-size: 15px;
right: 0;
transform: translateX(200%);
}
`;

pers is a prop, so you can access the props in the style body. I believe this should work for you.
export const SkillPer = styled.div`
height: 12px;
border-radius: 8px;
background-color: var(--color-green);
animation: ${fillBars} 2.5s 1;
position: relative;
&::before {
content: ${({ pers }) => `"${pers} %"`};
position: absolute;
padding: 4px 6px;
background-color: #333;
color: var(--color-white);
font-size: 15px;
right: 0;
transform: translateX(200%);
}
`;

Related

How to positioning tooltip always above the children

I am making tooltip with antd library. I wanted to change the basic styles, so I needed to override styles. Here is the code:
import * as Styled from './Tooltip.styles';
type Props = {
title: string;
children: React.ReactNode;
};
export const CustomTooltip = ({ title, children }: Props) => (
<Styled.Tooltip
visible
title={title}
getPopupContainer={(triggerNode) => triggerNode}>
{children}
</Styled.Tooltip>
);
import styled from 'styled-components';
import { Tooltip as TooltipAnt } from 'antd';
export const Tooltip = styled(TooltipAnt)`
.ant-tooltip-content {
position: relative;
overflow-x: hidden;
overflow-y: visible;
padding-bottom: 20px;
display: inline-block;
left: -35px;
top: 25px;
}
.ant-tooltip-arrow {
display: none;
}
.ant-tooltip-inner {
padding: 10px 15px;
background: white;
display: inline-block;
border-radius: 10px;
border: 3px solid #D04A02;
border-bottom-right-radius: 0;
z-index: 2;
max-width: 200px;
color: #000;
box-shadow: none;
}
.ant-tooltip-content:before {
content: '';
position: absolute;
width: 25px;
height: 25px;
background: white;
bottom: 14px;
right: -8px;
transform: rotate(25deg);
border-bottom: 3px solid #D04A02;
}
.ant-tooltip-content:after {
content: '';
width: 3px;
background: #D04A02;
height: 50%;
position: absolute;
right: -0.5px;
bottom: 12px;
}
`;
And component where I would like to call this Tooltip:
import { CustomTooltip } from 'components/Tooltip/Tooltip';
export const SomeComponent = () => {
return (
<div>
<CustomTooltip title="Home">
<p>Home</p>
</CustomTooltip>
</div>
);
};
The problem is, the tooltip is not above the children. How can I fix this?
Codesanbox: https://codesandbox.io/s/stupefied-cohen-sgxr3s?file=/src/App.tsx

How to make close effect after clicking on close in Styled-components?

I'm trying to make an in and out animation for my comment -
import {
Popup,
Overlay,
NavBarPopupHeader,
NavBarPopupContainer,
NavBarPopupImg,
NavBarPopupClose,
NavBarPopupContent,
NavBarPopupTitle,
NavBarPopupInfo,
NavBarPopupContentImg,
NavBarPopupFooter,
NavBarPopupSignOut,
} from "./styled.js";
function NavBarPopup(props) {
const { isPopupOpen } = props;
return (
<Overlay>
<Popup active={false}>
<NavBarPopupHeader>
<NavBarPopupClose
src="./popup_close.svg"
alt="close"
onClick={() => isPopupOpen(false)}
active={true}
/>
<NavBarPopupContainer>
<NavBarPopupImg />
</NavBarPopupContainer>
</NavBarPopupHeader>
<NavBarPopupContent>
<NavBarPopupTitle>You are logged as</NavBarPopupTitle>
<NavBarPopupInfo>'UserName'</NavBarPopupInfo>
<NavBarPopupInfo>'Email'</NavBarPopupInfo>
<NavBarPopupContentImg src="./popup_img.png" />
</NavBarPopupContent>
<NavBarPopupFooter>
<NavBarPopupSignOut>Sign Out...</NavBarPopupSignOut>
</NavBarPopupFooter>
</Popup>
</Overlay>
);
}
export default NavBarPopup;
I am using styled-components :
import styled, { keyframes, css } from "styled-components";
import { fadeIn, bounceInRight, bounceInLeft } from 'react-animations';
const fader = keyframes`${fadeIn}`;
const bounceIn = keyframes`${bounceInRight}`;
const bounceOut = keyframes`${bounceInLeft}`;
const Popup = styled.div`
position: fixed;
top: 0;
right: 0;
height: 100vh;
width: 400px;
background-color: #ffffff;
transition: ${(active) =>
active
? css`
${bounceIn} 0.5s linear
`
: css`${bounceOut} 0.5s`};
`;
const Overlay = styled.div`
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background-color: rgba(0, 0, 0, 0.8);
animation: 0.2s ${fader};
`;
const NavBarPopupHeader = styled.div`
width: 100%;
height: 15%;
background-color: #000000;
`;
const NavBarPopupContainer = styled.p`
text-align: center;
margin: 0;
padding: 30px 0 0 0;
`;
const NavBarPopupImg = styled.img`
width: 80px;
height: 80px;
border-radius: 50px;
border: none;
background-color: white;
color: black;
font-size: 25px;
`;
const NavBarPopupClose = styled.img`
position: absolute;
top: 5px;
left: 5px;
cursor: pointer;
`;
const NavBarPopupContent = styled.div`
height: 75%;
`;
const NavBarPopupTitle = styled.h3`
margin:0;
padding: 10px 0 10px 0;
text-align: center;
font-size: 30px;
`
const NavBarPopupInfo = styled.h4`
width: 80%;
margin: 10px auto;
padding:5px;
text-align: center;
font-size: 25px;
background-color: black;
color:white;
border-radius: 15px;
`
const NavBarPopupContentImg = styled.img`
width:100%;
margin-top:90px;
`
const NavBarPopupFooter = styled.div`
width: 100%;
height: 10%;
background-color: #000000;
`;
const NavBarPopupSignOut = styled.p`
width:200px;
text-align: center;
margin: 0 auto;
padding: 15px 0 0 0;
font-weight: 700;
font-size: 32px;
color: white;
text-decoration: underline;
cursor: pointer;
`;
export {
Popup,
Overlay,
NavBarPopupHeader,
NavBarPopupContainer,
NavBarPopupImg,
NavBarPopupClose,
NavBarPopupContent,
NavBarPopupTitle,
NavBarPopupInfo,
NavBarPopupContentImg,
NavBarPopupFooter,
NavBarPopupSignOut
};
I want my popup to be animated with $bounceIn when it appears, and disappear with $bounceOut when it closes. I tried to do it by passing an attribute to styled-components but now it only works when my Popup appears. Perhaps I chose the wrong approach, in which case please guide me in the right direction.

How can I use CSS Pseudo-elements styling inside React JSX to pass variables?

The following code is for adding a badge to a card.
CSS Working code:
.card::before {
position: absolute;
content: "";
background: #283593;
height: 18px;
width: 18px;
top: 2.5rem;
right: -0.7rem;
z-index: -1;
transform: rotate(45deg);
}
.card::after {
position: absolute;
content: "Sample Name";
top: 11px;
right: -14px;
padding: 0.5rem;
width: 11rem;
background: #3949ab;
color: white;
text-align: center;
box-shadow: 4px 4px 15px rgba(26, 35, 126, 0.2);
}
I want to pass variables in the form of JSX inside the CSS styling like below:
<div
className="card"
styleBefore={{
position: "absolute",
content: "",
background: "#283593",
height: "18px",
width: "18px",
top: "2.5rem",
right: "-0.7rem",
zIndex: "-1",
transform: "rotate(45deg)",
}}
styleAfter={{
position: "absolute",
content: `- ${this.props.name}`,
top: "11px",
right: "-14px",
padding: "0.5rem",
width: `${this.props.name.length}rem`,
background: "#3949ab",
color: "white",
textAlign: "center",
boxShadow: "4px 4px 15px rgba(26, 35, 126, 0.2)",
}}
>
Instead of "styleBefore" and "styleAfter" (Invalid fields) that I used above, how can I replicate ".card::before" and ".card::after" of css in JSX?
you can use styled components or makeStyles from mui/styles
You can use from styled-components:
import React from 'react';
import styled from 'styled-components';
const Div = styled.div`
&::before{
position: absolute;
content: "";
background: #283593;
height: 18px;
width: 18px;
top: 2.5rem;
right: -0.7rem;
z-index: -1;
transform: rotate(45deg);
}
&::after{
position: absolute;
content: ${props => props.name};
top: 11px;
right: -14px;
padding: 0.5rem;
width: 11rem;
background: #3949ab;
color: white;
text-align: center;
box-shadow: 4px 4px 15px rgba(26, 35, 126, 0.2);
}
`;
class App extends React.Component {
.
.
.
render(){
return(
<Div name=""></Div>
);
}
}
Of course, You must install the requirements:
yarn add styled-components
More information about styled-components
Tell me, if this helped you:)

React js styled component input animation not working

I am trying to create an form with input fields.I am trying to set up the floating labels for the inputs. The floating label works for the second field and not the first field. Please help me understand what am I missing on..
Here is code sandbox link :Please refer to productDetails component..
https://codesandbox.io/s/pensive-water-pojf8?file=/src/StyledComponents/FormInputStyles/index.js:199-1554
Form components
<InputWrapper>
<TextBox />
<LabelText>Product Name</LabelText>
</InputWrapper>
<InputWrapper>
<TextParagraph />
<LabelText1 for="description">Product Name</LabelText1>
</InputWrapper>
styled components: Where I am trying to make the input label floating
export const TextBox = styled.input`
display: flex;
width: 100%;
height: 2em;
border-radius: 5px;
border: none;
background: ${styles.backgroundGradient};
margin-top: ${props => props.marginTop || "1.5em"};
&:focus {
outline: none;
border: 2px solid #6e5dcc;
}
`;
export const LabelText = styled.label`
position: absolute;
top: 1.5em;
left: 0;
font-size: 18px;
line-height: 16px;
pointer-events: none;
transition: 0.5s;
color: ${styles.formContentColor};
${TextBox}:focus ~ &,
${TextBox}:not([value=""]) ~ & {
top: 0;
left: 0;
color: ${styles.formContentColor};
font-size: 16px;
}
`;
export const TextParagraph = styled.input`
display: flex;
width: 100%;
height: 7em;
border-radius: 5px;
border: none;
text-align: left;
appearance: none;
background: ${styles.backgroundGradient};
margin-top: ${props => props.marginTop || "1.5em"};
&:focus {
outline: none;
border: 2px solid #6e5dcc;
}
`;
export const LabelText1 = styled.label`
position: absolute;
top: 1.5em;
left: 0;
font-size: 18px;
line-height: 16px;
pointer-events: none;
transition: 0.5s;
color: ${styles.formContentColor};
${TextParagraph}:focus ~ &,
${TextParagraph}:not([value=""]) ~ & {
top: 0;
left: 0;
color: ${styles.formContentColor};
font-size: 16px;
}
`;

Transition doesn't work after animation forwards

Hie!
Transition doesn't work after animation with animation-fill-mode: forwards;
First animation fires and ends on hover, but then after unhovering transition doesn't apply.
Codepen here
It reproduces in chrome and safari. In firefox works fine.
pug:
button Button
scss:
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
button {
padding: 5px 0;
position: relative;
border: none;
border-radius: 0;
background: transparent;
outline: none;
cursor: pointer;
font-weight: 700;
text-transform: uppercase;
&:before {
content: '';
position: absolute;
bottom: 0;
left: 100%;
right: 0;
height: 4px;
border-radius: 2px;
background: blue;
transition: all .25s;
}
&:hover {
&:before {
animation: nav-link-hover .25s forwards;
}
}
}
#keyframes nav-link-hover {
0% {
left: 0;
right: 100%;
}
100% {
left: 0;
right: 0;
}
}
UPDATE
I've found workaround but will wait for any answer and gladly accept it if it will be better or for example successfully uses broken keyframes.
Still don't know what's wrong with keyframes in chrome/safari, but have found simple workaround.
Now first 'before'-element is on right with no width right: 0; width: 0;.On hover it moves to left with 100% width, that begins to transitionally grow: left: 0; right: auto; width: 100%;.
Finally, when hover was lost, 'before' starts to decreasing, resting on the right end again.
New code:
button {
padding: 5px 0;
position: relative;
border: none;
border-radius: 0;
background: transparent;
outline: none;
cursor: pointer;
font-weight: 700;
text-transform: uppercase;
&:before {
content: '';
position: absolute;
bottom: 0;
right: 0;
width: 0;
height: 4px;
border-radius: 2px;
background: blue;
transition: all .25s;
}
&:hover {
&:before {
left: 0;
right: auto;
width: 100%;
}
}
}
Codepen
Animating elements require a defined state before the animation begins. If you define a state on a trigger (ie. hover), some unexpected behaviour may occur. Therefore, you should set your starting point before the hover.
In this case, simply move left: 0; from the hover to the "non-hover" properties of &:before
button {
padding: 5px 0;
position: relative;
border: none;
border-radius: 0;
background: transparent;
outline: none;
cursor: pointer;
font-weight: 700;
text-transform: uppercase;
&:before {
content: '';
position: absolute;
left: 0;
bottom: 0;
right: 0;
width: 0;
height: 4px;
border-radius: 2px;
background: blue;
transition: all .25s;
}
&:hover {
&:before {
right: auto;
width: 100%;
}
}
}

Resources