0

I want to make a 3 x 6 matrix. I used flexbox and all the flexItems have a flex-basis of 1/6.

At full screen, its how I want it. However, if you make it a smaller screen it starts to wrap. I don't want to break the 3 x 6

https://codesandbox.io/s/vibrant-spence-gski65

import "./styles.css";
import React, { useState } from "react";

const gridValues = new Array(18).fill(0);

export default function App() {
  const [grid, setGrid] = useState<number[]>(gridValues);

  return (
    <div
      style={{
        width: "90%",
        height: "100%"
      }}
    >
      <div
        style={{
          display: "flex",
          flexWrap: "wrap",
          padding: "16px"
        }}
      >
        {grid.map((num, i) => {
          return (
            <span
              key={i}
              style={{
                display: "flex",
                flexBasis: "16.666%",
                cursor: "pointer",
                justifyContent: "center",
                padding: "16px",
                border: "1px solid black",
                flexShrink: 0
              }}
            >
              <span style={{ opacity: 0 }}>{num}</span>
            </span>
          );
        })}
      </div>
    </div>
  );
}
user349557
  • 83
  • 1
  • 12
  • **px** is a *fixed unit*, at some point the sum of all paddings will make your flexbox wrap its child elements as they simply no longer fit the `16.666%`. Not even taking the content of the child elements in account. 100 / 16.666 * 2 * 16px would be the minimum size triggering the wrap. – Rene van der Lende Jun 23 '22 at 01:32
  • Even if I did 'calc(1/6 * 100)%', it still wraps. Also, padding is ignored, it's border-box. I could understand why it wraps I guess flex-basis isn't meant to be used like this. I just want to achieve the 3 x 6 matrix with flexbox. – user349557 Jun 23 '22 at 01:38
  • Padding is not ignored, with `border-sizing: border-box` it in fact becomes part of the total element size, as does the `border` size. You cannot simply define 2 * 16px space and assume it won't take away space. `flex-basis` is the proper way to go, but at some point things no longer fit. – Rene van der Lende Jun 23 '22 at 01:45
  • I removed both `padding: 16px` from your *codesandbox* and was able to shrink the `` to `75px` before wrapping took place. For empty cells with a border, that's good enough in my book. – Rene van der Lende Jun 23 '22 at 01:54
  • You would have to send the link so I could view it. (it changes link upon editing) – user349557 Jun 23 '22 at 01:58
  • Sorry, but how hard can it be to remove 2 x `padding: "16px"` from your own code? – Rene van der Lende Jun 23 '22 at 02:01
  • ok ok it works but what if I want the padding? – user349557 Jun 23 '22 at 02:20
  • Not going to work with flexbox unless you get rid of fixed widths and keep the cells empty (i.e., no content). Simple with CSS Grid, though. – Michael Benjamin Jun 23 '22 at 02:26
  • 1
    guess I will go learn CSS grid. Thank you. – user349557 Jun 23 '22 at 02:28
  • 1
    FYI. Related: https://stackoverflow.com/q/29546550/3597276 – Michael Benjamin Jun 23 '22 at 02:31

1 Answers1

0

https://codesandbox.io/s/vibrant-spence-gski65?file=/src/App.tsx

Ended up using CSS grid instead after listening to comment. Definitely much easier

import "./styles.css";
import React, { useState } from "react";

const gridValues = new Array(18).fill(0);

export default function App() {
  const [grid, setGrid] = useState<number[]>(gridValues);

  return (
    <div
      style={{
        width: "90%",
        height: "100%"
      }}
    >
      <div
        style={{
          display: "grid",
          gridTemplateColumns: "1fr 1fr 1fr 1fr 1fr 1fr",
          gridTemplateRows: "1fr 1fr 1fr"
        }}
      >
        {grid.map((num, i) => {
          return (
            <span
              key={i}
              style={{
                display: "flex",
                cursor: "pointer",
                justifyContent: "center",
                padding: "16px",
                border: "1px solid black"
              }}
            >
              <span style={{ opacity: 0 }}>{num}</span>
            </span>
          );
        })}
      </div>
    </div>
  );
}
user349557
  • 83
  • 1
  • 12
  • You are still using the fixed padding of `16px`. Depending on how you plan to implement a responsive design, I think you will need to determine how narrow your padding must be on the smallest device your are aiming to support. I usually use 320x480 or 360x720 and to calculate in and outside spacing of elements. E.g. if you still want 3 columns on 360 devices, then you know that everything in and around a column must stay within `360 / 3 = 120px` per column. I use [linear math](https://codepen.io/renevanderlende/pen/YzEaKvO?editors=0100) to calculate sizes, most other devs use @media queries. – Rene van der Lende Jun 23 '22 at 12:31