Search code examples
htmlcssflexboxoverflow

HTML CSS horizontal and vertical overflow scroll with flexbox gets cut off


Hello I have the following code in a Next-component:

const Canvas: NextPage = () => {

const x: number[] = Array.from(Array(1617).keys());

return (
    <div className={styles.canvas}>
        <div className={styles.canvasPixels}>
            {x.map((number) =>
                <div key={number} className={styles.canvasPixel}></div>
            )}
        </div>
    </div>
);
}

The CSS-code for the Next-component is:

.canvas::-webkit-scrollbar {
  display: none;
}

.canvas {
  background-color: #ffffff;
  width: 100%;
  height: 60vh;
  overflow: scroll;
  border: 8px solid #514e4e;
  outline: 2px solid #000000;
  box-shadow: 3px 8px 10px rgba(0, 0, 0, 0.25);
  -ms-overflow-style: none;
  scrollbar-width: none;
  display: flex;
  align-items: center;
  justify-content: center;
}

.canvasPixels {
  width: 986px;
  min-width: 986px;
  height: 700px;
  min-height: 700px;
  border: 2px solid;
  border-color: #000000;
  display: flex;
  flex-wrap: wrap;
  margin: auto;
  white-space: nowrap;
}

.canvasPixel {
  margin: 0 !important;
  box-shadow: 2px 0 0 0 #87d13c, 0 2px 0 0 #87d13c, 2px 2px 0 0 #87d13c,
    2px 0 0 0 #87d13c inset, 0 2px 0 0 #87d13c inset;
  width: 20px;
  height: 20px;
}

I am trying to center an element (canvasPixels) in the middle of a div (canvas) with flexbox. The problem is that either the vertical side or the horizontal side gets cut off (it depends on the properties) and I can't find a way to fix the problem on both sides. The problem is because of flexbox. If I remove it, I won't have the problem anymore, but the thing (canvasPixels) has to be centered. An example is highlighted on this image (vertical cut-off): vertical cut-off

I have removed the scrollbars but it's the highest scrolling-point in the picture above.

I have searched through stackoverflow but I couldn't find a solution for my case. Some of the URLs that I have used:

Flex cut off border when screen scroll, Scrolling a flexbox with overflowing content


Solution

  • After some try and error I searched for flexbox alternatives and found display table. With display table everything worked fine. Since I couldn't find a proper solution online, I decided to keep this question and post my solution here. My Next-component-code:

    import { NextPage } from 'next';
    import styles from './Canvas.module.css';
    
    const Canvas: NextPage = () => {
    
    const x: number[] = Array.from(Array(49).keys());
    const y: number[] = Array.from(Array(34).keys());
    
    return (
        <div className={styles.canvasBoard}>
            <div className={styles.canvas}>
                <div className={styles.canvasLayout}>
                    <div className={styles.canvasPixels}>
                        {y.map((number) =>
                            <div className={styles.tableRow}>
                                {x.map((number) =>
                                    <div className={styles.tableCell}>
                                        <div key={number} className={styles.canvasPixel}></div>
                                    </div>
                                )}
                            </div>
                        )}
                    </div>
                </div>
            </div>
        </div>
    );
    }
    
    export { Canvas };
    

    My CSS-code:

    .canvasBoard::-webkit-scrollbar {
      display: none;
    }
    
    .canvasBoard {
      background-color: #ffffff;
      width: 100%;
      height: 60vh;
      overflow: scroll;
      border: 8px solid #514e4e;
      outline: 2px solid #000000;
      box-shadow: 3px 8px 10px rgba(0, 0, 0, 0.25);
      -ms-overflow-style: none;
      scrollbar-width: none;
    }
    
    .canvas {
      display: table;
      width: 100%;
      height: 100%;
    }
    
    .canvasLayout {
      display: table-cell;
      vertical-align: middle;
    }
    
    .canvasPixels {
      width: 986px;
      min-width: 986px;
      height: 700px;
      min-height: 700px;
      border: 2px solid;
      border-color: #000000;
      display: table;
      margin: auto;
      padding-right: 2px;
      padding-bottom: 1.5px;
    }
    
    .tableRow {
      display: table-row;
    }
    
    .tableCell {
      display: table-cell;
    }
    
    .canvasPixel {
      margin: 0 !important;
      box-shadow: 2px 0 0 0 #87d13c, 0 2px 0 0 #87d13c, 2px 2px 0 0 #87d13c,
        2px 0 0 0 #87d13c inset, 0 2px 0 0 #87d13c inset;
      width: 20px;
      height: 20px;
    }