How do I make my React Bootstrap cards line up horizontally and equally spaced (also responsively if possible)

28,116

You could use style={{display: 'flex', flexDirection: 'row'}} on the CardDeck and then put style={{flex: 1}} on the card.

They should fill up the remaining space. One thing is to make sure to provide the size that you want the CardDeck to be.

More info on flexbox here

Share:
28,116
frootloops
Author by

frootloops

Experienced Front-End Web Developer adept in all stages of development. Knowledgeable in user interfaces, testing, and debugging processes. Equipped with a diverse and promising skill-set. Proficient in an assortment of technologies including but not limited to Javascript ES6, ReactJS, Typescript, Redux, and GraphQL. Able to effectively self-manage on independent projects, as well as collaborate in a team setting.

Updated on August 08, 2022

Comments

  • frootloops
    frootloops over 1 year

    I am using Reactstrap and displaying my cards dynamically and they seem to want to stack vertically no matter what I try. Here is the component in which they are rendered:

    import React, { Component } from 'react';
    import { Link } from 'react-router-dom';
    import { connect } from 'react-redux';
    import { CardDeck } from 'reactstrap';
    import { fetchMerch } from '../actions/fetchMerchAction';
    import { fetchUniqueMerch } from '../actions/fetchUniqueMerchAction';
    import ItemCard from './ItemCard';
    import shortid from 'shortid';
    
    class ShopHome extends Component {
    
      componentDidMount() {
        this.props.onInitMerch();
      }
    
      showItemDetailHandler = (id) => {
        // console.log("*",id);
        this.props.onInitUniqueMerch(id);
        this.props.history.push(`detail/${this.props.id}`)
      }
    
      render() {
    
        let cards;
        if ( this.props.cards ) {
          cards = Object.values(this.props.cards).map( card => (
            <Link to={'/detail/' + card.id } key={`div-${shortid.generate()}`}>
    
                  <ItemCard 
                    key={card.id} 
                    id={card.id} 
                    title={card.title}
                    price={card.price}
                    image={card.img} 
                    description={card.description}
                    clicked={() => this.showItemDetailHandler(card.id)}
                  />
            </Link>
            ) 
          )
        };
        return ( 
            <CardDeck>
              {cards}
            </CardDeck>     
        );
      }
    }
    
    const mapStateToProps = state => {
      // console.log("map props to state")
      // console.log("----->",state.data.cardData)
      return {
        cards: state.data.cardData,
        id: state.data.cardData
      };
    }
    
    const mapDispatchToProps = dispatch => {
      return {
        onInitMerch: () => dispatch(fetchMerch()),
        onInitUniqueMerch: (id) => dispatch(fetchUniqueMerch(id))
      };
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(ShopHome);
    

    Here is the card component:

    import React, { Component } from 'react';
    import { withRouter } from 'react-router';
    import { Card, CardImg, CardText, CardBody,
      CardTitle, CardSubtitle } from 'reactstrap';
    import './ItemCard.css';
    
    class ItemCard extends Component {
    
      render() {
    
        return (
        <div>
          <Card className="card-style" onClick={this.props.clicked}>
            <CardImg top width="100%" src={this.props.image} alt="Card image cap" />
            <CardBody>
              <CardTitle >{this.props.title}</CardTitle>
              <CardSubtitle>${this.props.price}</CardSubtitle>
              <CardText>{this.props.description}</CardText>
            </CardBody>
          </Card>
        </div>
        );
      }
    }
    
    export default withRouter(ItemCard);
    

    Here is the ItemCard.css:

    .card-style {
      max-width: 30%;
    }
    

    If I give the cards a fixed size with inline styling: style={{width: 20 + 'rem'}} the cards line up horizontally but I cannot center them on the page. They line up a little to the left. I just want a three card row centered and evenly spaced.

  • frootloops
    frootloops over 5 years
    Thanks for the reply. I added a width of 100% to the CardDeck and added the styles you posted, but that seems to return the same results.
  • shkfnly
    shkfnly over 5 years
    Add justifyContent: center to the CardDeck
  • frootloops
    frootloops over 5 years
    Finally got it. I had to use em instead of % on the card width for some reason. Then I did what you said @shkfnly. Thanks for your help.
  • Priyom saha
    Priyom saha almost 4 years
    @shkfnly I am also facing the same problem but It's not working with the above instructions My code Link is : stackoverflow.com/q/62277219/7583640
  • shankar upadhyay
    shankar upadhyay over 3 years
    Your answer is really helpful @shkfnly. I am wondering if there could be a more elegant way to achieve the same.