I built this on a whim after seeing some terrible examples on Stack Overflow, so unlike other demos I build there was no immediate application. That means it may or may not be useful as-is.
For this post I have forked each variation of the original and added a little explanation. The embedded CodePen examples are also editable, so you can play around with the styles without leaving the page.
The Base Model
I started off with a straightforward box with an image at the top, having taken a bite out of the box. I kept the box itself partially transparent because I wanted to show that it can be done, though it also demonstrates just a little spacing wonkiness that can come into play on the right side. I also have a textured background to show that it can sit on any background you want.
In the absence of broad support for CSS variables, I keep all the color styles separate and grouped together to make it easy to change them.
I also keep the styles for the image broken up so you can just drop a different path into additional selectors or even inline on the element (ugh). If you are stuck with an image that just doesn’t fit, tweak the background-size and you are good to go.
If you want to play around with any styles, these pens are editable right in this page. So you can change a style property and see what happens.
For a little detail of what you’ll see looking at the styles, note that the item classed bio is just a generic block-level element. The top is below the image, so the image overlaps nothing. Then I create two new elements via the .bio::before and .bio::after. Those two elements get placed above the block and either side of the image. That creates the perception of a notch cut out.
The item classed pic then gets positioned above the bio block, fitting in the spot where I created the notch. Now the circle comes into play. It is the only element in the page that serves to be decoration (I hate that), as opposed to the two generated elements. I generate an item with .circle::after, give it a circular border, position it, and then crop it with .circle, dropping it into the gap between .bio::before and .bio::after. That completes the notch effect.
Scale It Up
I base all my sizing on ems. Because of that, you can scale this up or down just by changing the font-size style. Granted, this has an upper practical limit. I did not build responsive styles as this is intended as a fluid chunk of a page.
For this example I set the font-size to 200% and everything grows to match, include the border radii, the circle, the spacing, etc.
It stands to reason that some egos may demand a larger image. Or perhaps you are using this as a product box on a site and you want people to see the individual bristles of your toothbrush. No worries, just a few tweaks and we are good to go.
I started with a centered image because, well, I’m not sure.
Here I move the image to the left side, letting you do the math backward to move it to the right. Though if you look a little further down the demo, you’ll see I moved it to the right — on the bottom. I intentionally override the base styles so you can more easily see how I move the image (and do it yourself for kicks).
All of my examples use a single <p>, which doesn’t really work well for multiple paragraphs nor proper author citations. Here I have not only used a <blockquote> as the wrapper, but I’ve added a text citation into a <footer>. That means I only needed to add two more styles, one to visually hide the text (which assumes a left-to-right reading direction) and one to remove the bottom margin on the second-last element (since the last element is the <footer>).
If you use this strictly for quoting, you may want to play with the class names too. For example, pic probably isn’t the best choice in this context.
If you want to animate the image moving around, there is a bit of a catch. CSS transitions only work with absolutely positioned when both the starting and ending values are not automatically assigned. So I added values for both left and right at each end of the animation.
I put this on a <button> because it allows interaction, even with a keyboard. So do not use this on a non-interactive element as that would be wrong. Adding an ARIA role and/or tabindex to make it work is also wrong.
I’ve made some efforts within these examples to support users in different circumstances (different than your awesome high-powered machine with your perfect eyes and 4k display, er, I mean, yeah).
These bits may not be exciting to some readers, but I believe they are necessary to address.
The styles here are simple. They are strictly display and are not messing with any interactive elements or controls. However, you still need to follow some simple rules just as you would anywhere else:
Because the images are background images, there is no way to provide alternative text to screen readers. Unless you use the technique in my <blockquote> example to visually hide text, do not rely on the images to convey anything other than decoration, and certainly don’t put text in them.
Pay attention to the color contrast between the text and the background. Don’t do the cool gray on gray, low contrast text. If you aren’t sure if you have enough contrast, start with the WebAIM Color Contrast Checker.
All of my examples assume the page follows a left-to-right reading order. A right-to-left page should not suffer any ill effects (I tested), but you may want to move the photos around.
Windows High Contrast Mode
There is a great accessibility feature built into Windows called High Contrast Mode (HCM). Essentially it overrides the colors you have defined, potentially wreaking havoc with your perfect designs (though the user is better off for it).
Conveniently, there is a media query available to allow you to make some tweaks to your layouts for HCM (introduced in Windows 8). It is also worth noting that both Internet Explorer and Edge (as of this writing) discard background images altogether. I go into this in more detail in my post CSS Background Images & High Contrast Mode.
Conveniently, I have already written the basics of these media queries into my examples. Because background colors and images are discarded, I replace the key elements with borders so they are still visible. While the background image is missing, the border at least keeps the context in place. As long as you aren’t relying on the images to convey critical information, then their absence should not be a big deal.
As a good developer who believes in responsive design, I know you always provide print styles for your users. I’ve made it a bit easier by taking care of the heavy lift for you.
For each example I include print styles that still include the image, though you will need to re-specify it in the print styles. If you end up using inline images instead of background images in your version then that won’t be the case.
For the block quote style I make sure to dump the image in favor of displaying the text that is otherwise hidden. You can decide if this is a fit for you, but I feel it is important enough to display given that there is a chance the image won’t.
Overall, my goal is tweak the layout to make it useful, not necessarily reproduce what the is seen in the browser window. I also try to respect printer ink by setting all colors to black or white (except images). Finally, since it is not uncommon for a browser to allow users to print backgrounds, I explicitly re-set everything to prevent black-on-black scenarios.
Thanks for this tutorial! This is a really slick looking style that will make the comments section of any website more attractive. Another added bonus is that it makes it easier to visually understand who made what comment. Great job Sven!