How to center Bootstrap Cards with Even Spacing on Website?

33 Views Asked by At

I'm working on a React application using Bootstrap, and I'm facing challenges in getting the Bootstrap Cards to be centered with an even spacing on my website. The space between three cards in a row is way to high, furthermore the cards arent centered properly on the website. I've tried using the Bootstrap Grid Layout, but it doesn't seem to provide the desired result.

Below is the code I'm using for the Card component:

import Card from 'react-bootstrap/Card';
import Button from 'react-bootstrap/Button';
import ListGroup from 'react-bootstrap/ListGroup';
import Container from 'react-bootstrap/Container';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import './Card.css';

function KitchenSinkExample() {
    return (
        <Container fluid className="mt-4 text-center">
            <Row xs={1} md={3} className="g-4 justify-content-center">
                {Array.from({ length: 6 }).map((_, idx) => (
                    <Col key={idx} className="mb-4">
                        <Card style={{ width: '18rem' }}>
                            <Card.Img variant="top" src={`holder.js/100px180?text=Image cap ${idx + 1}`} className='card-img-top' />
                            <Card.Body>
                                <Card.Title>Card Title</Card.Title>
                                <Card.Text>
                                    Some quick example text to build on the card title and make up the
                                    bulk of the card's content.
                                </Card.Text>
                            </Card.Body>
                            <ListGroup className="list-group-flush">
                                <ListGroup.Item>Cras justo odio</ListGroup.Item>
                                <ListGroup.Item>Dapibus ac facilisis in</ListGroup.Item>
                                <ListGroup.Item>Vestibulum at eros</ListGroup.Item>
                            </ListGroup>
                            <Card.Body>
                                <Button variant="primary" className='chat-button'>Go somewhere</Button>
                            </Card.Body>
                        </Card>
                    </Col>
                ))}
            </Row>
        </Container>
    );
}

export default KitchenSinkExample;


And here is the corresponding CSS:

.btn-primary {
    background-color: #0074cc !important;
    color: white !important;
    padding: 10px !important;
    border-radius: 20px !important;
    width: 65% !important;
    font-size: 20px !important;
    margin-bottom: 10px;
}

.card {
    padding: 1.5em .5 .5em;
    text-align: center;
    box-shadow: 0 5px 10px rgba(0, 123, 255, 0.2);
    border-radius: 2em;
}

.card-title {
    font-weight: bold;
    font-size: 1.5em;
}

.card-img-top {
    width: 60%;
    border-radius: 50%;
    padding: 1em;
    margin: 0 auto;
    box-shadow: 0 5px 10px rgba(0, 123, 255, 0.2);
}

.chat-button:hover {
    background-color: #fff !important;
    color: #0074cc !important;
}

Despite my efforts, the cards are not appearing as desired. I want them to be centered on the page with equal spacing between them. Could someone please guide me on how to achieve this using the Bootstrap Grid Layout or any other recommended approach?

Any help would be greatly appreciated! Thanks in advance.

I tried to use the ReactJS Bootstrap Grid Layout, it didnt work

1

There are 1 best solutions below

0
Wongjn On

You could consider not setting the column count for Row. This then allows the inner Col components to be sized auto:

Set the column value (for any breakpoint size) to auto to size columns based on the natural width of their content.

This then allows the columns (and thus, the inner Cards) to be subject to the justify-content: center from the justify-content-center class:

const {
  Card,
  Button,
  ListGroup,
  Container,
  Row,
  Col
} = ReactBootstrap

function KitchenSinkExample() {
    return (
        <Container fluid className="mt-4 text-center">
            <Row xs={1} className="g-4 justify-content-center">
                {Array.from({ length: 6 }).map((_, idx) => (
                    <Col key={idx} className="mb-4" xs="auto" sm="auto">
                        <Card style={{ width: '18rem' }}>
                            <Card.Img variant="top" src={`https://placehold.co/100x180?text=Image+cap+${idx + 1}`}className='card-img-top' />
                            <Card.Body>
                                <Card.Title>Card Title</Card.Title>
                                <Card.Text>
                                    Some quick example text to build on the card title and make up the
                                    bulk of the card's content.
                                </Card.Text>
                            </Card.Body>
                            <ListGroup className="list-group-flush">
                                <ListGroup.Item>Cras justo odio</ListGroup.Item>
                                <ListGroup.Item>Dapibus ac facilisis in</ListGroup.Item>
                                <ListGroup.Item>Vestibulum at eros</ListGroup.Item>
                            </ListGroup>
                            <Card.Body>
                                <Button variant="primary" className='chat-button'>Go somewhere</Button>
                            </Card.Body>
                        </Card>
                    </Col>
                ))}
            </Row>
        </Container>
    );
}

