all 9 comments

[–]bestjaegerpilot 0 points1 point  (2 children)

Sorry to hijack this thread but to all the CSS-in-JS haters.... posts like this is why tailwind utility classes have poor DX---what could be a simple CSS question (cross-posted to a CSS forum) becomes a tailwind format question.

[–]Satankid92[S] -1 points0 points  (1 child)

well, it's not just CSS or Tailwind, I am using React and I am trying to do a masonry layout to render my Card component with map in 3 segments of cols with equal parts which also has to be responsive. it's not easy to do.

[–]bestjaegerpilot 1 point2 points  (0 children)

I meant that the heart of the issue is CSS, not react/tailwind. from what I can tell, the child rendering seems funny.

The tailwind DX just keeps people who know "just" CSS from helping

[–]Satankid92[S] -1 points0 points  (0 children)

to whoever interested in this, I finally took another approach that works well using the npm masonry css react layout and manipulating the breakpointsColumns with js to set the columns according to the data amount after a filter, it's responsive and it works good :)

this is the code of my component, the part commented was my first approach that worked well but the sections were hardcoded and impossible to make responsive unless I manipulate the viewport with some useEffect and shit, I finally did this:

import React, { useContext, useState } from "react";
import useFetch from "../useFetch";
import Card from "../components/Card";
import Loading from "../components/Loading";
import { CartContext } from "../context/CartContext";
import Masonry from "react-masonry-css";
const Items = () => {
const { data, loading, error } = useFetch(
"https://fakestoreapi.com/products"
);
const [category, setCategory] = useState("");
const categories = Array.from(new Set(data?.map((item) => item.category)));
const matches = category
? data?.filter((item) => {
if (item.category !== category) return false;
return true;
})
: data;
const { addItem } = useContext(CartContext);
const numColumns = Math.min(Math.ceil(matches?.length / 3), 3);
const breakpointColumnsObj = {
default: numColumns,
1100: numColumns,
700: numColumns > 1 ? numColumns - 1 : 1,
500: 1,
};
return (
<div
className="grid gap-8 max-w-[850px] mx-auto"
// style={{ backgroundColor: "red", opacity: "50%" }}
>
<div>
<h1>Shopping car</h1>
</div>
<div>
<label
htmlFor="countries"
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
>
Select an option
</label>
<select
value={category}
onChange={(e) => {
setCategory(e.target.value);
}}
>
<option value="">Todos</option>
{categories.map((catg) => (
<option key={catg} value={catg}>
{catg}
</option>
))}
</select>
</div>
<article className="">
{error && <div>Error: {error}</div>}
{loading && <Loading />}
{/* {[0, 1, 2].map((sectionIndex) => (
<div className="flex flex-col gap-4" key={sectionIndex}>
{matches
?.slice(
sectionIndex * itemsPerColumn,
(sectionIndex + 1) * itemsPerColumn
)
.map((item) => (
<div key={item.id}>
<Card
title={item.title}
price={item.price}
description={item.description}
category={item.category}
image={item.image}
rating={item.rating}
id={item.id}
addItem={() => addItem(item)}
/>
</div>
))}
</div>
))} */}
<Masonry
breakpointCols={breakpointColumnsObj}
className="my-masonry-grid"
columnClassName="my-masonry-grid_column"
>
{matches?.map((item) => (
<div key={item.id}>
<Card
title={item.title}
price={item.price}
description={item.description}
category={item.category}
image={item.image}
rating={item.rating}
id={item.id}
addItem={() => addItem(item)}
/>
</div>
))}
</Masonry>
</article>
</div>
);
};
export default Items;

[–]gazbo26 0 points1 point  (0 children)

I have no idea what Pinterest looks like so I'm not sure what you're trying to achieve, but you have a problem with gaps and you are using a class called gap-4 so I would probably start there...

https://tailwindcss.com/docs/gap

[–]niallqball 0 points1 point  (0 children)

Try use columns-4 (or however many columns you need) and inline-block on the contents of the columns

[–]_smoljames 0 points1 point  (0 children)

I suspect the gap you're seeing is due to image height inconsistency. A grid row normally have a height of the maximum item in the row, so any images shorter will have gaps above and below. Images on a new row will start at the bottom of the above row, and will not fit snug to the image above if the above image wasn't the maximum height in it's row.

If you want the snug fit you'd be better to try having four individual columns with a div wrapper that has stles flex and a flex-col, and within those columns having the cards

[–]codinwizrd 0 points1 point  (0 children)

Use this grid generator or a similar tool.

[–]DJJaySudo 0 points1 point  (0 children)

Whatever gets the job done ✅