Responsive Card Grid in React - javascript

I'm new to the front-end world, and I'm trying to make a "responsive" card grid, meaning I want to place an unknown number of cards inside a grid and make the text and layout fit
nicely. I'm using react-bootrap Card and CardGroup, this is what I got so far.
If I use too many Cards, they get horizontally stretched and don't create new rows for a better layout, I'd expect to have a min-width so if it doesn't fit it creates a new row, but I'm not sure how to get this done or if it's the best practice.
Sorry if some of the terms are incorrect; I just started learning as mentioned.
Here is my GridCard.js code
import React from "react";
import {Card, CardGroup, Button} from "react-bootstrap";
import "./CardGrid.css"
const CardGrid = () => {
return (
<CardGroup>
{Array.from({ length: 10 }).map((_, index) => (
<Card className={"card-grid"} key={index}>
<Card.Img className={"card-img"} variant="bottom" src={"https://cdn.pixabay.com/photo/2014/11/30/14/11/cat-551554_960_720.jpg"}/>
<Card.Body>
<Card.Title><strong>Lorem ipsum dolor sit amet</strong></Card.Title>
<Card.Text>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolores harum, illum.
Accusamus assumenda commodi consequuntur cumque, delectus deleniti dolorum eum illum
nam nostrum provident quaerat quisquam quos reiciendis, reprehenderit voluptas!</p>
</Card.Text>
<Button variant="primary"
href="www.google.com"
rel={"noopener noreferrer"}>
Learn More
</Button>
</Card.Body>
</Card>
))}
</CardGroup>
)
}
export default CardGrid
and my CardGrid.css
.card-group {
justify-content: center;
}
.card-grid, .card {
padding: 5px 5px !important;
height: auto !important;
justify-content: center;
margin: 1rem;
}
.card-body {
background-color: #F6F5F5;
margin: 0;
}
.card-img,
.card-img-top,
.card-img-bottom {
height: 10rem;
width: auto;
align-content: flex-start;
}
.card-text {
height: fit-content;
margin-bottom: 2rem;
}
.btn, .btn-primary {
position: absolute;
bottom: 5px;
color: #263238;
overflow: auto;
}

this is something complex I used in another project, this is the parent grid container
.parent{
display: grid;
grid-template-columns: repeat(auto-fit, minmax(40rem, 1fr));
grid-gap: 2rem;
margin-block: 2rem;
padding: 0 1rem;
justify-items: center;
align-items: center;
}
Where the grid-template-columns creates a column size from a minimum of 40rem and a maximun of 1fr. You can play with the sizes.
But if you're looking for something simpler, I'd use display flex and flex-wrap like this
.parent{
display:flex;
max-width: 1200px;
flex-wrap: wrap;
}
UPDATE...
Apparently what we were missing was assigning a width to the card component, we fixed it by using min-width to the card component

Related

why all the listItem components are not polpulating

