Skip to content

The Card Was Square, the Wrapper Wasn't

Adityo Guni Waluyo

The output card was already square at xl, but the panel still looked like a box in a box; the wrapper's padding and gap had to go too.

TL;DR

The chat center panel card was already square, yet a thin white strip and sidebar gaps remained. The wrapper still carried xl:p-4 and default gap-4, so the one-line fix was xl:p-0 xl:gap-0 on the parent. Lesson: a wrong-looking element isn't always the wrong one; match child resets with parent spacing resets at the same breakpoint.

I'd already made the workspace chat center panel square in the previous commit: xl:rounded-none and xl:border-0 on the output card. Border gone, rounding gone. But when I looked at the result at the xl breakpoint again, the panel still wasn't truly flush. A thin white strip around the card, plus spacing before the left and right sidebars.

A borderless box that still looks like a box inside a box.

My first guess was wrong: I figured the card wasn't square yet and some class had slipped through. I opened AiChatWorkspace.tsx again and read the card's className one by one. All there. The card was square.

What was still sticking turned out to be the wrapper. The center column wrapper was still carrying xl:p-4 from before, and the flex column still had the default gap-4. So the card was square, but it was sitting inside a wrapper with its own padding, and there was still a gap at the joints with the two sidebars. The full bleed failed not because of the card, but because the space in its parent didn't get removed along with it.

The fix is one line, in the parent:

- <div className="order-1 flex min-w-0 flex-1 flex-col gap-4 ... xl:p-4">
+ <div className="order-1 flex min-w-0 flex-1 flex-col gap-4 ... xl:gap-0 xl:p-0">

Why this makes sense: p-4 is the utility for setting padding on all four sides of an element [1]. gap is for setting the distance between children in a flex layout [2], and MDN notes this property controls the gaps, or gutters, between rows and columns in flex, grid, and multi-column containers [3]. Both of them work on the wrapper. Padding decides the space inside the wrapper, gap decides the distance between its children. Border and radius belong to the card; the spacing around it belongs to the parent. Removing the border on the child only fixes half the problem.

From this I picked up a new habit: a square utility on the child is a promise the parent has to pay off. If I spot xl:border-0 xl:rounded-none on a component, I immediately go find the parent and add xl:p-0 xl:gap-0 at the same breakpoint, as a pair. I could make a dedicated class like full-bleed to make the intent explicit, but for one usage in one file, I'd rather just drop two utilities into the className. Everything visible in one place, no jumping around to find a definition.

After commit 966844c went in, the center panel finally went edge to edge between the two sidebars and its height lines up with the shell. One line. What I take away from this case isn't the utility name, it's the location: the element that looks wrong isn't always the one that's wrong. Sometimes what needs changing is the wrapper.

Sources

Related articles