bruce
bruce

Reputation: 463

CSS alignment - card height shrinks when another card is added to the page

I am designing a website and can't get one of the card to be aligned correctly.

Here is a Codesandbox link with the full HTML and CSS : Link

The expected layout should be like this:

enter image description here

My last attempt ended with this layout : The issues I'm facing are:

  1. I can't get Content Area 2 to stay the same height as Content Area 3, Content Area 4 when I add another Content Area.

  2. Content Area 2 should only grow in height not get smaller to fit another Content Area

  3. The width of Content Area 2 isn't correct as well.

enter image description here

Here is how it when I add another content area.

enter image description here

<div class="grid-container">
  <header class="header">
    <div class="header__search">Main header</div>
  </header>
  <main class="main">
   <h3>Tabs</h3>
    <div class="overviewcard">
        <div class="overviewcard__icon">Filter(collapsed)</di>
      </div>
      <div class="main-header">
      <div class="header__search">Content Area 1</div>
    </div>
    <div >
    </div>
    <div class="main-cards">
      <div class="card">Content Area 2</div>
      <div class="card">Content Area 3</div>
      <div class="card">Content Area 4</div>
    </div>
  </main>
</div>

Any help is appreciated. A flexbox or CSS grid solution is fine

Upvotes: 0

Views: 1008

Answers (2)

somdev
somdev

Reputation: 186

Not sure what you want it to look like on mobile vs. desktop, but assuming the goal layout you provided is desktop, here's a CSS Grid solution:

body {
  margin: auto;
  padding: auto;
  color: blue;
  font-family: "Open Sans", Helvetica, sans-serif;
  box-sizing: border-box;
}
/* Assign grid instructions to our parent grid container, mobile-first (hide the sidenav) */
.grid-container {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 50px 1fr 50px;
  grid-template-areas:
    "header"
    "main"
    "footer";
  height: 100vh;
}
.menu-icon {
  position: fixed; /* Needs to stay visible for all mobile scrolling */
  display: flex;
  top: 5px;
  left: 10px;
  align-items: center;
  justify-content: center;
  background-color: #dadae3;
  border-radius: 50%;
  z-index: 1;
  cursor: pointer;
  padding: 12px;
}
/* Give every child element its grid name */
.header {
  grid-area: header;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 6px;
  background-color: #648ca6;
}
/* Make room for the menu icon on mobile */
.header__search {
  margin-left: 42px;
}
.main {
  grid-area: main;
  background-color: #eaeaea;
}
.main-header {
  display: flex;
  justify-content: space-between;
  margin: 20px;
  padding: 20px;
  height: 150px;
  background-color: #e3e4e6;
  color: slategray;
}
.main-overview {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(265px, 1fr));
  grid-auto-rows: 94px;
  grid-gap: 20px;
  margin: 20px;
}
.overviewcard {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px;
  background-color: #d3d3;
}
.main-cards {
  display: grid;
  grid-template-columns: 1fr;
  grid-gap: 20px;
  margin: 20px;
}
.card {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  background-color: #82bef6;
  -webkit-column-break-inside: avoid;
  padding: 24px;
  box-sizing: border-box;
}
/* Force varying heights to simulate dynamic content */
.card:first-child {
  grid-row: 1 / -1;
}
/* Medium screens breakpoint (1050px) */
@media only screen and (min-width: 65.625em) {
  /* Break out main cards into two columns */
  .main-cards {
  grid-template-columns: minmax(min-content, 2fr) minmax(min-content, 3fr);
  grid-template-rows: minmax(min-content, 1fr) minmax(min-content, 3fr) minmax(min-content, 2fr);
}
}
<div class="grid-container">
  <header class="header">
    <div class="header__search">Main header</div>
  </header>
  <main class="main">
    <h3>Tabs</h3>
    <div class="overviewcard">
      <div class="overviewcard__icon">Filter(collapsed)</div>
    </div>
    <div class="main-header">
      <div class="header__search">Content Area 1</div>
    </div>
    <div></div>
    <div class="main-cards">
      <div class="card">Content Area 2</div>
      <div class="card">Content Area 3</div>
      <div class="card">Content Area 4</div>
      <div class="card">Content Area 5</div>
    </div>
  </main>
</div>

*Edit: Adding some heavy commenting to the parts I changed to clarify what I did:

    /* Let's not use css columns here. That's basically a very dumbed down version of CSS Grid, wherein all content just stays in the normal flow and splits into columns. Not much flexibility there. Let's use Grid instead to define one column for our mobile layout. The media query below will add columns for larger screens. */
.main-cards {
  display: grid;
  grid-template-columns: 1fr;
  grid-gap: 20px;
  margin: 20px;
}

/* Instead of applying fixed heights to our children, let's let the parent grid take care of the layout. Then all we need to do is assign the first child to start at the beginning of the first row, and go until the end. i.e. full height of the parent. The rest of the children will now fall into the normal flow */
.card:first-child {
  grid-row: 1 / -1;
}

/* Medium screens breakpoint (1050px) */
@media only screen and (min-width: 65.625em) {
  /* Break out main cards into two columns, each going no smaller than its content, but as large as it needs to take up the remaining space. Second column grows at a ratio of 3:2 in comparison to the first */
  .main-cards {
  grid-template-columns: minmax(min-content, 2fr) minmax(min-content, 3fr);

   /* define our 3 rows for content areas 3-5. Same concept applies as the above. This time a ratio of first-second-third is 1:3:2 in regards to the remaining space. */
  grid-template-rows: minmax(min-content, 1fr) minmax(min-content, 3fr) minmax(min-content, 2fr);
}
}

Upvotes: 1

user7148391
user7148391

Reputation:

Here i made a very basic example of which you can work off of, The code is heavily commented.

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

body * {
  padding: 10px;
  border: 1px solid;
}

[grid] {
  display: grid;
  /* this creates 2 columns and 3 column lines */
  /* [line-1] columns [line-2] column [line-3] */
  /* The same is true for rows even if we don't create them*/
  grid-template-columns: 1fr 2fr;
  height: 100vh;
  grid-gap: 10px;
}

[grid]>div:nth-child(1) {
  /* 1/ -1 means take full width */
  grid-column: 1 / -1;
}

[grid]>div:nth-child(2) {
  /* 2 / 4 Start at row line 2 stop at row line 4 */
  /* if you want Content area 2 to span to the */
  /* remaining row just change 4 to 5 */
  grid-row: 2 / 4;
}

[grid]>div:nth-child(3) {
  /* start at column line 2 */
  grid-column: 2;
}

[grid]>div:nth-child(4) {
  /* start at column line 2 */
  grid-column: 2;
}

[grid]>div:nth-child(5) {
  /* start at column line 2 */
  grid-column: 2;
}
<div grid>
  <div>Content Area 1</div>
  <div>Content Area 2</div>
  <div>Content Area 3</div>
  <div>Content Area 4</div>
  <div>Content Area 5</div>
</div>

Upvotes: 1

Related Questions