ReactDOM.createRoot(document.getElementById('app')).render(<KitchenSinkExample/>);
.btn-primary {
    background-color: #0074cc !important;
    color: white !important;
    padding: 10px !important;
    border-radius: 20px !important;
    width: 65% !important;
    font-size: 20px !important;
    margin-bottom: 10px;
}

.card {
    padding: 1.5em .5 .5em;
    text-align: center;
    box-shadow: 0 5px 10px rgba(0, 123, 255, 0.2);
    border-radius: 2em;
}

.card-title {
    font-weight: bold;
    font-size: 1.5em;
}

.card-img-top {
    width: 60%;
    border-radius: 50%;
    padding: 1em;
    margin: 0 auto;
    box-shadow: 0 5px 10px rgba(0, 123, 255, 0.2);
}

.chat-button:hover {
    background-color: #fff !important;
    color: #0074cc !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-bootstrap/2.9.2/react-bootstrap.min.js" integrity="sha512-wNDLsNGwX8AMZLwX3fEvh6vc7dicHVKzmz1TbDAv2ssoh7i7Hb8qy+FuOsHDeRr5PLRhvf9CQwNy/7ljOllTcw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.2/css/bootstrap.min.css" integrity="sha512-b2QcS5SsA8tZodcDtGRELiGv5SaKSk1vDHDaQRda0htPYWZ6046lr3kJ5bAAQdpV2mmA/4v0wQF9MyU6/pDIAg==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<div id="app"></div>

Otherwise, for a centered 3×3 grid, you could create it yourself with CSS grid, instead of using Bootstrap layout components:

const {
  Card,
  Button,
  ListGroup,
  Container,
  Row,
  Col
} = ReactBootstrap

function KitchenSinkExample() {
    return (
        <Container fluid className="mt-4 text-center">
            <div className="grid">
                {Array.from({ length: 6 }).map((_, idx) => (
                    <Card style={{ width: '18rem' }}>
                        <Card.Img variant="top" src={`https://placehold.co/100x180?text=Image+cap+${idx + 1}`}className='card-img-top' />
                        <Card.Body>
                            <Card.Title>Card Title</Card.Title>
                            <Card.Text>
                                Some quick example text to build on the card title and make up the
                                bulk of the card's content.
                            </Card.Text>
                        </Card.Body>
                        <ListGroup className="list-group-flush">
                            <ListGroup.Item>Cras justo odio</ListGroup.Item>
                            <ListGroup.Item>Dapibus ac facilisis in</ListGroup.Item>
                            <ListGroup.Item>Vestibulum at eros</ListGroup.Item>
                        </ListGroup>
                        <Card.Body>
                            <Button variant="primary" className='chat-button'>Go somewhere</Button>
                        </Card.Body>
                    </Card>
                ))}
            </div>
        </Container>
    );
}

ReactDOM.createRoot(document.getElementById('app')).render(<KitchenSinkExample/>);
.grid {
  display: grid;
  grid-template-columns: 18rem;
  gap: 1.5rem;
  justify-content: center;
}

@media (min-width: 576px) {
  .grid {
    grid-template-columns: repeat(2, 18rem);
  }
}

@media (min-width: 768px) {
  .grid {
    grid-template-columns: repeat(3, 18rem);
  }
}

.btn-primary {
    background-color: #0074cc !important;
    color: white !important;
    padding: 10px !important;
    border-radius: 20px !important;
    width: 65% !important;
    font-size: 20px !important;
    margin-bottom: 10px;
}

.card {
    padding: 1.5em .5 .5em;
    text-align: center;
    box-shadow: 0 5px 10px rgba(0, 123, 255, 0.2);
    border-radius: 2em;
}

.card-title {
    font-weight: bold;
    font-size: 1.5em;
}

.card-img-top {
    width: 60%;
    border-radius: 50%;
    padding: 1em;
    margin: 0 auto;
    box-shadow: 0 5px 10px rgba(0, 123, 255, 0.2);
}

.chat-button:hover {
    background-color: #fff !important;
    color: #0074cc !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-bootstrap/2.9.2/react-bootstrap.min.js" integrity="sha512-wNDLsNGwX8AMZLwX3fEvh6vc7dicHVKzmz1TbDAv2ssoh7i7Hb8qy+FuOsHDeRr5PLRhvf9CQwNy/7ljOllTcw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.2/css/bootstrap.min.css" integrity="sha512-b2QcS5SsA8tZodcDtGRELiGv5SaKSk1vDHDaQRda0htPYWZ6046lr3kJ5bAAQdpV2mmA/4v0wQF9MyU6/pDIAg==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<div id="app"></div>