I have a Label element with some text and a Span inside. The text of the label changes on user click (it gets shorter/larger). If i put a margin left in the span then when the text of the label gets shorter/larger the span moves with it. I want the span to be static, no matter if the element sitting besides it gets shorter/larger. For some reason i dont know (i am a bit noob with css) position the span with absolute does the work (if you can explain to me why is that it would be great). It's there a more efficient way of doing that? Should i still be using absolute/relative positioning having Flexbox and CSS Grid? Do not pay attention to the <Wrapper> component. That is just a HOC that returns its children to avoid putting everything inside a <div>.
import React, { useState } from 'react';
import styled from 'styled-components';
import Wrapper from '../HOCs/Wrapper';
const ToggleCheckbox = styled.input`
display: none;
`;
const ToggleLabel = styled.label`
cursor: pointer;
padding: 2rem;
display: inline-block;
font-size: 1.6rem;
`;
const ToggleSpanBackground = styled.span`
background-color: #e3dede;
border-radius: 100px;
display: inline-block;
width: 40px;
height: 10px;
position: absolute;
left: 14rem;
top: 2.5rem;
cursor: pointer;
${ToggleCheckbox}:checked + ${ToggleLabel} & {
background-color: #2b90d9;
}
`;
const ToggleSpanButton = styled.span`
width: 2rem;
height: 2rem;
border-radius: 50px;
display: inline-block;
background-color: #e3dede;
position: absolute;
top: -0.5rem;
left: 0.3rem;
${ToggleCheckbox}:checked + ${ToggleLabel} ${ToggleSpanBackground} & {
background-color: #2b90d9;
left: 1.8rem;
}
`;
export default function Toggle(props) {
let [toggle, setToggle] = useState('off');
return (
<Wrapper>
<ToggleCheckbox type='checkbox' id='toggle-checkbox'></ToggleCheckbox>
<ToggleLabel
htmlFor='toggle-checkbox'
onClick={() =>
setToggle((prevState) => {
if (prevState === 'off') {
return 'on';
} else {
return 'off';
}
})
}
>
option: {toggle}
<ToggleSpanBackground>
<ToggleSpanButton></ToggleSpanButton>
</ToggleSpanBackground>
</ToggleLabel>
</Wrapper>
);
}
Well, position absolute effectively takes the element out of the DOM flow. So the thing getting bigger is not touching it any more so when it gets bigger it does not affect its position.
I would make the span have a fixed width, a width big enough for a long or short value.
Related
I write a CSS for my own main div:
.main {
height: 0%;
position: absolute;
width: 100%;
z-index: 100;
background: whitesmoke;
bottom: 0;
border-radius: 15px;
padding: 20px;
color: gray;
left: 0;
right: 0;
transition: height 1s ease-in;
}
.visible {
height: 96%;
}
When some state changes in my own program I would trigger .visible CSS class.
But it not working.
Check my React section:
import React, { useContext } from "react";
import styles from "../../sass/DownModal.module.scss";
import { ConfigContext } from "../../context/config";
import { EnumPageFrom } from "../../bussiness/Icon";
function Index({ children }: { children: React.ReactNode }) {
const { setActiveMenu, setBackground, activeMenu } =
useContext(ConfigContext);
return (
<div
className={`${styles.main} ${
activeMenu == EnumPageFrom.MenuAdd && styles.visible
}`}
>
{children}
</div>
);
}
export default Index;
Every stuff are working properly except CSS (.visible) class!
Why and How can I fit it?
Edit
.visible {
height: 96%;
}
.hidden {
height: 0%;
}
.main {
position: absolute;
width: 100%;
z-index: 100;
background: whitesmoke;
bottom: 0;
border-radius: 15px;
padding: 20px;
color: gray;
left: 0;
right: 0;
transition: height 4s;
}
<div
className={`${styles.main} ${
activeMenu == EnumPageFrom.MenuAdd ? styles.visible : styles.hidden
}`}
>
{children}
I breaking a snipped into some sections but transition still doesnt work.
There are a few potential issues that could be causing the .visible class not to be applied as expected:
Make sure that the activeMenu variable is being set correctly and
that the value of activeMenu is what you expect it to be when you
want the .visible class to be applied. You can check this by adding
a console log to print out the value of activeMenu at different
points in your code.
Make sure that the styles object in your React component contains
the correct class names for the .main and .visible classes. You can
check this by inspecting the styles object in your debugger or by
adding a console log to print out the object.
Make sure that the .visible class is being defined correctly in your
CSS. Make sure that the height property is set to a value that is
greater than 0, and make sure that the transition property is set
correctly. You can try adding a different property (such as color or
font-size) to the .visible class and see if it is applied as
expected to help narrow down the issue.
I have the following css/styled-components, and I want to be able to (1) have the text resize based on text rendered (currently longer words like "manufacturing" span past the image and get cut off) and (2) If the word is too long, I want the text to wrap within the image. Googling to no avail because it shows "how to wrap text around an image".
** Styled-components **
const ProfilePicContainer = styled.div`
position: relative;
display: inline-block;
text-align: center;
color: #fff;
`
const ProfilePicText = styled.div`
position: absolute;
top: -25%;
left: 40%;
overflow: overflow-wrap;
font-size: clamp(1.15em, 3vw, 1em);
`
const CompanyProfilePic = styled.img.attrs({ src: `${imgBlank}` })`
position: relative;
left: 30px;
top: -30px;
margin-bottom: -10px;
#media (max-width: 767px) {
width: auto;
};
`
** JSX **
export default function Intro({ company, isExpanded, mainWidth }) {
return (
<Wrapper>
<Banner>
<BannerImg background={company.banner} />
<ProfilePicContainer>
<CompanyProfilePic />
<ProfilePicText>{company.name}</ProfilePicText>
</ProfilePicContainer>
</Banner>
</Wrapper>
)
}
Here is my example where I need to put the first component in front of the second.
Currently the second component is in front of the first despite z-index. I tried also to put style on the component tag but it does not work. Where is my mistake ?
First component:
import styled from "styled-components";
const Container = styled.div`
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 500px;
z-index: 100;
`;
function Aaa() {
return (
<Container>asd</Container>
)
}
export default Aaa;
Second component
import styled from "styled-components";
const Container = styled.div`
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 500px;
margin-top: -200px;
background: pink;
z-index: 1;
`;
function Bbb() {
return (
<Container>qwe</Container>
)
}
export default Bbb;
App:
function App() {
return (
<>
<Aaa />
<Bbb />
</>
);
}
export default App;
You need position: relative.
Note: z-index only works on positioned elements (position: absolute, position: relative, position: fixed, or position: sticky) and flex items (elements that are direct children of display:flex elements).
https://www.w3schools.com/cssref/pr_pos_z-index.asp
E.g.
import styled from "styled-components";
const Container = styled.div`
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 500px;
margin-top: -200px;
background: pink;
z-index: 1;
`;
function Bbb() {
return (
<Container>qwe</Container>
)
}
export default Bbb;
I dont know why it not work,this seems no reason.But what ever, maybe you could use this instead:
import styled from "styled-components";
const Container = styled.div`
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 500px;
transform: translateY(0px);
`;
function Aaa() {
return (
<Container>asd</Container>
)
}
export default Aaa;
Try adding a container for the components instead of fragment and apply display: flex and flex-direction: column on that container and see if it works. Edit: Code sandbox with fix: https://codesandbox.io/s/floral-frog-fie10?file=/src/Aaa.js
I am trying to use the blur effect in css to blur the background and z-index to stack the logo on the blurred image but the same is not happening my logo is down under the blurred background.Please let me know the issue.
Styled component heirarchy:
<LandingPageContainer>
<Background />
<LandingPageContentContainer>
<Logo src={piattoLogo} />
<ContentContainer>
<Content>Premium handcrafted delicacies</Content>
<Button>Lets go!</Button>
</ContentContainer>
</LandingPageContentContainer>
</LandingPageContainer>
import styled from 'styled-components';
import landingBackground from '../../../../../img/piatto/CustomerLanding/CustomerLanding.jpg';
export const LandingPageContainer = styled.div`
display: block;
width: 100%;
height: 812px;
background-color: #0d0c0c;
`;
export const Background = styled.div`
width: 390px;
height: 526px;
left: -326px;
top: -80px;
filter: blur(2px);
background: url(${landingBackground}) no-repeat center center/cover;
`;
export const LandingPageContentContainer = styled.div`
display: block;
margin: auto;
padding: auto;
text-align: center;
margin-top: -130px;
z-index: 2;
`;
export const Logo = styled.img`
width: 201px;
height: 164px;
`;
`;
Remember z-index only works on positioned elements (relative, absolute, sticky, fixed).
I am trying to make the transition slowly (500ms) scale the Brandsdiv when props.pop changes. pop will equal true or false. Currently, transform: ${props => (props.pop ? "scale(1.2)" : "scale(1)")}; works fine and scales the div when pop = true but the transition is not working - the scaling abruptly changes.
import React from 'react'
import styled from 'styled-components'
const LogoImg = styled.img`
max-width: 100%;
padding: 5px;
`
export default function FeaturedManufacturerLink(props) {
const {
brandPagePath,
logo,
pop
} = props
const Brandsdiv = styled.div`
transition: transform 500ms;
display: flex;
width: 116px;
height: 85px;
border-radius: 50%;
margin: 25px 35px;
align-items: center;
text-align: center;
transform: ${props => (props.pop ? "scale(1.2)" : "scale(1)")};
`
return (
<Brandsdiv pop={pop}>
<a href={brandPagePath}>
<LogoImg src={logo} />
</a>
</Brandsdiv>
)
}
I moved const Brandsdiv. The prop change pop was causing the component to rerender.