Skip to content

Commit f748fdf

Browse files
.
1 parent 6a2dd0a commit f748fdf

13 files changed

Lines changed: 365 additions & 3 deletions

File tree

package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,20 @@
1313
},
1414
"dependencies": {},
1515
"devDependencies": {
16+
"@types/node": "^12.12.53",
1617
"@typescript-eslint/eslint-plugin": "^2.34.0",
1718
"@typescript-eslint/parser": "^2.34.0",
18-
"@types/node": "^12.12.53",
19-
"eslint": "^7.11.0",
19+
"eslint": "^7.2.0",
2020
"eslint-config-airbnb": "^18.2.0",
2121
"eslint-config-prettier": "^6.14.0",
22+
"eslint-import-resolver-typescript": "^2.0.0",
2223
"eslint-plugin-import": "^2.22.1",
24+
"eslint-plugin-jsx-a11y": "^6.4.1",
2325
"eslint-plugin-prettier": "^3.1.4",
26+
"eslint-plugin-react": "^7.21.5",
27+
"eslint-plugin-react-hooks": "^4.0.0",
2428
"htmlhint": "^0.14.1",
2529
"prettier": "^2.1.2",
26-
"eslint-import-resolver-typescript": "^2.0.0",
2730
"prettier-eslint": "^11.0.0",
2831
"stylelint": "^13.6.1",
2932
"stylelint-config-prettier": "^8.0.2",
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
:root {
2+
/**
3+
* Just change the scale factor.
4+
*/
5+
--tile-border-size: calc(50px * 1.5);
6+
--tile-gap: calc(10px * 1.5);
7+
--tile-width: calc(100px * 1.5);
8+
--color-tile: #111;
9+
}
10+
11+
/* Just for better looks */
12+
html {
13+
padding: 5%;
14+
}
15+
16+
.container {
17+
position: relative;
18+
width: 50vw;
19+
height: 100vh;
20+
margin: 0 auto;
21+
}
22+
23+
.tile {
24+
background: var(--color-tile);
25+
width: var(--tile-width);
26+
height: calc(var(--tile-width) / 2 * 1.1);
27+
position: absolute;
28+
justify-content: center;
29+
align-items: center;
30+
display: flex;
31+
box-sizing: border-box;
32+
padding: var(--tile-gap);
33+
}
34+
35+
.tile p {
36+
color: #fff;
37+
font-family: sans-serif;
38+
text-align: center;
39+
margin: 0;
40+
}
41+
42+
.tile::before,
43+
.tile::after {
44+
content: '';
45+
position: absolute;
46+
left: 0;
47+
width: 0;
48+
height: 0;
49+
border-left: var(--tile-border-size) solid transparent;
50+
border-right: var(--tile-border-size) solid transparent;
51+
}
52+
53+
.tile::before {
54+
top: calc(var(--tile-border-size) / 2 * -1);
55+
border-bottom: calc(var(--tile-border-size) / 2) solid var(--color-tile);
56+
}
57+
58+
.tile::after {
59+
bottom: calc(var(--tile-border-size) / 2 * -1);
60+
border-top: calc(var(--tile-border-size) / 2) solid var(--color-tile);
61+
}
62+
63+
.row-0 {
64+
top: 0;
65+
}
66+
67+
.row-1 {
68+
top: calc(var(--tile-width) * 0.9);
69+
}
70+
71+
.row-0.i-0 {
72+
left: 0;
73+
}
74+
75+
.row-0.i-1 {
76+
left: calc(var(--tile-width) + var(--tile-gap));
77+
}
78+
79+
.row-0.i-2 {
80+
left: calc(var(--tile-width) * 2 + var(--tile-gap) * 2);
81+
}
82+
83+
.row-1.i-0 {
84+
left: calc(var(--tile-width) / 2 + var(--tile-gap) / 2);
85+
}
86+
87+
.row-1.i-1 {
88+
left: calc(var(--tile-width) + var(--tile-width) / 2 + var(--tile-gap) + var(--tile-gap) / 2);
89+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
html
2+
body
3+
.container
4+
.tile.row-0.i-0
5+
p Lorem ipsum
6+
.tile.row-0.i-1
7+
p Dolor sit amet
8+
.tile.row-0.i-2
9+
p Velit esse cillum
10+
.tile.row-1.i-0
11+
p Consectetur adipiscing elit
12+
.tile.row-1.i-1
13+
p Sed do eiusmod tempor
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
3+
Idea: Flexible scaling with minimum configuration needed. Might be a solution that can work with CSS preprocessing generators.
4+
5+
Problem: It's not responsive and gap between tiles is not scalable.
6+
7+
Look here for a responsive solution:
8+
https://github.com/web-tiki/responsive-grid-of-hexagons
9+
10+
*/
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/* HEXAGONS */
2+
3+
:root {
4+
--hexagon-width: 200px;
5+
--hexagon-height: 230px;
6+
7+
/* Using a CSS variable for this might not work in all browsers yet */
8+
--hexagon: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%);
9+
}
10+
11+
.hexagon {
12+
-webkit-clip-path: var(--hexagon);
13+
clip-path: var(--hexagon);
14+
15+
/* Alternative display: Less accurate, but prevents showing streaks at the corners, that might occur due to rounding issues in some cases * /
16+
clip-path: polygon(50% 0, 99.75% 24.75%, 99.75% 74.75%, 50% 99.75%, 0% 74.75%, 0.25% 25.25%);
17+
/* */
18+
}
19+
20+
/* CONTENT */
21+
22+
/* 1. */
23+
img {
24+
width: var(--hexagon-width);
25+
height: var(--hexagon-height);
26+
}
27+
28+
/* 2. */
29+
.div {
30+
background: url('https://picsum.photos/230/230');
31+
width: var(--hexagon-width);
32+
height: var(--hexagon-height);
33+
margin: 5%;
34+
}
35+
36+
svg {
37+
width: var(--hexagon-width);
38+
height: var(--hexagon-height);
39+
}
40+
41+
/* PAGE */
42+
43+
html,
44+
body {
45+
background: #111;
46+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// 1
2+
img.hexagon(src='https://picsum.photos/230/230')
3+
4+
// 2
5+
.div.hexagon
6+
7+
// 3
8+
<svg xmlns="http://www.w3.org/2000/svg">
9+
<defs>
10+
<pattern id="img" patternUnits="userSpaceOnUse" width="200" height="230">
11+
<image href="https://picsum.photos/230/230" width="230"/></pattern>
12+
</defs>
13+
<path fill="url(#img)" d="M99.593 0l99.593 57.5v115L99.593 230 0 172.5v-115z"/>
14+
</svg>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
3+
This demo showcases different variants of creating hexagons with image backgrounds.
4+
5+
Depending on your needs or the system you use, you might find one or few of them practical to use.
6+
7+
This example is based on a client project, where the software did not allow using WebP format. As transparent PNGs are too large, we had to use JPG instead. This led to the need to hide borders, and all those fancy workarounds you see here :)
8+
9+
---
10+
11+
// Image formats
12+
This example uses JPG, which is not the best format here. Use WebP or PNG images with or without transparency.
13+
14+
Please note that WebP might not work everywhere (yet) and need a fallback.
15+
16+
---
17+
18+
// clip-path rounding
19+
1. clip-path might give tiny rounding issues in some cases. If using images with a background, it might shine through in some occasions and scales, showing a pixel wide streak around some corners.
20+
21+
Assuming you use a non-transparent image, here are thoughts on workarounds:
22+
23+
A) Edit the image to be in hexagonal shape as well and fill the background to match the body (less flexible, though it saves space compared to keeping all image data). If clipping the image to be in hexagonal shape, make sure it's a few pixels larger around all sides than it needs to be.
24+
25+
B) Modify the polygon() to take care of cutting off the edges. I don't recommend this approach though, as it distorts the shape. If you needed perfect alignment, it could become visible.
26+
27+
// clip-path vs. Bounding box
28+
2. Use of clip-path does not change the bounding-box of elements. If you need a border around the elements, it would be cut off. Here it's probably best to go with an SVG approach.
29+
30+
---
31+
32+
// Generators
33+
34+
CSS clip-path
35+
- https://bennettfeely.com/clippy
36+
37+
SVG hexagons
38+
- https://codepen.io/wvr/pen/WrNgJp
39+
40+
*/
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
:root {
2+
/**
3+
* Values are based on the background images aspect ratio
4+
* and its width of 50% viewport size (50vw).
5+
*/
6+
--ar-1: 16.6666666667vw; /* 50vw / 3 */
7+
--ar-3: calc(var(--ar-1) * 3); /* 50.0000000001vw */
8+
--ar-4: calc(var(--ar-1) * 4); /* 66.6666666668vw */
9+
}
10+
11+
/* LAYOUT */
12+
13+
html,
14+
body {
15+
background: #fff;
16+
margin: 0;
17+
padding: 0;
18+
}
19+
20+
.main {
21+
/* Aspect ratio - 3:4 */
22+
background: url('https://picsum.photos/960/1280') no-repeat 100% 0;
23+
background-origin: border-box;
24+
background-size: var(--ar-3);
25+
}
26+
27+
.col {
28+
--text-column-gap: 1%;
29+
30+
box-sizing: border-box;
31+
padding: calc(var(--text-column-gap) * 2);
32+
margin: 0 0 calc(var(--text-column-gap) * 4);
33+
}
34+
35+
.aspect-ratio--3-4 {
36+
width: var(--ar-3);
37+
38+
/* Deliberately allow overflowing text */
39+
min-height: var(--ar-4);
40+
}
41+
42+
/* CONTENT */
43+
44+
.text-higlight {
45+
background: #f3f3f3;
46+
}
47+
48+
.text-columns {
49+
columns: 3;
50+
column-gap: 1.3rem;
51+
column-rule: 0.125rem solid #fff;
52+
}
53+
54+
.text-body {
55+
font-family: system-ui;
56+
font-size: 1rem;
57+
line-height: 1.3rem;
58+
}
59+
60+
.text-head {
61+
font-family: system-ui;
62+
font-size: clamp(1rem, 2vw, 2rem);
63+
line-height: 150%;
64+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<main class="main">
2+
<div class="col aspect-ratio--3-4 text-head">
3+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
4+
minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit
5+
in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
6+
officia deserunt mollit anim id est laborum.
7+
</div>
8+
9+
<div class="col text-body text-columns text-higlight">
10+
Elementum tempus egestas sed sed risus pretium quam. Vitae justo eget magna fermentum iaculis eu non. Facilisis sed odio morbi quis
11+
commodo odio aenean sed adipiscing. Faucibus ornare suspendisse sed nisi. Magnis dis parturient montes nascetur ridiculus mus mauris.
12+
Arcu vitae elementum curabitur vitae nunc sed velit dignissim. Pellentesque adipiscing commodo elit at imperdiet. Sit amet luctus
13+
venenatis lectus. Sed risus pretium quam vulputate dignissim suspendisse. Platea dictumst quisque sagittis purus sit amet volutpat
14+
consequat. Nunc lobortis mattis aliquam faucibus purus. Quisque egestas diam in arcu cursus euismod quis viverra. A lacus vestibulum sed
15+
arcu non odio euismod lacinia. Placerat duis ultricies lacus sed. Arcu cursus vitae congue mauris rhoncus aenean vel elit scelerisque.
16+
Sagittis eu volutpat odio facilisis. Vel turpis nunc eget lorem dolor sed. Et sollicitudin ac orci phasellus egestas tellus rutrum.
17+
</div>
18+
</main>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
3+
Align columns to a scaling background image sizing
4+
5+
6+
How to use:
7+
8+
Resize the screen and see how the lower text column flows and stays below the top part, without overlapping the image.
9+
10+
In the smallest viewport, the column text exceeds image height, further pushing down the lower column. This is considered intentional for this demo. (We could also hide the text; just use less of it; or find some other fancy way to match the image to the text size dynamically.)
11+
12+
---
13+
14+
Challenges solved:
15+
- A background image that scales with viewport size and used as additional column (or rather, reserved space).
16+
- Content must never overlap the image.
17+
- Content must be placed next to and below the column, while keeping a consistent distance to each other.
18+
- Breakpoints cannot be used, as content size is unpredictable due to word wrapping differences depending on content, languages and browser abilities. Assume content can change anytime, so hard-coding or estimating lines of text is not an option.
19+
20+
Solution:
21+
- Start with the image size: Calculate its aspect ratio.
22+
- Use aspect-ratio and viewport width unit to define any other sizes.
23+
24+
---
25+
26+
Additionally:
27+
28+
Added a few typographic styles for a minimalist magazine style look, to give this demo a real world purpose.
29+
30+
*/

0 commit comments

Comments
 (0)