Floating Image
The default medium used to communicate on a web page is text. To better communicate, it's common for include an image or video with the text. Designing how these elements are positioned can further improve communication. For example. This article about a pilot's famous flight between England and Australia. See how the position of text and image reinforces this story.

Text wrapping is a useful tool when positioning elements. Text (and other inline elements) can wrap around an element using the float property. This can be refined by also using shape-outside with a value of:
- ▪
circle()
, - ▪
ellipse()
, - ▪
inset()
for rectangular shapes, - ▪
polygon()
for any shape with 3 or more vertices and - ▪
url()
to generate the shape from an image.
float
Below is an example of a div
with float
.
float
is limited to:
- ▪ positioning the element to the top-left or top-right corner of the following sybling inline element and
- ▪ the shape the text flows around is rectangular (text wraps around the element's box - made up of content, padding, border and margin).
localhost:3000
div { width: 40%; aspect-ratio: 1/1; float: right; border: 1px solid var(--black); } p { text-align: justify; } p + p { margin-top: 24px; }
shape-outside
The shape-outside
property creates an invisible shape within an element with float
.
Sybling inline elements will wrap around this shape instead of the element's box.
Any part of the shape outside the box is ignored.
/index.css
div { float: right; /* circle(<radius> at <x>, <y>) */ shape-outside: circle(50% at 50% 50%); }
localhost:3000
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Working out the values required for shape-outside
using a code editor can be tedious.
An easier why is to use Firefox's dev tools.
It provides an interface to generate the values.
Say you wanted to use a polygon shape.
In your editor, set values to a simple 3-side polygon, shape-outside: polygon(0 0, 100% 0, 100% 100%);
.
Then, open the dev tools, inspect the element and click the icon next to polygon
.
Now you can:
- ▪ drag a point to different position,
- ▪ double-click the line to add a point and
- ▪ shift-double-click a point to remove it.

shape-margin
shape-margin
adds a margin to the shape.
Like the shape, any part of the margin outside the element's box is ignored.
/index.css
div { float: right; shape-outside: circle(50% at 50% 50%); shape-margin: 16px; }
localhost:3000
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
shape-image-threshold
An alternative to manually defining a shape is shape-image-threshold. It creates a shape based on the transparency of pixels. It takes a threshold value. The shape is defined by the pixels whose alpha value is greater than the threshold. A value of:
- ▪
0.0
= full transparent - ▪
1.0
= fully opaque (not able to be seen through)
Below, the threshold is set to 0.1
.
This means the shape will be defined by all pixels that are more than 10% opaque.
localhost:3000
img { width: 40%; float: right; shape-outside: url('https://garden.bradwoods.io/images/circle.svg'); shape-image-threshold: 0.1; border: 1px solid var(--black); }
Gap
If an image asset doesn't contain any empty space and a gap is required, shape-margin
can't be used.
This is because any part of the margin that goes outside the image's element box is ignored.
A work-around is to apply float and shape properties to a parent element.
Then, add padding equal to the shape-margin
value.
This technique can also move the shape away from the top.
localhost:3000
:root { --gap: 16px; } div { width: 40%; padding: var(--gap) 0 var(--gap) var(--gap); float: right; shape-outside: url('https://garden.bradwoods.io/images/circle.svg'); shape-image-threshold: 0.1; shape-margin: var(--gap); border: 1px solid var(--black); } img { width: 100%; }
shape-image-threshold
is a great fit when working with images with a gradient.
Giving control of how much text can overlap the image.
When doing this, care must be taken to ensure text has enough contrast to have a AA rating.

Use Case - Drop Cap
A drop cap (dropped capital) is a large, decorative initial letter. Usually located at the beginning of a section or chapter of a book. Their use in religious and scholarly texts dates back almost 2000 years. Making them associated with, and communicate, an old, traditional feeling. They stand out by using contrast. Being larger and more decorated than the letters around them. They are used for:
- ▪ adding depth to what is being communicated in the text by incorporating an image,
- ▪ as a visual aid by providing anchor points. Helping users find their place when reading large amounts of text and
- ▪ to mark a new section, new idea or important passage.
Floating image techniques can be used to create a drop cap.
localhost:3000
<svg viewBox="0 0 100 100"> <text x="24" y="82">L</text> <!-- 1 and 98 instead of 0 and 100 to prevent stroke cut off --> <rect x="1" y="1" width="98" height="98" /> </svg> <p> orem ipsum dolor sit amet, consectetur *adipiscing elit, sed do eiusmod tem*por incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p>
If the intention of a drop cap is to draw the user's attention, we can use the browser's capabilities to do more than just display a static image. Known as going beyond skeuomorphic. Humans attention is drawn to movement. Some believe this behaviour comes from our ancient ancestors who needed to be aware of moving things around them in case of predators. We can use this behaviour to make a drop cap more effective by adding an animation.
localhost:3000
<svg viewBox="0 0 100 100"> <text x="24" y="82">L</text> <rect x="4" y="4" width="92" height="92" /> <circle r="2"> <animateMotion dur="40s" path="M 4 4 H 96 V 96 H 4 L 4 4" repeatCount="indefinite" /> </circle> </svg> <p> orem ipsum dolor sit amet, consectetur *adipiscing elit, sed do eiusmod tem*por incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p>
You could argue a constant animation is too distracting to the user. Once their attention is drawn to a section, the animation has fulfilled its purpose. It's no longer required. Instead of a constant animation, we could use an entrance animation. A short animation that plays when the user 1st sees the element. This approach requires the Intersection Observer.
localhost:3000
svg { width: 68px; margin-right: 8px; float: left; } rect { fill: none; stroke: var(--black); } text { font-size: 96px; fill: var(--black); transform: translateY(100%); transition: transform 3s ease-out; } .show { transform: translateY(0%); } /* For accessibility, remove animation for users who enabled reduced motion preference setting */ @media screen and (prefers-reduced-motion: reduce) { text { transition-duration: 0s; } }
References
Where to Next?


