Skip to content

Commit 35b8209

Browse files
committed
initial commit
0 parents  commit 35b8209

File tree

6 files changed

+717
-0
lines changed

6 files changed

+717
-0
lines changed

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2014 Liam Brummitt
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# jquery.matchHeight.js #
2+
3+
*matchHeight* makes the height of all selected elements exactly equal.
4+
5+
[brm.io/jquery-match-height](http://brm.io/jquery-match-height/)
6+
7+
I needed a more robust version of the common [equal heights](https://www.google.com/search?q=jquery+equal+heights) plugin (that everyone and their grandma has made before).
8+
9+
So matchHeight improves on these by adding features and handling the edge cases where the others tend to fail in practice.
10+
11+
### Demo
12+
13+
See the [jquery.matchHeight.js demo](http://brm.io/jquery-match-height-demo).
14+
15+
[![jquery.matchHeight.js screenshot](http://brm.io/img/content/jquery-match-height/jquery-match-height.png)](http://brm.io/jquery-match-height-demo)
16+
17+
### Features
18+
19+
- row aware, handles floating elements
20+
- responsive, automatically updates on window resize
21+
- handles mixed `padding`, `margin`, `border` values (even if every element has them different)
22+
- accounts for `box-sizing`
23+
- handles images and other media (updates automatically after loading)
24+
- data attributes API
25+
- tested in IE8+, Chrome, Firefox, Chrome Android
26+
27+
### Status
28+
29+
Current version is `v0.5.0`. I've fully tested it and it works well, but if you use it make sure you test fully too.
30+
Please report any [issues](https://github.com/liabru/jquery-match-height/issues) you find.
31+
32+
### Install
33+
34+
[jQuery](http://jquery.com/download/) is required, so include it first.
35+
<br>Download [jquery.matchHeight.js](https://github.com/liabru/jquery-match-height/blob/master/jquery.matchHeight.js) and include the script in your HTML file:
36+
37+
<script src="jquery.matchHeight.js" type="text/javascript"></script>
38+
39+
### Usage
40+
41+
$(elements).matchHeight(byRow);
42+
43+
Where `byRow` is a boolean that enables or disables row detection, default is `true`.<br>
44+
You should apply this on the [DOM ready](http://api.jquery.com/ready/) event.
45+
46+
See the included [test.html](https://github.com/liabru/jquery-match-height/blob/master/test.html) for a working example.
47+
48+
### Data API
49+
50+
Use the data attribute `data-match-height="group-name"` (or `data-mh` shorthand) where `group-name` is an arbitrary string to denote which elements should be considered as a group.
51+
52+
All elements with the same group name will be set to the same height when the page is loaded, regardless of their position in the DOM, without any extra code required.
53+
54+
Note that `byRow` will be enabled when using the data API, if you don't want this then use the above method.
55+
56+
### Examples
57+
58+
$(function() {
59+
$('.item').matchHeight();
60+
});
61+
62+
Will set all elements with the class `item` to the height of the tallest.<br>
63+
If the items are on multiple rows, the items of each row will be set to the tallest of that row.
64+
65+
<div data-mh="my-group">My text</div>
66+
<div data-mh="my-group">Some other text</div>
67+
<div data-mh="my-other-group">Even more text</div>
68+
<div data-mh="my-other-group">The last bit of text</div>
69+
70+
Will set both elements in `my-group` to the same height, then both elements in `my-other-group` to be the same height respectively.
71+
72+
See the included [test.html](https://github.com/liabru/jquery-match-height/blob/master/test.html) for a working example.
73+
74+
### Advanced Usage
75+
76+
There are a few internal properties and functions you should know about:
77+
78+
$.fn.matchHeight._groups
79+
80+
The array that contains all element groups that have had `matchHeight` applied. Used for automatically updating on resize events.<br>
81+
Search and modify this array if you need to remove any groups or elements, for example if you're deleting elements.
82+
83+
$.fn.matchHeight._update()
84+
85+
If you need to manually trigger an update of all currently set equal heights groups, for example if you've modified some content.
86+
87+
88+
$.fn.matchHeight._apply(elements, byRow)
89+
90+
Use the apply function directly if you wish to avoid the automatic update functionality.
91+
92+
### Why not use CSS?
93+
94+
Making robust, responsive equal height columns for _arbitrary content_ is [difficult or impossible](http://filamentgroup.com/lab/setting_equal_heights_with_jquery/) to do with CSS alone (at least without hacks or trickery, in a backwards compatible way).
95+
96+
Note you should probably ensure your layout is still usable if JavaScript is disabled.
97+
98+
### License
99+
100+
jquery.matchHeight.js is licensed under [The MIT License (MIT)](http://opensource.org/licenses/MIT)
101+
<br/>Copyright (c) 2014 Liam Brummitt
102+
103+
This license is also supplied with the release and source code.
104+
<br/>As stated in the license, absolutely no warranty is provided.

jquery.matchHeight.js

+178
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
/**
2+
* jquery.matchHeight.js v0.5.0
3+
* http://brm.io/jquery-match-height/
4+
* License: MIT
5+
*/
6+
7+
(function($) {
8+
9+
$.fn.matchHeight = function(byRow) {
10+
if (this.length <= 1)
11+
return this;
12+
13+
// byRow default to true
14+
byRow = (typeof byRow !== 'undefined') ? byRow : true;
15+
16+
// keep track of this group so we can re-apply later on load and resize events
17+
$.fn.matchHeight._groups.push({
18+
elements: this,
19+
byRow: byRow
20+
});
21+
22+
// match each element's height to the tallest element in the selection
23+
$.fn.matchHeight._apply(this, byRow);
24+
25+
return this;
26+
};
27+
28+
$.fn.matchHeight._apply = function(elements, byRow) {
29+
var $elements = $(elements),
30+
rows = [$elements];
31+
32+
// get rows if using byRow, otherwise assume one row
33+
if (byRow) {
34+
35+
// must first force an arbitrary equal height so floating elements break evenly
36+
$elements.css({
37+
'display': 'block',
38+
'padding-top': '0',
39+
'padding-bottom': '0',
40+
'border-top': '0',
41+
'border-bottom': '0',
42+
'height': '100px'
43+
});
44+
45+
// get the array of rows (based on element top position)
46+
rows = _rows($elements);
47+
48+
// revert the temporary forced style
49+
$elements.css({
50+
'display': '',
51+
'padding-top': '',
52+
'padding-bottom': '',
53+
'border-top': '',
54+
'border-bottom': '',
55+
'height': ''
56+
});
57+
}
58+
59+
$.each(rows, function(key, row) {
60+
var $row = $(row),
61+
maxHeight = 0;
62+
63+
// iterate the row and find the max height
64+
$row.each(function(){
65+
var $that = $(this);
66+
67+
// ensure we get the correct actual height (and not a previously set height value)
68+
$that.css({ 'display': 'block', 'height': '' });
69+
70+
// find the max height (including padding, but not margin)
71+
if ($that.outerHeight(false) > maxHeight)
72+
maxHeight = $that.outerHeight(false);
73+
});
74+
75+
// iterate the row and apply the height to all elements
76+
$row.each(function(){
77+
var $that = $(this),
78+
verticalPadding = 0;
79+
80+
// handle padding and border correctly (required when not using border-box)
81+
if ($that.css('box-sizing') !== 'border-box') {
82+
verticalPadding += parseInt($that.css('border-top-width'), 10) + parseInt($that.css('border-bottom-width'), 10);
83+
verticalPadding += parseInt($that.css('padding-top'), 10) + parseInt($that.css('padding-bottom'), 10);
84+
}
85+
86+
// set the height (accounting for padding and border)
87+
$that.css('height', maxHeight - verticalPadding);
88+
});
89+
});
90+
91+
return this;
92+
};
93+
94+
/*
95+
* _applyDataApi will apply matchHeight to all elements with a data-match-height attribute
96+
*/
97+
98+
$.fn.matchHeight._applyDataApi = function() {
99+
var groups = {};
100+
101+
// generate groups by their groupId set by elements using data-match-height
102+
$('[data-match-height], [data-mh]').each(function() {
103+
var $this = $(this),
104+
groupId = $this.attr('data-match-height');
105+
if (groupId in groups) {
106+
groups[groupId] = groups[groupId].add($this);
107+
} else {
108+
groups[groupId] = $this;
109+
}
110+
});
111+
112+
// apply matchHeight to each group
113+
$.each(groups, function() {
114+
this.matchHeight(true);
115+
});
116+
};
117+
118+
/*
119+
* _update function will re-apply matchHeight to all groups with the correct options
120+
*/
121+
122+
$.fn.matchHeight._groups = [];
123+
124+
$.fn.matchHeight._update = function() {
125+
$.each($.fn.matchHeight._groups, function() {
126+
$.fn.matchHeight._apply(this.elements, this.byRow);
127+
});
128+
};
129+
130+
/*
131+
* bind events
132+
*/
133+
134+
// apply on DOM ready event
135+
$($.fn.matchHeight._applyDataApi);
136+
137+
// update heights on load and resize events
138+
$(window).on('load resize orientationchange', $.fn.matchHeight._update);
139+
140+
/*
141+
* rows utility function
142+
* returns array of jQuery selections representing each row
143+
* (as displayed after float wrapping applied by browser)
144+
*/
145+
146+
var _rows = function(elements) {
147+
var tolerance = 1,
148+
$elements = $(elements),
149+
lastTop = null,
150+
rows = [];
151+
152+
// group elements by their top position
153+
$elements.each(function(){
154+
var $that = $(this),
155+
top = $that.offset().top - parseInt($that.css('margin-top'), 10),
156+
lastRow = rows.length > 0 ? rows[rows.length - 1] : null;
157+
158+
if (lastRow === null) {
159+
// first item on the row, so just push it
160+
rows.push($that);
161+
} else {
162+
// if the row top is the same, add to the row group
163+
if (Math.floor(Math.abs(lastTop - top)) <= tolerance) {
164+
rows[rows.length - 1] = lastRow.add($that);
165+
} else {
166+
// otherwise start a new row group
167+
rows.push($that);
168+
}
169+
}
170+
171+
// keep track of the last row top
172+
lastTop = top;
173+
});
174+
175+
return rows;
176+
};
177+
178+
})(jQuery);

0 commit comments

Comments
 (0)