As a way of finishing up the comic-books-in-web-tech trend that I’ve been on the past few weeks, I thought I’d take a look at creating dynamic comic panels with CSS.
Panels in traditional comics are rectangular, but Japanese manga and Western graphical experimentation in the late 1970s created panels that took on all kinds of shapes, the demo above being one example.
One Photo, Two Shapes
The central design derives from a single photo:
Because the panels will be positioned individually, we need two copies of the image. I’ve placed both copies inside a <div>
element with an id
:
<div id="comicbookpanels">
<img src="boxers.jpg" alt>
<img src="boxers.jpg" alt="Two boxers fighting in a ring">
</div>
Using the standard technique of placing the images inside an element with relative
positioning to provide the same base absolute
position reference:
#comicbookpanels {
position: relative;
}
#comicbookpanels img {
position: absolute;
}
#comicbookpanels img {
top: 0; left: 0;
width: 100%;
}
Clipping The Panels
The photos are divided using CSS clip-path, applied with xth-of-type
pseudo element selectors:
#comicbookpanels img:first-of-type {
clip-path: polygon(0 0, 61% 0, 49% 100%, 0 100%);
}
#comicbookpanels img:last-of-type {
clip-path: polygon(100% 0, 61% 0, 49% 100%, 100% 100%);
}
I used Bennett Feely’s excellent Clip Path Maker to generate the points. The advantage of using this technique, rather than editing and exporting them as separate images in PhotoShop, is adaptability: changing the angle between the panels would be as easy as changing a single number in each clip-path
.
As clip-path
is not yet supported in Firefox and other browsers, we’ll fallback to the original SVG method of clipping HTML content. The good news is that the SVG syntax uses the same values as clip-path, just divided by 100. At the bottom of the document, add:
<svg id="clippingpaths">
<defs>
<clipPath id="leftpanel" clipPathUnits="objectBoundingBox">
<polygon points="0,0 .61,0 .49,1 0,1" />
</clipPath>
<clipPath id="rightpanel" clipPathUnits="objectBoundingBox">
<polygon points="1,0 .61,0 .49,1 1,1" />
</clipPath>
</defs>
</svg>
To apply the SVG together with the CSS clip-path
, while offsetting the second image copy:
#comicbookpanels img:first-of-type {
clip-path: url(#leftpanel);
clip-path: polygon(0 0, 61% 0, 49% 100%, 0 100%);
}
#comicbookpanels img:last-of-type {
top: 2rem;
left: 1rem;
clip-path: url(#rightpanel);
clip-path: polygon(100% 0, 61% 0, 49% 100%, 100% 100%);
}
Despite the SVG only containing a <defs>
element, it will still take up space on the page as a replaced element. We can’t use display: none
on the SVG to remove this space, since that will also remove the clipping effect for browsers that need it; instead, we’ll set the height of the element to 0
using HTML pr CSS:
#clippingpaths {
height: 0;
}
Applying the Text
To create the textboxes I’ve added a paragraph in the <div>
, with the appropriate words grouped inside <span>
elements:
<div id="comicbookpanels">
<img src="boxers.jpg" alt>
<img src="boxers.jpg" alt="Two boxers fighting in a ring">
<p>
<span>The blows</span>
<span>landed like</span>
<span>a hammer…</span>
</p>
</div>
The text uses Nate Piekos’ excellent Sequentialist BB font. The paragraph is positioned, and the <span>
elements staggered:
#comicbookpanels p {
position: absolute;
left: 50%;
margin-top: 30%;
font-size: 1.4rem;
}
#comicbookpanels span {
background: #fff;
border: 2px solid #000;
padding: .5rem;
display: block;
position: relative;
margin-top: 1rem;
}
#comicbookpanels p span:first-child {
margin-left: 1rem;
}
#comicbookpanels p span:last-child {
margin-left: -1rem;
}
As Jen Simmons has emphasised over the last year in a series of passionate presentations, web design no longer has to be made up from a series of rectangles. This work is very much made in that spirit; I really like the result, and hope it might inspire design work of your own.
Photograph by Morgan Ossola, licensed under Creative Commons.
Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.
Check out the CodePen demo for this article at https://codepen.io/dudleystorey/pen/ONWZKo