1

Good day.

I have the following task: I want to build a grid of cards (for example - news), which will keep their proportions with a change of browser's width. For this reason I decided to use aspect-ratio hack for setting card's height (setting padding-top).

This solution works fine for cards with the same width. But my design uses ordinary cards and double.

I chose the "desktop-first" strategy. So my goal is to save cards' proportions with start height - 300px.

So, in my design, I have ordinary card with start size: width: 380px and height: 300px. And double card with start size: width: 780px and height: 300px.

For each case I counted the values for padding-top. For ordinary card: 300/380 = 0,7894736842105263, so padding-top: 78.94836842105263%. For double card: 300/780 = 0,3846153846153846, so padding-top: 38.46153846153846%.

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

body {
  font-family: sans-serif;
  background-color: #f0f0f0;
  color: #323232;
}

.container {
  max-width: 1600px;
  margin-right: auto;
  margin-left: auto;
  padding-left: 10px;
  padding-right: 10px;
}

.row {
  margin: 0 -10px;
}
.row::before, .row::after {
  display: table;
  content: '';
}
.row::after {
  clear: both;
}

.col {
  float: left;
  width: 100%;
  padding: 0 10px;
}

@media (min-width: 768px) {
  .col--regular {
    width: 50%;
  }
}
@media (min-width: 920px) {
  .col--regular {
    width: 33.3333%;
  }

  .col--doubled {
    width: 66.6666%;
  }
}
@media (min-width: 1220px) {
  .col--regular {
    width: 25%;
  }

  .col--doubled {
    width: 50%;
  }
}
.card {
  position: relative;
  margin-bottom: 20px;
  background-position: center;
  background-size: cover;
}
.card__title {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  padding: 10px;
  font-size: 18px;
  font-weight: 700;
}
.card--regular {
  padding-top: 78.94836842105263%;
}
.card--doubled {
  padding-top: 38.46153846153846%;
}
<div class="container">
    <div class="row">
        <div class="col col--doubled">
            <div class="card card--doubled" style="background-image: url('https://images.unsplash.com/5/unsplash-kitsune-4.jpg?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=bc01c83c3da0425e9baa6c7a9204af81&auto=format&fit=crop&w=1350&q=80');">
                <div class="card__title">
                    Big card title
                </div>
            </div>
        </div>
        <div class="col col--regular">
            <div class="card card--regular" style="background-image: url('https://images.unsplash.com/5/unsplash-kitsune-4.jpg?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=bc01c83c3da0425e9baa6c7a9204af81&auto=format&fit=crop&w=1350&q=80');">
                <div class="card__title">
                    Regular card title
                </div>
            </div>
        </div>
        <div class="col col--regular">
            <div class="card card--regular" style="background-image: url('https://images.unsplash.com/5/unsplash-kitsune-4.jpg?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=bc01c83c3da0425e9baa6c7a9204af81&auto=format&fit=crop&w=1350&q=80');">
                <div class="card__title">
                    Regular card title
                </div>
            </div>
        </div>
        <div class="col col--regular">
            <div class="card card--regular" style="background-image: url('https://images.unsplash.com/5/unsplash-kitsune-4.jpg?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=bc01c83c3da0425e9baa6c7a9204af81&auto=format&fit=crop&w=1350&q=80');">
                <div class="card__title">
                    Regular card title
                </div>
            </div>
        </div>
        <div class="col col--regular">
            <div class="card card--regular" style="background-image: url('https://images.unsplash.com/5/unsplash-kitsune-4.jpg?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=bc01c83c3da0425e9baa6c7a9204af81&auto=format&fit=crop&w=1350&q=80');">
                <div class="card__title">
                    Regular card title
                </div>
            </div>
        </div>
        <div class="col col--regular">
            <div class="card card--regular" style="background-image: url('https://images.unsplash.com/5/unsplash-kitsune-4.jpg?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=bc01c83c3da0425e9baa6c7a9204af81&auto=format&fit=crop&w=1350&q=80');">
                <div class="card__title">
                    Regular card title
                </div>
            </div>
        </div>
    </div>
</div>

But if you look at the working example, you will see that double card has a greater height than regular when we change browser's width. So this breaks the grid.

Please tell me what my mistake is. Or how to solve this situation.

Link to example: https://codepen.io/dimitrysh/pen/jZBOzJ

UPD: developers from https://ru.insider.pro/ managed to achieve such result. Please check this "example".

