Unable to target nth child of styled component - css

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

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

CSS: Combining static html class with dynamic class that uses attribute selector

Html :
<div class="main main-280">
"main-280" is dynamically generated and may change so css for that selector alone would be:
div[class^="main-"]{-------}
But how do I target both classes as in .main.main-280 using an attribute selector? It seems like this wouldn't work:
.main.div[class^="main-"]{-------}
Not sure I know what you exactly mean, but:
const main = document.querySelector('.main');
document.querySelector('button').addEventListener('click', () => main.classList.toggle('main-280'));
body {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
min-height: 100vh;
}
div[class^="main"][att="alwaysVisible"] {
height: 150px;
width: 150px;
background-color: royalblue;
border-radius: 8px;
}
.main.main-280 {
box-shadow: 4px 8px 20px rgba(0,0,0,.5);
}
<div class="main main-280" att="alwaysVisible"></div>
<button>toggle class main-280</button>

How to control the size of <label> element in React?

I want to make element to be the same size of box, but the size of label is shorter than I expected. Also, "width" is not working in the React.
How can I solve this problem?
const DragDrop = () => {
...
return (
<div className="DragDrop" style={{ height: `${30 + 5 * files.length}vh` }}>
<input
type="file"
accept="audio/flac, audio/mp3, audio/ogg, audio/wav"
id="fileUpload"
style={{ display: "none" }}
multiple={true}
onChange={onChangeFiles}
/>
<div className={isDragging ? "DragDrop-File-Dragging" : "DragDrop-File"}>
<label htmlFor="fileUpload">
<Box ref={dragRef} className={"DragDrop-FileBox"}>
<Typography variant="h5">
{isDragging
? "Drop here!"
: "Drag files"}
</Typography>
</Box>
</label>
</div>
</div>
);
};
This code shows example like this.
If I remove element, the result shows like this. (just I expected.)
And here is scss file I used.
#mixin filledStyle() {
background-color: grey;
border-radius: 10px;
color: white;
}
#mixin alignCenter() {
display: flex;
display: -webkit-flex;
flex-direction: column;
-ms-flex-direction: column;
align-items: center;
}
#mixin alignCenterVertical() {
display: flex;
display: -webkit-flex;
flex-direction: column;
-ms-flex-direction: column;
justify-content: center;
align-items: center;
}
.DragDrop {
width: 100%;
height: 20vh;
#include alignCenter();
&-File {
width: 100%;
height: 200px;
border: 2px dashed grey;
border-radius: 10px;
#include alignCenterVertical();
cursor: pointer;
transition: 0.12s ease-in;
&-Dragging {
width: 100%;
#include filledStyle();
}
}
&-FileBox {
width: 100%;
height: 200px;
border: 2px dashed grey;
border-radius: 10px;
#include alignCenterVertical();
cursor: pointer;
transition: 0.12s ease-in;
}
}
Make forcefully take the label width 100% via width 100% in the label
.DragDrop {
width: 100%;
height: 20vh;
#include alignCenter();
label{
width:100%;
}
}
It seems <label> elements are inline, by default (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label).
inline elements can have neither width nor height (ignored).
Set display: inline-block to overcome this problem.

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>

Placing a div below another div using Flexbox

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

Resources