Harry
Harry

Reputation: 1742

How to align contents in different containers using only css

I am trying to build a Pricing Tablesimilar to one shown below.

on-full-width

Following are my requirements

here is a minimum snippet for my current solution using JS

findTallest = function () {
  var tallestByGroupNum = {}
  $(".item-contents").each(
    function () {
      var grpNum = $(this).parent().attr('data-group-num');
      // !< instead of > to support undefined values
      if (!($(this).height() < tallestByGroupNum[grpNum] )) {
        tallestByGroupNum[grpNum] = $(this).height();
      }
    }
  );

  $(".item-box").height(
    function () {
      return tallestByGroupNum[$(this).attr('data-group-num')];
    }
  );
};

$(window).resize(findTallest);
findTallest();
/* Put your css in here */

.item-box {
  border: 1px solid red;
}
.pricingCard {
  border: 2px solid red;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>



<div class="container">
  <div class="col-xs-6 pricingCard">
    <h1>Free</h1>

    <div class="item-box" data-group-num="1">
      <div class="item-contents">
        Long long long long long long long long long long long long long long long long long description
      </div>
    </div>

    <button class="btn btn-primary">Get Started</button>

    <div class="item-box" data-group-num="2">
      <div class="item-contents">
        <div>Point</div>
        <div>Point</div>
        <div>Point</div>
      </div>
    </div>

    <button class="btn btn-primary">Get Started</button>
  </div>

  <div class="col-xs-6 pricingCard">
    <h1>Premium</h1>

    <div class="item-box" data-group-num="1">
      <div class="item-contents">
        Short description
      </div>
    </div>

    <button class="btn btn-primary">Get Started</button>

    <div class="item-box" data-group-num="2">
      <div class="item-contents">
        <div>Point</div>
        <div>Point</div>
        <div>Point</div>
        <div>Point</div>
        <div>Point</div>
        <div>Point</div>
      </div>
    </div>

    <button class="btn btn-primary">Get Started</button>
  </div>
</div>

To explain the problem, here's the snippet exluding the JS code. Note that the buttons don't align properly as before.

Also the solution suggested in the comments are similar to this only.

/* Put your css in here */

.item-box {
  border: 1px solid red;
}
.pricingCard {
  border: 2px solid red;
  text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>



<div class="container">
  <div class="col-xs-6 pricingCard">
    <h1>Free</h1>

    <div class="item-box" data-group-num="1">
      <div class="item-contents">
        Long long long long long long long long long long long long long long long long long description
      </div>
    </div>

    <button class="btn btn-primary">Get Started</button>

    <div class="item-box" data-group-num="2">
      <div class="item-contents">
        <div>Point</div>
        <div>Point</div>
        <div>Point</div>
      </div>
    </div>

    <button class="btn btn-primary">Get Started</button>
  </div>

  <div class="col-xs-6 pricingCard">
    <h1>Premium</h1>

    <div class="item-box" data-group-num="1">
      <div class="item-contents">
        Short description
      </div>
    </div>

    <button class="btn btn-primary">Get Started</button>

    <div class="item-box" data-group-num="2">
      <div class="item-contents">
        <div>Point</div>
        <div>Point</div>
        <div>Point</div>
        <div>Point</div>
        <div>Point</div>
        <div>Point</div>
      </div>
    </div>

    <button class="btn btn-primary">Get Started</button>
  </div>
</div>

Again to emphasis on the problem here's the comparison enter image description here

Currently I am using javascript to achieve this. I detect the tallest element and then set the height of the parent container to that.

Here the link to the plnkr on my current implmentation is JS.

Can this be done in css alone (using some bootstrap classes).

Upvotes: 5

Views: 935

Answers (2)

vkjgr
vkjgr

Reputation: 4448

With flexbox, I'd do something like this:

* {
  box-sizing: border-box;
}

.pricing {
  background: #eee;
  display: flex;
  flex-direction: column;
  padding: 2em 0;
}
@media (min-width: 48em) {
  .pricing {
    flex-direction: row;
    flex-wrap: wrap;
  }
}
.pricing .block {
  display: flex;
  justify-content: center;
  flex: 1 1 50%;
}
@media (max-width: 48em) {
  .pricing .block {
    flex: 1;
  }
  .pricing .block:nth-child(odd) {
    order: -1;
  }
  .pricing .block:nth-child(2) {
    margin-top: 2em;
  }
}
.pricing header,
.pricing ul {
  background-color: white;
  box-shadow: 0 0 0 1px silver;
  padding: 1em;
  width: 80%;
}
.pricing header {
  display: flex;
  flex-direction: column;
}
.pricing button {
  margin-top: auto;
}

ul {
  margin: 0;
}
ul li {
  margin-left: 1em;
}

h1,
h2 {
  margin: 0.125em 0;
}

button {
  font: inherit;
}
<div class="pricing">
  <div class="block">
    <header>
      <h1>Free</h1>
      <h2>0$</h2>
      <p>short description</p>
      <button>Get Started</button>
    </header>
  </div>
  <div class="block">
    <header>
      <h1>Premium</h1>
      <h2>5$</h2>
      <p>long description long description long description long description long description long description</p>
      <button>Get Started</button>
    </header>
  </div>
  <div class="block">
    <ul>
      <li>Point 1</li>
      <li>Point 2</li>
      <li>Point 3</li>
    </ul>
  </div>
  <div class="block">
    <ul>
      <li>Point 1</li>
      <li>Point 2</li>
      <li>Point 3</li>
      <li>Point 4</li>
      <li>Point 5</li>
      <li>Point 6</li>
      <li>Point 7</li>
    </ul>
  </div>
</div>

Upvotes: 3

hairmot
hairmot

Reputation: 2975

In pure css using bootstrap the only way you are going to achieve this is with two different layouts of these elements. In one you will have your current html - these will be for smaller screen sizes, in the other, you will have a layout where the two top divs are in a row and the two bottom divs are in a row. This will allow the rows to keep the same height. You then use media queries or hidden classes e.g. hidden-md the relevant html. It's not great as it requires duplication of code, but it is a pure css solution.

An example i've put together can be found here jsfiddle - It needs a lot of work with the styling but you can see how the different elements are displayed at different widths just using bootstrap classes.

I also had to make use of flex-box for the the align-items vertical stretching

Upvotes: 0

Related Questions