Thank you in advance!

Dmitry S.
  • 71
  • 1
  • 8
  • 2
    what have you tried so far? Please post the code here – Yashaswi N P Feb 09 '18 at 12:56
  • Questions seeking code help must include the shortest code necessary to reproduce it **in the question itself** preferably in a **Stack Snippet**. Although you have provided a link, if it was to become invalid, your question would be of no value to other future SO users with the same problem. See [**Something in my website doesn't work can I just paste a link**](http://meta.stackoverflow.com/questions/254428/something-in-my-web-site-or-project-doesnt-work-can-i-just-paste-a-link-to-it). – Paulie_D Feb 09 '18 at 12:59
  • but he has provided the code in codepen @Paulie_D – Rupal Feb 09 '18 at 13:02
  • ...and the code should be **in the question** not in a separate link, whether it's Codepen/JSFiddle or whatever. – Paulie_D Feb 09 '18 at 13:03
  • Sorry. I updated my question with code-snippet. – Dmitry S. Feb 09 '18 at 13:13
  • Are you talking about the rounding which results in one pixel difference? The easiest was to avoid that affecting how the columns are laid out, was if you could group them in row elements in the same way you want them displayed - https://codepen.io/anon/pen/PQpqQG – CBroe Feb 09 '18 at 13:16
  • Yes, it's all about the one pixel. I'm afraid that in my case it's impossible to group items in additional rows. – Dmitry S. Feb 09 '18 at 13:21
  • Read more about float values behavior here: https://stackoverflow.com/questions/15300163/how-do-browsers-deal-with-non-integer-values-for-height-and-width – Kiran Dash Feb 09 '18 at 13:21

2 Answers2

0

Interesting question ...

If you want the heights to be exactly equal, you need to calculate them the same way. So, lets make col--doubled the same width than col--regular.

Now, the padding trick wroks the same for both.

The car--doubled will need to have width: 200%. And we need to adjust the spacing, setting an adequate margin to col-doubled.

On a side note: May be you could consider switching to a grid display.

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

body {
  font-family: sans-serif;
  background-color: #f0f0f0;
  color: #323232;
}

.container {
  max-width: 1600px;
  margin-right: auto;
  margin-left: auto;
  padding-left: 10px;
  padding-right: 10px;
}

.row {
  margin: 0 -10px;
}
.row::before, .row::after {
  display: table;
  content: '';
}
.row::after {
  clear: both;
}

.col {
  float: left;
  width: 100%;
  padding: 0 10px;
}

@media (min-width: 768px) {
  .col--regular {
    width: 50%;
  }
}
@media (min-width: 920px) {
  .col--regular {
    width: 33.3333%;
  }

  .col--doubled {
    width: 33.3333%;
    margin-right: 33.33%;
  }
}
@media (min-width: 1220px) {
  .col--regular {
    width: 25%;
  }

  .col--doubled {
    width: 25%;
    margin-right: 25%;
  }
}
.card {
  position: relative;
  margin-bottom: 20px;
  background-position: center;
  background-size: cover;
}
.card__title {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  padding: 10px;
  font-size: 18px;
  font-weight: 700;
}
.card--regular, .card--doubled {
  padding-top: 78.94836842105263%;
}

.card--doubled {
   width: calc(200% + 20px);
}
<div class="container">
    <div class="row">
        <div class="col col--doubled">
            <div class="card card--doubled" style="background-image: url('https://images.unsplash.com/5/unsplash-kitsune-4.jpg?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=bc01c83c3da0425e9baa6c7a9204af81&auto=format&fit=crop&w=1350&q=80');">
                <div class="card__title">
                    Big card title
                </div>
            </div>
        </div>
        <div class="col col--regular">
            <div class="card card--regular" style="background-image: url('https://images.unsplash.com/5/unsplash-kitsune-4.jpg?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=bc01c83c3da0425e9baa6c7a9204af81&auto=format&fit=crop&w=1350&q=80');">
                <div class="card__title">
                    Regular card title
                </div>
            </div>
        </div>
        <div class="col col--regular">
            <div class="card card--regular" style="background-image: url('https://images.unsplash.com/5/unsplash-kitsune-4.jpg?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=bc01c83c3da0425e9baa6c7a9204af81&auto=format&fit=crop&w=1350&q=80');">
                <div class="card__title">
                    Regular card title
                </div>
            </div>
        </div>
        <div class="col col--regular">
            <div class="card card--regular" style="background-image: url('https://images.unsplash.com/5/unsplash-kitsune-4.jpg?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=bc01c83c3da0425e9baa6c7a9204af81&auto=format&fit=crop&w=1350&q=80');">
                <div class="card__title">
                    Regular card title
                </div>
            </div>
        </div>
        <div class="col col--regular">
            <div class="card card--regular" style="background-image: url('https://images.unsplash.com/5/unsplash-kitsune-4.jpg?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=bc01c83c3da0425e9baa6c7a9204af81&auto=format&fit=crop&w=1350&q=80');">
                <div class="card__title">
                    Regular card title
                </div>
            </div>
        </div>
        <div class="col col--regular">
            <div class="card card--regular" style="background-image: url('https://images.unsplash.com/5/unsplash-kitsune-4.jpg?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=bc01c83c3da0425e9baa6c7a9204af81&auto=format&fit=crop&w=1350&q=80');">
                <div class="card__title">
                    Regular card title
                </div>
            </div>
        </div>
    </div>
</div>
vals
  • 61,425
  • 11
  • 89
  • 138
  • Thank you for your answer. How I can see in your snippet, padding trick works perfect. But I want to clarify: Is this approach (with percentage margins and 200% width) dirty? P.S. Unfortunately in my project I can't use css-grid. P.S.2 I have updated my question with link https://ru.insider.pro/, how did they do it - for regular and doubled cards? Thank you! – Dmitry S. Feb 10 '18 at 14:35
0

I found, as it seems to me, a flexible solution of the problem.

The trick is to use the flexbox module for strings.

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

body {
  font-family: sans-serif;
  background-color: #f0f0f0;
  color: #323232;
}

.container {
  max-width: 1180px;
  margin-right: auto;
  margin-left: auto;
  padding-left: 10px;
  padding-right: 10px;
}

.row {
  margin: 0 -10px;
}
.row::before, .row::after {
  display: table;
  content: '';
}
.row::after {
  clear: both;
}

.col {
  float: left;
  width: 100%;
  padding: 0 10px;
  overflow: hidden;
}
@media (min-width: 768px) {
  .col--regular {
    width: 50%;
  }
}
@media (min-width: 920px) {
  .col--regular {
    width: 33.3333%;
  }
  .col--double {
    width: 66.6666%;
  }
}
@media (min-width: 1220px) {
  .col--regular {
    width: 25%;
  }
  .col--double {
    width: 50%;
  }
}

.card {
  position: relative;
  margin-bottom: 20px;
  background-position: center;
  background-size: cover;
  background-image: url("https://images.unsplash.com/5/unsplash-kitsune-4.jpg?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=bc01c83c3da0425e9baa6c7a9204af81&auto=format&fit=crop&w=1350&q=80");
  overflow: hidden;
}
.card__title {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  padding: 10px;
  font-size: 18px;
  font-weight: 700;
}
.card--regular {
  padding-top: 78.94836842105263%;
}
.card--double {
  padding-top: 38.46153846153846%;
}

.flex-container {
  width: 100%;
}
.flex-container .flex-row {
  width: 100%;
  display: flex;
  justify-content: flex-start;
  align-items: stretch;
  flex-wrap: wrap;
}
<div class="container flex-container">
    <div class="row flex-row">
        <div class="col col--double">
            <div class="card card--double">
                <div class="card__title">
                    Big card title
                </div>
            </div>
        </div>
        <div class="col col--regular">
            <div class="card card--regular">
                <div class="card__title">
                    Regular card title
                </div>
            </div>
        </div>
        <div class="col col--regular">
            <div class="card card--regular">
                <div class="card__title">
                    Regular card title
                </div>
            </div>
        </div>
        <div class="col col--regular">
            <div class="card card--regular">
                <div class="card__title">
                    Regular card title
                </div>
            </div>
        </div>
        <div class="col col--regular">
            <div class="card card--regular">
                <div class="card__title">
                    Regular card title
                </div>
            </div>
        </div>
        <div class="col col--regular">
            <div class="card card--regular">
                <div class="card__title">
                    Regular card title
                </div>
            </div>
        </div>
    </div>
</div>

Pay attention to css-classes flex-container, flex-row.

Thus we will stretch the cards according to the height of the highest card.

Dmitry S.
  • 71
  • 1
  • 8