target child element styled components
Asked Answered
M

3

30

I'm trying to change the nth-child(2) background color of the ColorBox element by targeting it as a child of ImgGrid but I just can't seem to get it to work, I have tried multiple variations with different elements and nothing seems to be working

This will change the background color if I don't try to target an nth-child element

const ImgGrid = styled.div`
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  ${ColorBox} {
    background: #ff00ff;
  }
`

How can I target the nth-child(2) of the ColorBox element?

import React from 'react'
import styled from 'styled-components'
// import Img from '../../atoms/Img'
import { array, bool } from 'prop-types'

const Wrap = styled.div`
  padding: 20px 0;
`

const BoxWrap = styled.div`
  position: relative;
  border: 1px solid #000;
  height: auto;
  padding: 20px;
`

const Title = styled.div`
  position: absolute;
  display: flex;
  align-items: center;
  top: -20px;
  left: 50%;
  -webkit-transform: translateX(-50%);
  transform: translateX(-50%);
  height: 40px;
  background: #f6f6f6;
  padding: 10px;
`

const BoxInner = styled.div`
  width: 100%;
  height: 100%;
`

const ColorBox = styled.div`
  height: 60px;
  width: 100%;
  background: #FFD700;
`

const ImgCell = styled.div`
  flex: 0 0 25%;
  padding: 5px;
`

const ImgGrid = styled.div`
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  &:nth-child(2) ${ColorBox} {
    background: #ff00ff;
  }
`

const ImgCellInner = styled.div`
  position: relative;
`

// const ImgText = styled.div`
//   position: absolute;
//   bottom: 0;
//   left: 0;
//   padding: 5px;
//   width: 100%;
//   background: rgba(0,0,0,0.7);
//   color: #fff;
// `


const ImgWrap = styled.div`
  width: 100%;
`

const ColorWrap = styled.div`

`

const Filter = ({ filterData, color }) => (
  <Wrap>
    <BoxWrap>
      <Title>
        For Women
      </Title>
      <BoxInner>
        <ImgGrid>
          {filterData.map(filter =>
            <ImgCell>
              <ImgCellInner>
                <ImgWrap>
                  {color &&
                  <ColorWrap>
                    <ColorBox />
                    {filter.text}
                  </ColorWrap>
                  }
                </ImgWrap>
              </ImgCellInner>
            </ImgCell>,
          )}
        </ImgGrid>
      </BoxInner>
    </BoxWrap>
  </Wrap>
)

/* eslint-disable*/
Filter.propTypes = {
  filterData: array,
  color: bool,
}

Filter.defaultProps = {
  filterData: array,
  color: bool,
}

export default Filter
Mountebank answered 9/2, 2018 at 20:12 Comment(2)
Will it be ok to pass prop with sort of index to the ColorBox and access this prop in the styled-component?Aorist
sure if that worksMountebank
A
46

I can assume your code is not working because &:nth-child(2) means you are selecting ImgGrid which is second child itself. Try to specify ImgCell as nth-child(2):

const ImgGrid = styled.div`
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  ${ImgCell}:nth-child(2) ${ColorBox} {
    background: #ff00ff;
  }
`

I'm not sure about scoping, so probably you need to use & before:

const ImgGrid = styled.div`
      display: flex;
      flex-wrap: wrap;
      flex-direction: row;
      & ${ImgCell}:nth-child(2) ${ColorBox} {
        background: #ff00ff;
      }
    `
Aorist answered 9/2, 2018 at 20:34 Comment(3)
How I apply the same in a series of <tr>s in the code? I tried const CustomTbody = styled.tbodytr:nth-child(odd){className: 'odd'}Strati
@Strati I'm not quite sure what your code is doing, because inside { } should be css and className: 'odd' is not.Aorist
Sorry, my bad. I wanted to add class with the help of pseudo elements. I was mixing SASS class names with styled components. As I understand from the industry experts, theme should be applied with styled components.Strati
P
10

If you stumble on this question looking for how to target all children elements, here is how;

    const ParentDiv = styled.div`
       >*  {
           background: white;
           padding: 5px;
           };
            /* ...etc */
           
           `;
Purkey answered 31/8, 2021 at 13:23 Comment(0)
G
2

I had the same problem. :focus-within in parent element worked for me, could solve your problem too.

Eg:

export const Parent = styled.div`
  display: flex;
  align-items: center;
  border: 1px solid #000;

  &:focus-within {
    border: 1px solid #2ADCC6;
  }
`;

export const Child = styled.input`
  flex: 1;
  border: none;
`;

Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-within

Gewirtz answered 16/9, 2021 at 14:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.