*** i map through an array and for every item m calling ListItem component so there should be 3 ListItems but only one is getting populated ,dont know what wrong please help
*** this my app js ***
import FeedbackList from "./components/FeedbackList";
import FeedbackStatus from "./components/FeedbackStatus";
import Header from "./components/Header";
import feedbackData from "./data/feedback";
function App() {
return (
<div className="App">
<Header/>
<FeedbackStatus feedback={feedbackData}/>
<FeedbackList/>
</div>
);
}
export default App;
*** this is my feedbacklist component , where i map through feedbackData and for each item i m calling feedbackItem component , passed item as prop ***
import React from "react";
import FeedbackItem from "./FeedbackItem";
import { useState } from "react";
import feedbackData from "../data/feedback";
function FeedbackList() {
const [feedback, setFeedback] = useState(feedbackData);
return (
<div className="feedbackList">
<div className="imgcon">
<img
className="feedbackimage"
src="https://png.pngtree.com/png-clipart/20220930/original/pngtree-customer-reviews-with-people-giving-star-ratings-on-a-mobile-phone-png-image_8644419.png"
alt="feedback"
/>
</div>
<div className="showfeedback">
{feedback.map((item) => (
<FeedbackItem key={item.id} item={item} />
))}
</div>
</div>
);
}
export default FeedbackList;
*** my feedbackData ***
const feedbackData = [
{
id: 1,
rating: 10,
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. consequuntur vel vitae commodi alias voluptatem est voluptatum ipsa quae.',
},
{
id: 2,
rating: 9,
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. consequuntur vel vitae commodi alias voluptatem est voluptatum ipsa quae.',
},
{
id: 3,
rating: 8,
text: 'Lorem ipsum dolor sit amet consectetur adipisicing elit. consequuntur vel vitae commodi alias voluptatem est voluptatum ipsa quae.',
},
]
export default feedbackData
*** this is my feedbackItem component , here i have received item as prop ***
import React from 'react'
function FeedbackItem({item}) {
return (
<div className='feedbackItem'>
<p className='rating'> {item.rating}</p>
<p className='review'></p>
</div>
)
}
export default FeedbackItem
*** this is my css if it helps ***
#import url('https://fonts.googleapis.com/css2?family=Poppins:wght#400;600;700&display=swap');
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Poppins', sans-serif;
background-color: rgb(9, 154, 154);
line-height: 1.6;
}
.heading{
text-align: center;
color: white;
max-width: 768px;
margin: auto;
padding: 0 20px;
}
.feedbackList{
display: flex;
height: 100vh;
}
.imgcon{
flex: 4;
justify-content: center;
align-items: center;
}
.showfeedback{
flex: 6;
}
.feedbackimage{
object-fit: cover;
width: 600px;
height: 600px;
margin-left: 100px;
margin-top: 100px;
background-attachment: fixed;
}
.feedbackItem{
border-radius: 20px;
background-color: aquamarine;
width: 50vw;
height: 20vh;
position: absolute;
margin-top: 110px;
margin-left: 50px;
margin-bottom: 50px;
}
.review{
text-align: center;
font-weight: 900;
margin: 10px 5px 5px 5px ;
color:#fff;
}
.rating{
display: flex;
justify-content: center;
align-items: center;
border-radius: 50px;
width: 30px;
height: 30px;
background-color: rgb(251, 221, 51);
text-align: center;
position: relative;
top: 5px;
left: 5px;
vertical-align: middle;
color: black;
}
.states{
display: flex;
justify-content: space-between;
align-items: center;
}
.states :nth-child(1){
margin-left: 20px;
}
.states :nth-child(2){
margin-right: 20px;
}
import FeedbackList from "./components/FeedbackList";
import FeedbackStatus from "./components/FeedbackStatus";
import Header from "./components/Header";
import feedbackData from "./data/feedback";
function App() {
return (
<div className="App">
<Header/>
<FeedbackStatus feedback={feedbackData}/>
<FeedbackList feedbackData={feedbackData}/>
</div>
);
}
export default App;
function FeedbackList(props) {
const [feedback, setFeedback] = useState(props.feedbackData);
return (
<div className="feedbackList">
<div className="imgcon">
<img
className="feedbackimage"
src="https://png.pngtree.com/png-clipart/20220930/original/pngtree-customer-reviews-with-people-giving-star-ratings-on-a-mobile-phone-png-image_8644419.png"
alt="feedback"
/>
</div>
<div className="showfeedback">
{feedback.map((item) => (
<FeedbackItem key={item.id} item={item} />
))}
</div>
</div>
);
}

FAQ boxes of my website aren't working well?

I tried to build this kind of FAQ question boxes in my website:
If I click on "plus" icon or text, they won't be open. Therfore I think, there may be some errors in JavScript code.
These are codes of the FAQ boxes in HTML, CSS & JavaScript:
[But they are not working well]
// Showing/hiding FAQS answers
const faqs = document.querySelectorAll('.faq');
faqs.forEach(faq => {
faq.addEventListener('click', () => {
faq.classList.toggle('open');
// Changing icon
const icon = faq.querySelector('.faq__icon i');
if (icon.className === 'uil uil-plus') {
icon.className = "uil uil-minus"
} else {
icon.className = "uil uil-plus"
}
})
})
.faq {
padding: 2rem;
display: flex;
align-items: center;
gap: 1.4rem;
height: fit-content;
background: var(--color-primary);
cursor: pointer;
}
.faq h4 {
font-size: 1rem;
line-height: 2.2;
}
.faq__icon {
align-self: flex-start;
font-size: 1.2rem;
}
.faq p {
margin-top: 0.8rem;
display: none;
}
.faq.open p {
display: block;
}
<article class="faq">
<div class="faq__icon"><i class="uil uil-plus"></i></div>
<div class="question__answer">
<h4>Lorem Ipsum ?</h4>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptates sapiente odio natus excepturi, culpa rem deleniti? Cum pariatur aut nulla a recusandae sit itaque voluptatem optio! Possimus, iure! Mollitia, voluptatum?</p>
</div>
</article>
I do not know how to do this; can you help me, please?

