Skip to content

Commit 18cfd85

Browse files
committed
Lint and prettify, add package.json
1 parent 241151d commit 18cfd85

File tree

7 files changed

+1479
-118
lines changed

7 files changed

+1479
-118
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
node_modules/
12
.DS_Store
3+
*.min.js

LICENSE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
66

77
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
88

9-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
9+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE

README.md

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,86 @@
11
# `masonry-component`
22

3-
`masonry-component` is a lightweight, zero-dependencies [Web Component](https://developer.mozilla.org/en-US/docs/Web/API/Web_components) which allows you to display a bunch of images of different sizes in a 'masonry' style grid.
3+
`masonry-component` is a lightweight, zero-dependencies [Web Component](https://developer.mozilla.org/en-US/docs/Web/API/Web_components) which allows you to display a bunch of images of different sizes in a 'masonry' style grid.
44

55
<p align="center"><a href='https://htmlpreview.github.io/?https://raw.githubusercontent.com/chrishow/masonry-component/main/index.html' target=_blank'>Simple demo here</a></p>
66

7+
## Benefits
78

9+
- **👼 Super simple**: just one javascript file
10+
- **🤏 Really small**: 6.5k unzipped, 1.5k stripped and zipped
11+
- **🏃 Super fast**: No recalculation on resize (unless you change the number of columns, when it will happen automatically)
12+
- **🔧 Configurable with CSS**: Uses CSS vars to configure, so is easy to use in responsive pages
813

9-
## Benefits
14+
## How to use
15+
16+
Include the javascript:
17+
18+
```javascript
19+
<script src="path/to/masonry-component.js"></script>
20+
```
1021

11-
- **👼 Super simple**: just one javascript file
12-
- **🤏 Really small**: 6.5k unzipped, 1.5k stripped and zipped
13-
- **🏃 Super fast**: No recalculation on resize (unless you change the number of columns, when it will happen automatically)
14-
- **🔧 Configurable with CSS**: Uses CSS vars to configure, so is easy to use in responsive pages
15-
16-
## How to use
17-
Include the javascript:
18-
```javascript
19-
<script src='path/to/masonry-component.js'></script>
20-
```
2122
Add the HTML:
23+
2224
```html
2325
<masonry-component>
24-
<img src='https://picsum.photos/600/300' width=600 height=300>
25-
<img src='https://picsum.photos/600/500' width=600 height=500>
26-
<img src='https://picsum.photos/600/200' width=600 height=200>
27-
<img src='https://picsum.photos/600/300' width=600 height=300>
28-
...
26+
<img src="https://picsum.photos/600/300" width="600" height="300" />
27+
<img src="https://picsum.photos/600/500" width="600" height="500" />
28+
<img src="https://picsum.photos/600/200" width="600" height="200" />
29+
<img src="https://picsum.photos/600/300" width="600" height="300" />
30+
...
2931
</masonry-component>
3032
```
31-
.. and that's it.
33+
34+
.. and that's it.
3235

3336
## Configuration
34-
There are two options, the number of columns, and the gap between the items. These are both controlled using CSS custom properties, so can be specified in your CSS, HTML (or both).
37+
38+
There are two options, the number of columns, and the gap between the items. These are both controlled using CSS custom properties, so can be specified in your CSS, HTML (or both).
39+
3540
```css
3641
masonry-component {
37-
--masonry-gap: 10px;
38-
--masonry-column-count: 3;
42+
--masonry-gap: 10px;
43+
--masonry-column-count: 3;
3944
}
4045
```
46+
4147
`masonry-gap` can be specified in pretty much any unit (`px`, `rem`, `em`, `vw`). Technically, it can be any unit that works as a `margin-bottom`, so percentage units are not supported.
4248

4349
This makes it super easy to change the number of columns at smaller widths, eg:
50+
4451
```css
4552
masonry-component {
46-
--masonry-gap: 10px;
47-
--masonry-column-count: 3;
48-
49-
@media (max-width: 800px) {
50-
--masonry-column-count: 3;
51-
}
53+
--masonry-gap: 10px;
54+
--masonry-column-count: 3;
55+
56+
@media (max-width: 800px) {
57+
--masonry-column-count: 3;
58+
}
5259
}
5360
```
54-
Recalculation will happen automatically when the window width changes to match the media query.
61+
62+
Recalculation will happen automatically when the window width changes to match the media query.
5563

5664
## Advanced usage
65+
5766
If you don't know the dimensions of your images so can't add `width` and `height` attributes to the image tags, you will want to trigger a re-layout as the images load. You can do this at any time by calling the `layout` method on the component:
67+
5868
```javascript
59-
document.querySelector('masonry-component').layout();
69+
document.querySelector("masonry-component").layout();
6070
```
71+
6172
To automatically trigger as each of the images load, you can do this:
73+
6274
```javascript
63-
document.querySelectorAll('masonry-layout img').forEach(
64-
(img) => {img.onLoad = ()=> img.closest('masonry-layout').layout()}
65-
);
75+
document.querySelectorAll("masonry-layout img").forEach((img) => {
76+
img.onLoad = () => img.closest("masonry-layout").layout();
77+
});
6678
```
79+
6780
## Licence
68-
Licen[c|s]e is [MIT](https://opensource.org/license/mit/), you can do what pretty much you want with it.
81+
82+
Licen[c|s]e is [MIT](https://opensource.org/license/mit/), you can do what pretty much you want with it.
6983

7084
## Credits
85+
7186
`masonry-component` was written by [Chris How](https://github.com/chrishow/), based on [andreasbm/masonry-layout](https://github.com/andreasbm/masonry-layout)

index.html

Lines changed: 64 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,66 @@
11
<!DOCTYPE html>
22
<html lang="en">
3-
<head>
4-
<meta charset="UTF-8">
5-
<title>Masonry Component</title>
6-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7-
<link rel="preconnect" href="https://fonts.googleapis.com">
8-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9-
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@200&display=swap" rel="stylesheet">
10-
11-
<style>
12-
body {
13-
font-family: 'Inter', sans-serif;
14-
}
15-
masonry-component {
16-
--masonry-gap: 1vw;
17-
--masonry-column-count: 4;
18-
19-
@media (max-width: 950px) {
20-
--masonry-gap: 1em;
21-
--masonry-column-count: 3;
22-
}
23-
24-
25-
@media (max-width: 800px) {
26-
--masonry-gap: 10px;
27-
--masonry-column-count: 2;
28-
}
29-
30-
}
31-
32-
</style>
33-
34-
<script src="masonry-component.js"></script>
35-
</head>
36-
<body>
37-
<noscript>
38-
<p>Please enable Javascript in your browser.</p>
39-
</noscript>
40-
41-
<h1>Responsive Masonry Component</h1>
42-
43-
<masonry-component></masonry-component>
44-
45-
<script>
46-
let imageHeight;
47-
let image;
48-
let i;
49-
50-
const $masonry = document.querySelector('masonry-component');
51-
52-
53-
for(i = 0; i < 25; i++) {
54-
imageHeight = Math.floor(Math.random() * 500) + 200;
55-
56-
image = document.createElement('img');
57-
image.setAttribute('loading', 'lazy');
58-
image.setAttribute('width', '600');
59-
image.setAttribute('height', imageHeight);
60-
image.setAttribute('src', `https://picsum.photos/600/${imageHeight}`);
61-
$masonry.appendChild(image);
62-
}
63-
64-
$masonry.layout();
65-
</script>
66-
67-
</body>
68-
</html>
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>Masonry Component</title>
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<link rel="preconnect" href="https://fonts.googleapis.com" />
8+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9+
<link
10+
href="https://fonts.googleapis.com/css2?family=Inter:wght@200&display=swap"
11+
rel="stylesheet"
12+
/>
13+
14+
<style>
15+
body {
16+
font-family: "Inter", sans-serif;
17+
}
18+
masonry-component {
19+
--masonry-gap: 1vw;
20+
--masonry-column-count: 4;
21+
22+
@media (max-width: 950px) {
23+
--masonry-gap: 1em;
24+
--masonry-column-count: 3;
25+
}
26+
27+
@media (max-width: 800px) {
28+
--masonry-gap: 10px;
29+
--masonry-column-count: 2;
30+
}
31+
}
32+
</style>
33+
34+
<script src="masonry-component.js"></script>
35+
</head>
36+
<body>
37+
<noscript>
38+
<p>Please enable Javascript in your browser.</p>
39+
</noscript>
40+
41+
<h1>Responsive Masonry Component</h1>
42+
43+
<masonry-component></masonry-component>
44+
45+
<script>
46+
let imageHeight;
47+
let image;
48+
let i;
49+
50+
const $masonry = document.querySelector("masonry-component");
51+
52+
for (i = 0; i < 25; i++) {
53+
imageHeight = Math.floor(Math.random() * 500) + 200;
54+
55+
image = document.createElement("img");
56+
image.setAttribute("loading", "lazy");
57+
image.setAttribute("width", "600");
58+
image.setAttribute("height", imageHeight);
59+
image.setAttribute("src", `https://picsum.photos/600/${imageHeight}`);
60+
$masonry.appendChild(image);
61+
}
62+
63+
$masonry.layout();
64+
</script>
65+
</body>
66+
</html>

masonry-component.js

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
"use strict";
22

3-
const COL_COUNT_CSS_VAR_NAME = '--masonry-column-count';
3+
const COL_COUNT_CSS_VAR_NAME = "--masonry-column-count";
44
const DEFAULT_COL_COUNT = 3;
55

6-
const GAP_CSS_VAR_NAME = '--masonry-gap';
6+
const GAP_CSS_VAR_NAME = "--masonry-gap";
77
const DEFAULT_GAP_PX = 10;
88

99
// https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
1010
const ELEMENT_NODE_TYPE = 1;
1111

12-
1312
const $template = document.createElement("template");
1413
$template.innerHTML = `
1514
<style>
@@ -72,10 +71,10 @@ class MasonryComponent extends HTMLElement {
7271
connectedCallback() {
7372
window.addEventListener("resize", this.onResize);
7473

75-
// 'sizer' element is used to measure gap so it can be specified
74+
// 'sizer' element is used to measure gap so it can be specified
7675
// in rem, em, vw, px
77-
this.$sizer = document.createElement('div');
78-
this.$sizer.setAttribute('id','sizer');
76+
this.$sizer = document.createElement("div");
77+
this.$sizer.setAttribute("id", "sizer");
7978
this.shadowRoot.appendChild(this.$sizer);
8079

8180
this.renderedColumnCount = 0;
@@ -98,12 +97,11 @@ class MasonryComponent extends HTMLElement {
9897

9998
onResize() {
10099
// If the number of columns haven't changed, no need to relayout
101-
if(this.renderedColumnCount !== this.columnCount) {
100+
if (this.renderedColumnCount !== this.columnCount) {
102101
this.layout();
103102
}
104103
}
105104

106-
107105
layout() {
108106
const colCount = this.columnCount;
109107
// console.log(`Laying out ${colCount} columns`);
@@ -114,7 +112,9 @@ class MasonryComponent extends HTMLElement {
114112
// const gap = this.gap;
115113
const gap = this.gap;
116114

117-
const $elements = Array.from(this.children).filter(node => node.nodeType === ELEMENT_NODE_TYPE);
115+
const $elements = Array.from(this.children).filter(
116+
(node) => node.nodeType === ELEMENT_NODE_TYPE
117+
);
118118
// console.log($elements);
119119

120120
// An array that keeps track of the highest col height.
@@ -126,7 +126,6 @@ class MasonryComponent extends HTMLElement {
126126
// Go through all elements and figure out what column (aka slot) they should be put in.
127127
// We only do reads in this for loop and postpone the writes
128128
for (const $elem of $elements) {
129-
130129
// Read the height of the element
131130
const height = $elem.getBoundingClientRect().height;
132131

@@ -156,9 +155,9 @@ class MasonryComponent extends HTMLElement {
156155
}
157156

158157
/**
159-
* Render X amount of columns.
160-
* @param colCount
161-
*/
158+
* Render X amount of columns.
159+
* @param colCount
160+
*/
162161
renderCols(colCount) {
163162
// Get the current columns
164163
const $columns = this.columns;
@@ -175,7 +174,6 @@ class MasonryComponent extends HTMLElement {
175174

176175
// Add some new columns
177176
for (let i = 0; i < colCount; i++) {
178-
179177
// Create a column element
180178
const $column = document.createElement(`div`);
181179
$column.classList.add(`column`);
@@ -199,8 +197,10 @@ class MasonryComponent extends HTMLElement {
199197
}
200198

201199
get columnCount() {
202-
let currentColCount = this.masonryComputedStyle.getPropertyValue(COL_COUNT_CSS_VAR_NAME);
203-
if(!currentColCount) {
200+
let currentColCount = this.masonryComputedStyle.getPropertyValue(
201+
COL_COUNT_CSS_VAR_NAME
202+
);
203+
if (!currentColCount) {
204204
currentColCount = DEFAULT_COL_COUNT;
205205
}
206206

@@ -213,8 +213,8 @@ class MasonryComponent extends HTMLElement {
213213
get gap() {
214214
// Meaasure sizer element to get pixel size
215215
const calculatedGap = this.$sizer.clientWidth;
216-
return calculatedGap;
217-
}
216+
return calculatedGap;
217+
}
218218

219219
findSmallestColIndex(colHeights) {
220220
let smallestIndex = 0;

0 commit comments

Comments
 (0)