Placing a div below another div using Flexbox - css

I have markup like so:
HTML:
<ListElementRoot>
<ListElementText>
{children}
</ListElementText>
<ListElementDescription>
{description}
</ListElementDescription>
</ListElementRoot>
//platform.web.js
export const ListElementRoot = div(style.root)
export const ListElementIcon = div(style.icon)
export const ListElementText = div(style.text)
export const ListElementDescription = div(style.description)
//CSS
.root {
display: flex;
width: 100%;
height: 56px;
align-items: center;
border-top: 1px solid var(--color-gray2);
padding: 0;
}
.icon {
position: absolute;
width: 28px;
height: 28px;
align-items: center;
padding-left: 18px;
}
.text {
color: #000;
font-size: calc(var(--font-size-body) / 10)rem;
padding-left: 64px;
}
.description {
color: #000;
font-size: calc(var(--font-size-body) / 12.3)rem;
padding-left: 64px;
}
I'm new to flexbox.
How can I make element just under ?
I'm trying to find a solution but it is heavily twisted in flexbox for me (for now). Any ideas?
EDIT:
Without flex-direction: column;
With flex-direction: column;

You need to have a flex-direction property set to column for your flex container (.root).
Here you can find a jsfiddle example.
EDIT:
Change align-items: center to be align-items: flex-start in order to have the elements align to the left

Related

CSS Issue on React project

I'm starting to play with CSS and I'm struggling to center my "tasks". To debug I used a colored border and it's centered, but the elements aren't.
.App {
display: block;
text-align: center;
align-items: center;
}
.done {
color: red;
}
.task {
text-align: center;
align-items: center;
display: flex;
margin: auto;
width: 50%;
border: 3px solid green;
padding: 10px;
}
Here is where the CSS is targetting:
import React, { Component } from "react";
class Task extends Component {
render() {
return (
<div className={`task ${this.getClass()}`}>
<div>{this.props.task.text}</div>
<button className="task-element" onClick={() => this.props.onDone(this.props.task.id)}>
<span className="material-symbols-outlined">check_box</span>
</button>
<button className="task-element" onClick={() => this.props.onDelete(this.props.task.id)}>
<span className="material-symbols-outlined">
delete
</span>
</button>
</div>
);
}
getClass() {
return this.props.task.isDone ? 'done' : 'notDone';
}
}
export default Task;
Here is the Output
Tryed to center elements and can't.
You need to use the justify-content property to center the elements inside the flexbox
Try this
.task {
align-items: center;
justify-content: center;
display: flex;
margin: auto;
width: 50%;
border: 3px solid green;
padding: 10px;
}
You would need to justifyContent to centen, as your flex main axis is horizontal, and you want to center the element horizontally. Justify content manage content along main Axis, Here you can give a CSS a try, and let me know whether it works
.task {
text-align: center;
align-items: center;
justify-content: center; /*This will align the content to center in horizontal direction which is main axis if flex direction is row*/
display: flex;
margin: auto;
width: 50%;
border: 3px solid green;
padding: 10px;
}
If you can provide whole code in a codesandbox, I can help more on that
Following are good articles on Flex box
An Interguide to Flex box by Josh W Comeau
Css Trick article on Flex box

Input container width same as input content

I have an input container here:
const InputContainer = styled(BaseInputContainer)`
display: inline-block;
width: 100%;
align-items: center;
input[type="number"] {
background: black;
width: 100%;
text-align: center;
}
`;
I want the width of the container to be the same size of the input field, basically
width: fit-content
but that does not work in the InputContainer component. How do I do this?

aligning text and buttons in flex div CSS

I am trying to align Text on the left and button controls on right in display: flex div.
<CustomFieldContainer>
<StyledWellContainer>
<FieldDetails key={id}>
<H4 bold>{label}</H4>
<StyledBody>({capitalizeFirst(type)}) {required && <StyledSpan>REQUIRED</StyledSpan>} </StyledBody>
</FieldDetails>
<DeleteAction {...props} />
</StyledWellContainer>
</CustomFieldContainer>
this to what I got so far.
below is the CSS for all the above reactjs elements.
const CustomFieldContainer = styled.div`
display: flex;
flex-direction: row;
`;
const FieldDetails = styled.div`
display: flex;
flex-direction: column;
border: none;
`;
const DeleteButton = styled(Button)`
flex-basis:33.33%;
margin-right: 0;
margin-left:auto;
display:block;
`;
this makes
what I am trying to achieve is very simple, as below
any help would be tremendous, the basic idea is to main a container to have texts on the left and controls on the right. thank you.
Update:
const StyledWellContainer = styled(WellContainer)`
margin-right: 1rem;
width: 100%;
padding-bottom: 2px;
padding-top: 0;
`;
import styled from 'styled-components';
const WellContainer = styled.div`
display: flex;
flex-direction: column;
padding: 1rem;
border: ${({ theme, borderType }) => (borderType === 'attention' ? theme.color.border.negative : theme.color.border.light)};
border-radius: 12px;
& > * {
padding-bottom: 1rem;
margin-bottom: 1rem;
border-bottom: ${({ theme, disableDivider }) => (disableDivider ? 'none' : theme.color.border.light)};
}
& > :last-child {
padding-bottom: 0;
margin-bottom: 0;
border-bottom: none;
}
`;
export default WellContainer;
Update after changes, advised by adam.
Your StyledWellContainer styles need changing such that:
flex: 1 0;
display: flex;
flex-direction: row;
align-items: flex-start;
Currently it is a column, which is why the button appears below rather than by the side.
By adding row, this fixes that. flex: 1 0 tells it to stretch to fit the parent, and align-items: flex-start; will prevent the content of the button being stretched to height.
You also need to let the button be its base size and not tell it to grow:
const DeleteButton = styled(Button)`
flex: 0 0 auto;
margin-right: 0;
margin-left: auto;
`;
StyledWellContainer needs to be the flex container, not CustomFieldContainer
const StyledWellContainer = styled.div`
align-items: center;
display: flex;
flex-direction: row;
`;
const FieldDetails = styled.div`
display: flex;
flex: 2;
flex-direction: column;
height: 100%;
border: none;
`;
const DeleteButton = styled(Button)`
flex: 1;
margin-right: 0;
margin-left:auto;
display:block;
`;