how to align this page contnet without horizontal scroll bar?

Hi I am creating simple website using CSS flexbox, but from some reasons my layout in About.vue stretch out with this horizontal bar only this component is in mainLayout.vue, and I can't figure out what is wrong making this problem. Did someone know how to fix it?
MainLayout.vue
<template>
<div class="wrapper--main">
<Navbar />
<Hero />
<main>
<slot />
</main>
<Footer />
</div>
</template>
<script lang="ts">
import Hero from "../components/Hero.vue";
import Footer from "../components/Footer.vue";
import Navbar from "../components/Navbar.vue";
import { defineComponent } from "vue";
export default defineComponent({
components: { Navbar, Footer, Hero },
});
</script>
<style lang="sass">
#import "../styles/mainLayout.sass"
#import "../styles/variables.sass"
#import "../styles/utilitys.sass"
</style>
MainLayout.sass
#import url('https://fonts.googleapis.com/css2?family=Lato:wght#400;700&display=swap')
*,
*::before,
*::after
box-sizing: border-box
margin: 0px
padding: 0px
img,
picture,
svg
max-width: 100%
display: block
object-fit: cover
img
object-fit: cover
#media (min-width: 768px)
html
font-size: 130%
body
font-family: 'Lato', sans-serif
font-weight: 400
line-height: 1.65
max-width: 2000px
background-color: hsl(var(--white))
color: hsl(var(--text))
.wrapper--main
display: grid
grid-template-rows: auto 1fr auto
min-height: 100vh
main
display: grid
gap: var(--size-fluid-6)
margin-bottom: var(--size-fluid-5)
margin-top: var(--size-fluid-5)
Index.vue
<template>
<MainLayout><About /> </MainLayout>
</template>
<script lang="ts">
import MainLayout from "../layouts/MainLayout.vue";
import About from "../components/About.vue";
import { defineComponent } from "vue";
export default defineComponent({
components: { MainLayout, About },
});
</script>
<style lang="sass">
</style>
About.vue
<template>
<div class="about-container">
<div class="wrapper gap">
<div class="title-container--about gap--sm">
<div class="title-wrapper">
<h2 class="h2">lorem ipsum</h2>
<p class="title-container--sm">
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dolor
iusto impedit molestiae quo, labore perspiciatis quia, deserunt quis
nobis asperiores, delectus ut! Quaerat ut molestiae sunt ex
molestias fuga quis. orem ipsum dolor sit amet consectetur,
adipisicing elit. Dolor iusto impedit molestiae quo, labore
perspiciatis quia, deserunt quis nobis asperiores, delectus ut!
Quaerat ut molestiae sunt ex molestias fuga quis.
</p>
</div>
<div class="arrow--map">
<img class="icon--lg" src="../icons/arrow-map.svg" alt="" />
</div>
<div class="container-about-btn-map">
<img class="icon--lg about-map" src="../icons/map.svg" alt="" />
<button class="btn btn--primary about-btn">lorem ipsum</button>
</div>
</div>
<img class="img-about only-desktop" src="../img/about.jpg" alt="" />
</div>
</div>
</template>
<script lang='ts'>
import { defineComponent } from "vue";
export default defineComponent({});
</script>
<style lang="sass">
.title-container--sm
width: var(--size-fluid-10)
flex-grow: 0
.about-map
margin-right: auto
.about-btn
margin-right: auto
.container-about--btn-map
display: flex
flex-direction: column
justify-content: center
width: 200px
.gap--sm
gap: var(--size-fluid-4)
.title-container--about
display: flex
flex-direction: column
.arrow--map
display: flex
justify-content: center
.gap
gap: var(--size-fluid-8)
.about-container
margin-left: var(--size-fluid-7)
margin-right: var(--size-fluid-7)
#media (max-width: 1440px)
.only-desktop
display: none
</style>
Try adding this:
html, body
...
max-width: 2000px
width: 100vw
overflow-x: hidden
Although the overflow-x should be a last-resort if the method above fails.
An explanation of why it works
Well, the max-width property you put for the body element only says that the width of the body should not exceed a certain value. Your html element also has a width of its own, and by default thats the viewport (screen) width.
So if your body content stretches out in the y axis, your body element will expand to a maximum of the value you set inorder to accomodate that content, which means it will overflow the width of your html element.
Specifying width: 100vw means that the body will be of the same width as the html element and should not exceed that.
The max-width property only comes into play when the screen size is really large — e.g. on desktops — and you want to limit the width of the page content. That's not something that's typically done, because all the page content will be stuck to one side of the screen. I'm sure this is not your desired effect beacause this also means full-width elements like your navbar will not stretch across the entire screen.

