React & Css: How to style multiple nested components?

Hi!

After taking a few courses here (Front-end with React, HTML and CSS), I’ve decided to go on and try to develop my own project, coded with React and styled with CSS. I was doing well so far in the React part, but when I tried to style everything a little to give it a form, I hit a wall.

I’m using grid display with CSS files to try and order everything on my page, but it seems that child components can only express themselves within their parent component. which makes it extremely difficult to organize when there’s something like 5 or 6 degrees between the original parent component and the final child component, and that you want to display each of these components on the same page, but in different locations (and not necessarily locations that are included in the perimeter of the previous parent component).

Is there a best practice to follow here in order to achieve that?
What’s commonly used as CSS styling method when there are several components that need to appear on the same page but they’re all nested in one another?

I would really appreciate help on this as I’ve been struggling for a few days on this :frowning:
Thanks!!

Hi @ruby0855699667, I have moved your topic into the CSS category, as I think you will get better answers that way. Let me know if you want it changed back.

Thank you.
I’m still not sure wether it belongs to React or CSS function, as fundamentally it is a CSS issue, but I suspect only React devs would be able to tackle it, that’s why I originally posted it in the React section.

If your layout is very complex with precise positioning needed (example), CSS Grid will help a lot.

Otherwise, use CSS Flex Box for most of your needs. It will handle symmetrical layouts very easily or layouts where you need to auto-wrap elements (i.e. a bunch of book rows or a bunch of product rows will auto-wrap to the next line). It’s great for responsive design, too, (small screen , tablets , big computer screens).

Thank you very much for your reply!

Actually what I’m trying to do is kinda similar to the complex design you’ve linked in your message. Except that in my version, imagine a search bar on the left that would return a list of elements right under the search bar, and displayed in a scrollable column, and each time u click on one, it displays the details in the same way details of elements are displayed in your example.

And to achieve that, basically I have a SearchResult parent Component rendering a List Component rendering several Elements components, each rendering an ElementDetail component (for which I turn display on/off on click).
In your version it seems you’re not using component at all. Does it mean I have to give up components and nesting to use the grid styling? In this case, is it better to give up coding using components, or would it be better to use an alternate CSS display method? (And if so, which one?).

Thank you!

No, components is not an issue. Components in the end just compile down to regular HTML elements which can be affected by CSS. Using Grid, Flex Box or any CSS with React is just fine.

Can you post a picture or a drawing of the layout? That will be a better way to say what would be best.

Understand that some parts of this layout may be best with Flex Box and other smaller parts can use CSS Grid. You can mix them to make your final layout.

Sure.

So basically, on step:

1/It renders the page, but only the search component (the search bar) and the recipient for the search result (scrollable list, empty for now).

2/Enter a search term and click on search. Renders a Result List component in the search result recipient.

3/You can scroll through the Result List component and click on one element.

4/Upon click on one element, it renders a Details component which displays its details on the right

Basically and simply put, that’s how it works.
My problem is, since 4 is nested in 3, which is nested in 2 which is nested in 1, 4 can only be displayed in the zone allocated to 1 originally, and so on. (If I use what I know of grid display in CSS).
Is there a way to go around that, use grid system, have the display I want, but not be prisoner of a parent or grand-parent grid?

When I see this layout, I would tend to use Flex Box for most of it balancing it with margin and/or padding properties to refine positioning. Of course, Grid could work, too, but there’s enough symmetry that Flex Box could work using parent and child properties.

Are you challenging yourself to do this in Grid and therefore, trying to only use Grid? Or are you allowing yourself to use whatever works, including a combination of ways?

Here’s a sketch of the outer most elements using Flex: https://codepen.io/SixStringsCoder/pen/db5589ae9283e3782328912e8fb9d03e

Here’s Grid only: https://codepen.io/SixStringsCoder/pen/347a71165b7685b033043644c28b36ae

Depends on what you’re challenging yourself to practice with this project. I think Flex could do it and in some cases with Section 3 you wouldn’t need Flex nor Grid if you use block level HTML elements which will sit on top of each other.

Thanks again for taking the time.
I wasn’t challenging myself to do everything with Grid, but when I started to code the CSS, that’s what seemed the most natural to me. Plus, we’re not being taught Flex in the codecademy CSS course, so I didn’t know anything…Now I’ve learned the basics of it, and tried to apply them to my styling. It feels like it fits better for my project indeed, but eventually I run into the same problem. I’m starting to think the issue is how I coded the React part that makes it impossible for me to obtain the styling I’m after. Here are the 2 elements that fundamentally cause me trouble:

import React from 'react';
import Dealer from '../Dealer/Dealer';
import './Dealerslist.css';