Unable to target nth child of styled component

I'm trying to target 3 children divs of a styled component, and I can't figure out what I'm doing wrong with my syntax, and the styled component docs don't seem to cover this well. My code is:
const HamburgerButton = styled.div`
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
min-height: 60%;
min-width: 50px;
border-radius: 8px;
&:nth-child(1){
width: 32px;
min-height: 3px;
background-color: red;
}
&:nth-child(2){
width: 32px;
min-height: 3px;
background-color: red;
}
&:nth-child(3){
width: 32px;
min-height: 3px;
background-color: red;
}
`
const MobileNav = () => {
const [open, setOpen] = useState(false)
return (
<MobileNavContainer>
<Name>
<h1>Josh Bangle</h1>
</Name>
<HamburgerButton>
<span />
<span />
<span />
</HamburgerButton>
</MobileNavContainer>
);
}
the nth-child(2) selector seems to style the HamburgerButton component itself for some reason, so I can only imagine it's a syntax issue, although googling has done nothing to help me out with it.
https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child
nth-child styles the element based on it's position within the group (this has confused me a million times over the years). HamburgerButton being the 2nd element within MobleNavContainer, it got styled. You want to add that class to the spans.
const HamburgerButton = styled.div`
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
min-height: 60%;
min-width: 50px;
border-radius: 8px;
& span:nth-child(1){
width: 32px;
min-height: 3px;
background-color: red;
}
& span:nth-child(2){
width: 32px;
min-height: 3px;
background-color: red;
}
& span:nth-child(3){
width: 32px;
min-height: 3px;
background-color: red;
}
`
Putting a space between the & and the : tells the code to look out for child components. with the way you've written it above it is telling the code to look for the nth HamburgerButton. you can also write the code I have above without the span if you want to reference any nth child element
& :nth-child(2){
color: red;
}
Example:
margin-right: 1rem;
:nth-child(*what ever number*) {
margin-right: 0;
}
to target every other child you can also replace what ever number with odd or even

How to align items above and below each other within one flexbox?

I'm currently trying to align the number 238,741 and the letter N in Number. Currently I have a padding between the Prize Pool div and the Number Active div. They're all contained within a parent with display set to flex and flex-direction: column. They're then within another parent container with display flex and direction set to row. I tried setting different paddings between the divs but when I zoom in or out they don't maintain their position.
I cannot figure out how to make them align and stay aligned when zooming in and out or going into mobile view. I've spent 7 hours on it and made little progress by going through CSS tricks.
Code:
<Wrapper>
<HeaderWrapper row alignItems="center">
<PrizeText variant={TextVariant.subhead}>Prize Pool</PrizeText>
<Text color={TextColor.primary} fontWeight="600" variant={TextVariant.subhead}>Number Active</Text>
<GoldText style={{'padding-right': '26%'}} variant={TextVariant.display}>$7,162,245</GoldText>
<GoldText color={TextColor.primary} variant={TextVariant.display}>238,741</GoldText>
</HeaderWrapper>
</Wrapper>
const HeaderWrapper = styled(Box)`
height: auto;
align-items: flex-start;
/* border: 2px solid white; */
flex-wrap: wrap;
margin-top: 45px;
margin-left: 32px;
`;
const MoneyWrapper = styled(Box)`
height: auto;
align-items: flex-start;
/* border: 2px solid white; */
flex-wrap: wrap;
margin-left: 32px;
`;
const GoldText = styled(Text)`
background-image: linear-gradient(98.84deg, #C9882B 0%, #E7CA66 47.71%, #C69935 100%);
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
white-space: nowrap;
`;
const PrizeText = styled(Text)`
padding-right: 152px;
color: ${props => props.theme.palette.text.primary};
font-weight: 600;
white-space: nowrap;
`;
const Wrapper = styled(Box)`
position: relative;
border: 2px solid white;
width: 100%;
/* justify-content: center; */
align-items: center;
`;
A Box is just a div, with display set to flex and can take the prop col or row to change the flex direction.
It might help to rethink the structure of your components. If you wrap <PrizeText> and <GoldText> in a container and <Text> and <GoldText> in another container then things will fall into place for you.
Kind of like this:
.wrapper {
display: flex;
justify-content: space-around;
padding: 1rem;
}
.missing-wrapper {
width: 50%;
}
h1, h5, div {
border: 1px solid red;
}
<div class="wrapper">
<div class="missing-wrapper">
<h5>Prize Pool</h5>
<h1>$7,162,245</h1>
</div>
<div class="missing-wrapper">
<h5>Number Active</h5>
<h1>238,741</h1>
</div>
</div>

Resources