Grid items disappearing on smaller screen sizes [duplicate]

This question already has answers here:
Can't scroll to top of flex item that is overflowing container
(12 answers)
Closed 3 years ago.
I am a very new developer attempting to make a presentable photo-gallery-esque type thing to practice a bit. I have been leaning on CSS grid heavily for my layout...and I am pretty proud of what I have thus far.
I have four cards each containing an image thumbnail, a header, and some text. When the user hovers over any card they have the option to "view" the image which brings up a full screen modal. Everything works as I have intended...however...when I decrease the screen size some cards end up disappearing off screen!
I am very new to CSS grid and I have tried just about everything I know at this point. Please help me cross the finish line!
The code below works perfectly if just copy-pasted into the html portion on codepen.io.
Thank you in advance for any help you may offer!
const buttons = document.querySelectorAll('button');
const modal = document.querySelector('.modal');
const image = modal.querySelector('img');
buttons.forEach(button => {
button.addEventListener('click', handleButtonClick);
});
function handleButtonClick(event) {
const card = event.currentTarget.closest('.card');
const chosenImage = card.querySelector('img').src;
image.src = chosenImage;
modal.classList.add('open');
}
document.addEventListener('click', function(event) {
const target = event.target;
const isModal = target.classList[0] === 'modal';
if (isModal) {
modal.classList.remove('open');
}
});
body {
margin: 0;
height: 100vh;
display: grid;
align-content: center;
background: linear-gradient(0deg, rgba(130, 109, 118, 1) 0%, rgba(172, 52, 52, 1) 100%);
}
.wrapper {
display: grid;
grid-gap: 40px;
justify-content: center;
grid-template-columns: repeat(auto-fit, 300px);
grid-template-rows: 450px;
grid-auto-rows: 450px;
}
.card {
border: solid 5px #ac3434;
border-radius: 0.8rem;
overflow: hidden;
background: #3a363670;
display: grid;
grid-gap: 4px;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(8, 1fr);
}
.img-wrapper {
grid-column: 2 / span 3;
grid-row: 2 / span 3;
display: grid;
}
.img-wrapper img {
height: 100%;
width: 100%;
object-fit: cover;
border: solid 3px #ac3434;
border-radius: 50%;
}
.card-body {
grid-column: 1 / -1;
grid-row: 5 / -1;
padding: 0 10px 0;
font-family: 'Ubuntu', sans-serif;
}
.card-body h2 {
font-family: 'Anton', sans-serif;
}
.card-overlay {
grid-column: 1 / -1;
grid-row: 1 / -1;
background: #ac34347a;
display: grid;
place-items: center center;
transform: translateY(100%);
transition: 0.4s;
}
.card:hover .card-overlay {
transform: translateY(0%);
}
.card-overlay button {
background: none;
color: white;
text-transform: uppercase;
position: relative;
bottom: 78px;
border: solid 3px white;
border-radius: 0.4rem;
font-family: 'Ubuntu', sans-serif;
}
.modal {
height: 100vh;
width: 100vw;
position: fixed;
background: #0000008f;
display: grid;
place-items: center center;
/* Make modal invisible until triggered */
opacity: 0;
/* Makes it so the modal does not log click
events */
pointer-events: none;
}
.open {
/* Displays the modal */
opacity: 1;
pointer-events: all;
}
.modal-inner {
width: 500px;
}
.modal-inner img {
width: 100%;
height: 100%;
object-fit: contain;
}
<div class="wrapper">
<div class="card">
<div class="img-wrapper">
<img src="https://picsum.photos/500">
</div>
<div class="card-body">
<h2>Sunny Walls</h2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Enim cupiditate molestias sed ea sit, dolore quos itaque consectetur doloribus at. Dolor accusamus consequuntur perspiciatis! Deserunt?
</p>
</div>
<div class="card-overlay">
<button>View ➜</button>
</div>
</div>
<div class="card">
<div class="img-wrapper">
<img src="https://picsum.photos/500">
</div>
<div class="card-body">
<h2>Kit-the-Kat</h2>
<p>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Dignissimos quaerat veritatis nobis voluptas minus exercitationem.
</p>
</div>
<div class="card-overlay">
<button>View ➜</button>
</div>
</div>
<div class="card">
<div class="img-wrapper">
<img src="https://picsum.photos/500">
</div>
<div class="card-body">
<h2>Sass in the City</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Explicabo accusantium consectetur vel ullam assumenda corrupti id ratione odio, nisi adipisci?
</p>
</div>
<div class="card-overlay">
<button>View ➜</button>
</div>
</div>
<div class="card">
<div class="img-wrapper">
<img src="https://picsum.photos/500">
</div>
<div class="card-body">
<h2>City Things</h2>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sint culpa suscipit libero consequatur quod non dolore neque aperiam nihil beatae? Dolores, deserunt.
</p>
</div>
<div class="card-overlay">
<button>View ➜</button>
</div>
</div>
</div>
<div class="modal">
<div class="modal-inner">
<img>
</div>
</div>
You need to use media tags in the css.
Your site is not responsive and when you change screen size it does not resize the components.
https://www.w3schools.com/css/css_rwd_mediaqueries.asp