class Dealerslist extends React.Component{

    render(){
        if(this.props.dealerResults.length === 0){
            return (
                <div className="List">
                <h2>Dealers list</h2>
                <h2>No Results</h2>
                </div>
            )
        }else if(this.props.isClear){
        return(
<div className="ContainerDealerslist">
    {this.clearState}
    <div className="List">
    <h3>Dealers list</h3>
</div>
    {this.props.dealerResults.map(dealr=>
        {return(
        <Dealer onClick={this.handleClick} dealr={dealr} key={dealr.id}/>);}
        )
        } 
</div>
        );
    }
    }
}


export default Dealerslist;

Here’s the related CSS:

.List{
width:20%;
height: 5%;
display:flex;
border:6px yellow solid;
flex-direction:column;
}

.ContainerDealerslist{
width:100%;
height:100%;
border:5px blue solid;
}

so basically in the component above, I render a list of Dealer’s components. Now here’s the Dealer component itself:

import React from 'react';
import DealerDetails from '../DealerDetails/DealerDetails';
import './Dealer.css';

class Dealer extends React.Component{
constructor(props){
    super(props);
    this.state={
        showComponent: false,
    };
    this.handleClick = this.handleClick.bind(this);
    this.clearState = this.clearState.bind(this);
}
handleClick(){
    this.setState({
      showComponent: true,
    });
  }

  clearState(){
      this.setState({
          showComponent: false
      })
  }

    render(){
            return(
                <div>
                <div className="RealDealer">
                <button onClick={this.handleClick}>details</button>
                <img src={this.props.dealr.logo} height="80" width="80" alt="logo shop"/>
                  <h5>{this.props.dealr.name}, {this.props.dealr.location}</h5>
                </div>
              {this.props.clearState}
              <div className="RealDealerDetails">
                <DealerDetails dealer={this.props.dealr} state={this.state.showComponent}/>
              </div>
              </div>

            );
    }
     
};

export default Dealer;

and here’s the related CSS (Some of the styling is just here for the visibility of my tests):

.RealDealer{
width:20%;
display:flex;
border:3px purple solid;
}

.RealDealerDetails{
position:absolute;
display:flex;
z-index: 10;
border:5px greenyellow solid;

}

so my Dealer component renders each Dealer’s basic info, plus a DealerDetails component (Only shows up with onClick event handler). So the pattern of rendering each time is:
Dealer A basic info
Dealer A DealerDetails component
Dealer B basic info
Dealer B DealerDetails component

My problem is, even though I’m fine with the Dealer’s basic info being displayed in a list (that’s the expected result, and that’s what correspond the 3/ in the drawing of my previous post), I’m not fine with the details being rendered where they are rendered. I would like them to render everytime in the “Details” of my previous message’s drawing, but no matter how I experiment with Flex and/or Grid, I can’t manage to get it there. Is there something I’m missing? :frowning:

Ruby, why don’t meet on CodePen to discuss this. I familiarized myself with the code you provided but I’m unsure of a few things and it would be good to see all the code. I’m more than happy to help and it will probably be a lot less going back and forth.

One thing I want to check out is if you have a bigger container around your DealersList and Dealer components. It currently looks like the DealerList component, with width of 100%, is taking up all the space. Then RealDealer has 20% width which means it could be off of the screen?

Plus, RealDealerDetails may be better off with flex-direction: column rather than the default “row” you currently have it set at.

Anyway, message me. I’m in Portland, OR (PST) and I’m more than willing to meet about this and help however a I can. Let me know where you’re at so we can set up a time.

Thank you Steve! The CodePen session was eye-opening even if it didn’t work properly XD

So to end this topic, I finally managed to solve my issue, not by changing my CSS code, but by fundamentally changing the way I coded my React components. Having the Dealer’s Details being rendered as a child of a single Dealer element somehow restricted this child element to the parent one, and no matter what display system I used, I couldn’t manage to get the Dealer’s details to display where I wanted to.

So instead of that, upon search I generated both a dealer’s list and the Dealer’s details. By doing so, I was able to separate the two display zones, and that did the trick! :slight_smile:
Hope it’ll help someone along the way.

Again, thank you Steve!

One thing my wife, Rebecca, and I do before we start React projects is we:

  1. Draw the website layout on paper or in Photoshop/Illustrator

  2. Make a static website only using HTML and CSS. This helps solve a lot of the layout issues with Flex/Grid

  3. Then we copy our HTML and CSS into React components. Then make small adjustments to HTML if needed.

  4. Add the logic to the components.

We found it easier than working straight away with React.

That said, sometimes it’s just fun to start code in React right away. But I usually get lost later on when the components start to pile up! :crazy_face: