CSS Grid / Flex Resize Magic

Viewed 478

I've been spending the last few days trying to understand how CSS flexbox and grid works, and trying to use that knowledge in creating a particular UI, with no luck so far. I'm almost at the point of giving up on it.

The UI looks something like this:

+----------+-----------------------+---------------------+-----------------+
| CANVAS-1 | DIV-3                 | DIV-5               | DIV-7           |
|          |                       |                     |                 |
|          |                       |                     |                 |
|          |                       |                     +-----------------+
|          |                       |                     | DIV-8           |
+----------+-----------------------+---------------------+                 |
| CANVAS-2 | DIV-4                 | DIV-6               |                 |
|          |                       |                     +----------------[4]
|          |                       |                     | DIV-9           |
|          |                       |                     |                 |
|          |                       |                     |                 |
+---------[1]---------------------[2]-------------------[3]----------------+

Ignoring resize capability, I can design this layout without many problems. However, I have to allow resizing as well, and this is where I have failed miserably over the past two weeks now. My constraints are as follows:

  1. The layout should fill the browser window (width: 100vw, height: 100vh).
  2. The two rows in the first three columns should have equal heights.
  3. DIV-8 should have height equal to its content and DIV-7/9 should take up the remaining space equally.
  4. CANVAS-1 and CANVAS-2 should have a width such that aspect ratio of the canvas is maintained (both canvas elements have width="1242" height="2208" attributes defined.
  5. Column #3 and #4 should have an initial width of 300px.

Using a nested grid, I can implement this layout just fine. However, I am also supposed to allow the layout to be resized according to the following rules:

  1. Dragging [1] to the left should shrink both canvases while keeping their aspect ratios unchanged. Dragging right beyond its initial position should not be allowed. Dragging this line should not affect any other grid lines.
  2. Dragging [2] should move the grid line to the left or right, such that minimum width of DIV-3/4 is no less than 400px and that of DIV-5/6 is no less than 200px. Dragging this line should not affect any other grid lines.
  3. Dragging [3] should move the grid line to the left or right, such that minimum width of DIV-5/6 is no less than 200px, and that of DIV-7/8/9 is no less than 400px. Dragging this line should not affect any other grid lines.
  4. Dragging [4] should move the grid lines between DIV-7/8 and DIV-8/9 up or down, such that height of DIV-8 should remain unchanged, and space will be traded between DIV-7 and DIV-9.
  5. DIV-3/4/5/6/7/8/9 should have scrollbars rendered if the content is not completely visible.
  6. All this should be PREFERABLY done in CSS using resize: horizontal/vertical and grid-template-cols: auto/minmax/min-content/max-content etc, without any JavaScript.

Please help me figure out if this is even possible using CSS alone. If not, please point me towards a JavaScript solution to this problem. I've tried and tested a lot of possibilities to achieve this layout using grid and flexboxes, nested up to 3 levels deep, without success. Please help me solve this problem. I'm sure I'll learn new things here. :)

Thanks, Asim

1 Answers

After many hours of trying (unsuccessfully) with CSS alone, I followed @Dai's direction and ventured into JavaScript. I stumbled across this beautiful library Grid Split by Nathan Cahill. I was able to modify my grid slightly by introducing placeholder columns for 2px wide gutters and modifying the CSS to not use auto units (which the library doesn't support at the moment). Hooking it up now allows me to cleanly resize the grid across any vertical or horizontal edge I want.

Thank Nathan (if you come across this post) :)

Related