Vertical alignment of floating divs [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I need to create a row, where three divs are positioned side by side:
In the divs, the middle one is always vertical aligned middle and the other ones are vertical aligned top.
I did this with the settings
Container:
display:table
Row:
display:table-row
Cell:
display:table-cell with float:none
This works fine, but now the requirement is, that only the last div should become vertical bottom aligned. (see attachment 2):
Anyways, I couldn't manage it, since display table cell and vertical-align:top on the left and right div doesn't allow me to vertical align bottom.
I also tried to use position absolute on the last div, but I can't know if the variable height of the div is bigger in the left or in the right div
thanks for your help!
flexbox can do that quite easily
* {
box-sizing: border-box;
}
.wrap {
width: 80%;
margin: 5vh auto;
border: 1px solid grey;
display: flex;
}
.col {
display: flex;
flex-direction: column;
flex: 1;
border: 1px solid green;
padding: 1em;
margin: 1em;
}
.left,
.right {
flex: 2;
/* just a number...means they are twice as wide as the middle */
}
.middle {
justify-content: center;
}
header {
flex: 0 0 25px;
background: red;
margin-bottom: 1em;
}
nav {
flex: 0 0 35px;
background: blue;
margin-bottom: 1em;
}
.content {
flex: 0 0 auto;
background: orange;
margin-bottom: 1em;
}
footer {
height: 50px;
background: green;
width: 50px;
align-self: flex-end;
width: 100%;
margin-top: auto;
}
<div class="wrap">
<div class="col left">
<header></header>
<nav></nav>
<div class="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab, impedit. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cupiditate cum magnam maiores unde consequuntur, similique deserunt delectus omnis expedita in, laborum praesentium consequatur
eius adipisci saepe rerum reprehenderit nostrum temporibus.</div>
<footer></footer>
</div>
<div class="col middle">
<div class="content">Lorem ipsum dolor sit amet.</div>
</div>
<div class="col right">
<header></header>
<nav></nav>
<div class="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellendus, modi!</div>
<footer></footer>
</div>
</div>
I would do this with flexbox: http://codepen.io/pjetr/pen/KpYzqj
div { display: flex; }
/* I was required to add some code, to accompany the codepen link :) */
but remember to check this: http://caniuse.com/#feat=flexbox

Categories

Resources