Match Height

So you want to make your elements the same height, huh?

CSS not cutting it?

Yep, we know.

Basic Example

Flexbox & CSS Grid are amazing tools, but until we get CSS Subgrid you still need JavaScript to match elements across containers.

Match Height makes this as easy as adding a data-match-height attribute.

<h3 data-match-height="heading">My Example Heading</h3>

Person 1

Stuff about person 1.

Person 2

So much stuff about person 2. You wouldn't believe how interesting they are. We could just talk about them all day.

Person With a Long Name

Stuff about person with a long name.

Responsive Example

But how do I turn it off on mobile?

Simple! Add data-match-height-enable to your container element.

<div data-match-height-enable="(min-width: 560px)">
  ...
</div>

Person 1

Stuff about person 1.

Person 2

So much stuff about person 2. You wouldn't believe how interesting they are. We could just talk about them all day.

Person With a Long Name

Stuff about person with a long name.

Grouping Elements

What if I have different groups of elements with the same name? How can I match them separately?

You've got a couple options.

1. Use the data-match-height-group attribute to wrap elements in a more specific group.

<div data-match-height-group="group-1">
  <div><h3 data-match-height="heading"></h3></div>
  <div><h3 data-match-height="heading"></h3></div>
  <div><h3 data-match-height="heading"></h3></div>
</div>
<div data-match-height-group="group-2">
  <div><h3 data-match-height="heading"></h3></div>
  <div><h3 data-match-height="heading"></h3></div>
  <div><h3 data-match-height="heading"></h3></div>
</div>

2. Or, if you need to keep your elements in the same container, add prefixes to your group names.

<div>
  <div><h3 data-match-height="group-1-heading"></h3></div>
  <div><h3 data-match-height="group-1-heading"></h3></div>
  <div><h3 data-match-height="group-1-heading"></h3></div>
  <div><h3 data-match-height="group-2-heading"></h3></div>
  <div><h3 data-match-height="group-2-heading"></h3></div>
  <div><h3 data-match-height="group-2-heading"></h3></div>
</div>

Triggering Updates

If you ever need to force-update elements, call MatchHeight.update().

To help save the planet, you can also limit your update to a specific group of elements.

MatchHeight.update();

// or

MatchHeight.update('.your-elements');

Need to start over? Call MatchHeight.reset().

MatchHeight.reset();

Declarative & Imperative

Big words!

While we recommend using HTML attributes for most cases, sometimes you do need control to programmatically match elements.

For that, we offer MatchHeight.add().

MatchHeight.add('.your-elements');

// or

MatchHeight.add('.your-elements', 'some-group');

Elements are added to a new, unique group by default, but you can also specify a group to add them to.

jQuery-Friendly

We don't require jQuery, but we do love all you jQuery power users out there!

As long as you load jQuery first, we'll add a handy .matchHeight() function just for you.

<script src="jquery.js"></script>
<script src="match-height.js"></script>
<script>
  $('.jquery-elements').matchHeight();
</script>

SPA-Friendly

What's that? You're using the latest and greatest JS frameworks?

Excellent!

To integrate Match Height, just call MatchHeight.reset() when your app mounts...

const app = new Vue({
  el: '#app',
  mounted() {
    MatchHeight.reset();
  },
});

Or use MatchHeight.add() when your components mount...

Vue.component('person', {
  props: ['person'],
  template: `
    <div>
      <h3 v-text="person.name" ref="heading"></h3>
      <img :src="person.image" alt="">
      <p v-text="person.description"></p>
    </div>
  `,
  mounted() {
    this.$nextTick(() => MatchHeight.add(this.$refs.heading, 'person-heading'));
  },
  beforeDestroy() {
    MatchHeight.remove(this.$refs.heading, 'person-heading');
  },
});

Either way, the power is yours!

Debugging

If your powers grow wildly out of control, use MatchHeight.debug() to help get a grip on things.

Just specify a group or element to get all the details...

// Running any of these...

MatchHeight.debug('group-id');
MatchHeight.debug('.your-class');
MatchHeight.debug(element);
MatchHeight.debug(elements);

// will console.log()...

{
  isEnabled: true
  control: div.example
  enable: "(min-width: 560px)"
  disable: null
  groupID: "example-heading"
  group: (3) [h3.example__heading, h3.example__heading, h3.example__heading]
}

And with that, we bid you adieu!

Go forth and match responsibly.

P.S. CSS Subgrid

Keep an eye on CSS Subgrid. When that's supported everywhere, you won't need this plugin anymore!

@media (min-width: 560px) {
  .example {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
  }

  .example__item {
    display: grid;
    grid-template-rows: subgrid;
    grid-row: auto / span 3;
  }
}