Santhosh
Santhosh

Reputation: 91

Complex responsive layout

I have a complex layout design and I want to make it responsive. The problem is I don't know-

  1. How I should approach this design (how to structure the html to achieve this)
    • flex?
    • grid?
    • absolute positioning?
  2. Is it even possible to make this kind of layout without making 2 sets of everything and hiding one of them for desktop and vice versa?

This is the layout that I'm talking about:

Desktop layout

Desktop layout

Mobile layout

Mobile layout

I don't even need the code part for this implementation.

I just need to know if this is possible and if so how do I do that(which structure, what display type for the parent etc) If not, what are the work arounds?

Changing the design is the final resort but i really don't want to do that.

Upvotes: 2

Views: 300

Answers (3)

Santhosh
Santhosh

Reputation: 91

Even though @tao answered this question with an better answer, I'd also like to provide a less "professional" answer but works great.

My answer uses grid-template-areas and media queries. In addition to that, I'm not going to select my own answer as accepted answer(Even though this is what I used in the end)

https://codepen.io/absanthosh/pen/WNRqLYQ?editors=1100

Upvotes: 1

tao
tao

Reputation: 90038

  1. Have the three elements as siblings, in the order you want them displayed on mobile.
  2. Detach the blue element's background from its contents (conceptually) - they are not the same thing.
  3. Render the yellow and blue (transparent on desktop) elements as right column (using grid or flex), while placing the blue background under them (I used the parent's :before) for positioning the background.
  4. I purposefully placed an inline red border on the contents of the blue element, to highlight its position.
  5. You're pretty much done. The rest are implementation details.

I challenge you to do it yourself before looking at the solution below.

Key points of the solution below:

  • Note the required position: relative on the parent and also the position:relative; z-index: 0 on the "right-column" elements (without those rules they're rendered below the :before).
  • I used min-heights here to size the elements (as they're empty) but, once you place content inside them, you could/should remove the min-heights.
  • You'll probably need to adjust the margins/paddings to suit your needs, once you place real content inside them, but that should be fairly straight-forward.

Here it is:

body {
  margin: 0;
}

* {
  box-sizing: border-box;
}

.red {
  background-color: #ff8584;
  padding: 1rem;
}

.yellow {
  background-color: #fff742;
}

.green {
  background-color: #c0ff72;
}

.blue {
  background-color: #72ccff;
}

.red>* {
  min-height: 100px;
  margin-bottom: 1rem;
}

.red>*:last-child {
  margin-bottom: 0;
}

@media (min-width: 768px) {
  .red {
    position: relative;
    display: grid;
    grid-template: 'green yellow' auto 'green blue' 1fr / 1fr 1fr;
    min-height: 100vh;
    grid-column-gap: 1rem;
  }
  .red:before {
    content: '';
    position: absolute;
    background-color: #72ccff;
    top: 1rem;
    right: 1rem;
    bottom: 1rem;
    left: calc(50% + .5rem);
  }
  .red>* {
    margin-bottom: 0;
  }
  .yellow {
    margin: 1rem 1rem 0;
    grid-area: yellow;
  }
  .green {
    grid-area: green;
  }
  .blue {
    grid-area: blue;
  }
  .yellow,
  .blue {
    position: relative;
    z-index: 0;
  }
  .blue {
    background-color: transparent;
  }
}
<div class="red">
  <div class="yellow"></div>
  <div class="green"></div>
  <div class="blue" style="border: 1px solid red"></div>
</div>

I also wrote an SCSS version, making the background properties @mixins and the $spacer a variable, so they could be easily replaced.

Upvotes: 3

Johannes
Johannes

Reputation: 67748

I suppose what you could do is:

In the HTML code make the order of elements yellow-green-blue, all three as siblings and direct children of red.

For the mobile version there will be no position settings necessary, no flex or anything, just regular divs with default (= full) width, with some padding and margins.

For the desktop version make green and blue inline-blocks, with a little less than 50% width, all taking into account according paddings and margins. Apply position: relative to red and position: absolute to yellow, which gets a width of around 45% (again, depending on paddings and margins) and a right setting that places it where you want it (as a percentage value). The top setting for yellow depends on the padding/margins of red and blue.

Upvotes: 0

Related Questions