Please Give Me Some Space

There’s all kinds of ways to do that. Some more advisable and better-suited for certain situations than others, of course.

We could do it directly in HTML:

<p>We go from one line...<br><br> down a couple more.</p>

But that’s what CSS is really for:

<p>We go from one line...<span>down a couple more.</span></p>
span {
  display: block;
  margin-block-start: 1.5rem;
}

Line height can also give us extra breathing room between lines of text:

p {
  line-height: 1.35;
}

Since we’re talking text, there’s also letter-spacing and word-spacing, not to mention text-indent:

But let’s talk boxes instead of text. Say we have two simple divs:

<div>Twiddle Dee</div>
<div>Twiddle Dum</div>

Those are block-level so they’re already on different lines. We can reach for margin again. Or we could create the impression of space with padding. I suppose we could translate those suckers in either direction:

div:nth-child(2) {
  transform: translateY(100px);
}

But maybe those elements are absolutely positioned so we can use physical offsets:

div {
  position: absolute;
}
div:nth-child(1) {
  inset: 0;
}
div:nth-child(2) {
  inset-inline-start: 100px; /* or top: 100px; */
}

If we’re working in a grid container, then we get gap-age:

<section>
  <div>Twiddle Dee</div>
  <div>Twiddle Dum</div>
</section>
section {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 100px;
}

Same deal with a flexible container:

section {
  display: flex;
  gap: 100px;
}

While we’re working in grid and flexible containers, we could call on any alignment property to generate space.

section {
  display: flex;
  align-items: space-between;
  justify-content: space-between;
}

There are tables, of course:

<table cellspacing="100">
  <!-- etc.  -->
  <tbody>
    <tr>
      <td>Twiddle Dee</td>
      <td>Twiddle Dum</td>
    </tr>
  </tbody>
</table>

Or the CSS-y approach:

/* We could use `display: table` if we're not working in a table element. */
table {
  border-spacing: 100px;
}

Let’s go deeper into left field. We can make one element look like two using a linear gradient with a hard color stop:

div {
  background-image:
    linear-gradient(
      to right,
      rgb(255 105 0 / 1) 50%,
      rgb(207 46 46 / 1) 50%,
      rgb(207 46 46 / 1) 100%
    );
}

Then we do a head fake and insert a hard transparent color stop between the two colors:

As long as we’re fakin’ bacon here, might as well toss in the ol’ “transparent” border trick:

Let’s go back to text for a moment. Maybe we’re floating an element and want text to wrap around it… in the shape of the floated element while leaving some space between the two. We have shape-margin for that:

Dare I even mention the spacer.gif days?

<div>Twiddle Dee</div>
<img src="spacer.gif"> <!-- 🤢 -->
<div>Twiddle Dum</div>

There’s gotta be more

You’re all a smart bunch with great ideas. Have at it!


Please Give Me Some Space originally published on CSS-Tricks. You should get the newsletter.

Float an Element to the Bottom Corner

Need to lay out an element to the right or the left, such that text wraps around it? That’s an easy task for the float property. But what about if you also want to push that element (let’s call it an image) to one of the bottom corners while we’re at it? Sounds a bit tricky, right? We probably need JavaScript?

Nope, few lines of (tricky) CSS can do it! Here’s the CSS-only solution that will make your image to stick to the bottom corner, regardless of the size and content.

Resize the wrapper element and see the magic at work:

Let’s dissect the code.

Markup and layout

We’ll need a wrapper element to contain everything, and we’ll be using flexbox on it. Flexbox allows us to rely on the default stretch alignment to be able to later use height: 100%.

<div class="wrapper">
  <div class="box">
    <div class="float"><img></div>
    Lorem ipsum dolor ...
  </div>
</div>
.wrapper {
  display: flex;
}

.float {
  float: right;
  height: 100%;
  display: flex;
  align-items: flex-end;
  shape-outside: inset(calc(100% - 100px) 0 0);
}

The .box within the .wrapper is our flex item. We don’t need any particular CSS applied to the box. It defines the height of the wrapper and, at the same time, is stretched to the same height. This behavior will give us a “reference height” that can be used by the child elements.

From the specification:

If the flex item has align-self: stretch, redo layout for its contents, treating this used size as its definite cross size so that percentage-sized children can be resolved.

The keyword is the definite which allows us to safely use a percentage (%) height inside the box element.

Now for the floated element

Our .float element will take the entire height next to the text content, thanks to the height calculation we detailed above. Inside this element we push the image to the bottom using flexbox alignment.

A paragraph of lorem i-sum text with a small square image to the right of the text. The image is located at the bottom right of the text and the space above the image is empty.
The image is floated to the right but the free space above it prevents the content from wrapping around it.

Now for the real trickery, using the shape-outside property. Here’s how MDN defines it:

The shape-outside CSS property defines a shape—which may be non-rectangular—around which adjacent inline content should wrap. By default, inline content wraps around its margin box; shape-outside provides a way to customize this wrapping, making it possible to wrap text around complex objects rather than simple boxes.

In other words, shape-outside sets the way content flows around an element’s bounding box.

It takes a number of values. One of those is the inset() function which, again, according to MDN:

Defines an inset rectangle. When all of the first four arguments are supplied they represent the top, right, bottom and left offsets from the reference box inward that define the positions of the edges of the inset rectangle.

So, with shape-outside: inset(calc(100% - X) 0 0) we can create an inset rectangle that starts exactly at the top of the image. And the top is equal to 100% - X, where X is the image height and 100% is the height of the .float element. This allows the text to wrap within the free space on the top of the image. This is responsive, plus we can easily switch between left and right (by adjusting the float property)

That’s it! The only major caveat is that you need to know the image height.

Want more?

We can extend this concept a little further to account for fancier situations. For example, we can float the image to the right, but pin it to the middle of the box with justify-content: center: and also adjust our inset rectangle to the middle by changing the shape-outside from inset(calc(100% - X) 0 0) to inset(calc(50% - X/2) 0 0)

We can also float two images at both bottom corners:

Nothing complex here. I am simply using the same floating element twice, once on the right, and again on the left. And why stop at two corners when we can place images at all four corners:

The same basic idea is at play here, but we’re are also relying on the common float feature for the top images. However, you’ll notice that this is where the concept starts to break down a bit, and we get some unwanted overflow depending on the size of the containing box. We can make the height of the .float element greater than 100% and apply somewhat “magic numbers” that smooth things out by adjusting the padding and margin of the images.

Did you know that shape-outside accepts radial-gradient() as a value? We can use that to place rounded images like below:

The transparent part of the gradient is the free space where the text can go. You may have noticed that we applied a border-radius to the image as well. The shape-outside property will simply affect the .float element and we need to manually adjust the shape of the image to follow the shape defined by shape-outside.

While we’re at it, let’s combine this with our earlier example that pins the image to the vertical center of the box using justify-content: center:

Another radial-gradient() and also another border-radius configuration.

We could have used a linear-gradient() instead to make a triangular shape for the wrapping area:

This is the same idea that we used for the radial-gradient(). The big difference is that we’re using clip-path instead of border-radius to cut our image.

And, since we did it for the others, let’s use the justify-content: center idea to pin the image to the vertical center of the box’s right edge:

We used a conic-gradient() in the above demo with shape-outside to define the triangular shape and clip-path to get a similar shape on the image

All of these examples can still be optimized using less of code in the case that the image is decorative (when it’s not needed inside the HTML for SEO purposes). Let’s replace the .float element with a pseudo-element and apply the image as background instead:

We’re using mask to show just the portion of the image that we need and, guess what, it uses the same value as shape-outside! So, all we had to do is define one value for the shape.

That’s it!

There are a lot of possibilities here to place not just rectangles in corners, but any kind of shape at any position, using largely the same code structure. We only need to:

  • Adjust the shape-outside property to define the shape
  • Apply some styling to the image to follow the previously defined shape or apply the same value to mask in case we are using the pseudo element version

Then everything holds it place, even in responsive designs.


The post Float an Element to the Bottom Corner appeared first on CSS-Tricks.

You can support CSS-Tricks by being an MVP Supporter.

Using CSS to Set Text Inside a Circle

You want to set some text inside the shape of a circle with HTML and CSS? That’s crazy talk, right?

Not really! Thanks to shape-outside and some pure CSS trickery it is possible to do exactly that. 

However, this can be a fiddly layout option. We have to take lots of different things into consideration, like character count, word count, typeface variations, font sizing, font formatting, and responsive requirements to name a few. One size, does not fit all here. But hey, let’s do it anyway.

Here’s the goal: we want to display a <blockquote> and an author citation inside a circle shape. We also want to make the layout as flexible as we can. This layout won’t require any additional files and keeps the HTML markup squeaky clean.

This is what we’re striving for:

The shape-outside feature is not supported in Internet Explorer or Microsoft Edge 18 and below at the time of this writing.

First up, the HTML

We’re going to end up needing a wrapper element to pull this off, so let’s use the semantic <blockquote> as the inner element. The outside wrapper can be a div:

<div class="quote-wrapper">
  <blockquote class="text" cite="http://www.inspireux.com/category/quotes/jesse-james-garrett/">
    <p>Experience design is the design of anything, independent of medium, or across media, with human experience as an explicit outcome, and human engagement as an explicit goal.</p>
    <footer>– Jesse James Garrett</footer>
  </blockquote>
</div>

If you’re interested in a deep-dive on the HTML of quotes, you’re in luck. We’re going to set the quote itself in a <p> and the name of the author inside a <footer>. We’ve got class names for the CSS styling hooks we’ll need.

Next, some baseline CSS

Let’s start with the div wrapper. First, we’ll set the minimum (responsive) square size at 300px so it fits on smaller screens. then, we’ll add relative positioning (because we will need it later). 

.quote-wrapper {
  height: 300px;
  position: relative;
  width: 300px;
}

Now we’ll make the blockquote fill the whole wrapper and fake a circle shape with a radial gradient background. (That’s right, we are not using border-radius in this example).

.text {
  background: radial-gradient(
    ellipse at center,
    rgba(0, 128, 172, 1) 0%,
    rgba(0, 128, 172, 1) 70%,
    rgba(0, 128, 172, 0) 70.3%
  );
  height: 100%;
  width: 100%;
}

One thing to note is that 70% displays a much rougher edge. I manually added very small percentage increments and found that 70.3% looks the smoothest.

Notice the edge on the right is much smoother than the edge on the left.

Now we have our base circle in place. Add these additional style rules to .text.

.text {
  color: white;
  position: relative;
  margin: 0;
}

Here’s what we have so far:

Giving text the CSS treatment

Let’s style the paragraph first:

.text p {
  font-size: 21px;
  font-style: italic;
  height: 100%;
  line-height: 1.25;
  padding: 0;
  text-align: center;
  text-shadow: 0.5px 0.5px 1px rgba(0, 0, 0, 0.3);
}

Let’s use the blockquote’s ::before pseudo-element to create our shaping. This is where the shape-outside property comes into play. We plot out the polygon() coordinates and float it to the left so the text wraps inside the shape.

.text::before {
  content: "";
  float: left;
  height: 100%;
  width: 50%;
  shape-outside: polygon(
    0 0,
    98% 0,
    50% 6%,
    23.4% 17.3%,
    6% 32.6%,
    0 50%,
    6% 65.6%,
    23.4% 82.7%,
    50% 94%,
    98% 100%,
    0 100%
  );
  shape-margin: 7%;
}

Let’s change the radial background color to red. The path editor polygon points and connecting lines are also blue. We are changing this color temporarily for greater contrast with the editor tool.

background: radial-gradient(
  ellipse at center,
  rgba(210, 20, 20, 1) 0%,
  rgba(210, 20, 20, 1) 70%,
  rgba(210, 20, 20, 0) 70.3%
);

I like Firefox’s developer tools because it has super handy features like a shape-outside path editor.  Click on the polygon shape in the inspector to see the active shape in the browser window. Big thumbs up to the Mozilla dev team for creating a very cool interface!

The Firefox shape editor tool also works for clip-path and <basic-shape> values.

Here’s what we have at this point:

Those points along the shape are from Firefox’s editing tool.

We can do the same sort of thing for the paragraph’s ::before pseudo-element. We use the shape-outside to make the same polygon, in reverse, then float it to the right.

.text p::before {
  content: "";
  float: right;
  height: 100%;
  width: 50%;
  shape-outside: polygon(
    2% 0%,
    100% 0%,
    100% 100%,
    2% 100%,
    50% 94%,
    76.6% 82.7%,
    94% 65.6%,
    100% 50%,
    94% 32.6%,
    76.6% 17.3%,
    50% 6%
    );
  shape-margin: 7%;
}

Looking good, but where did the footer go? It overflowed the <blockquote> (where the circular colored background is), so we’re unable to see that white text on a white background.

Styling the footer

Now we can style the <footer> and give it an absolute position to bring it back on top of the circle.

.quote-wrapper blockquote footer {
  bottom: 25px;
  font-size: 17px;
  font-style: italic;
  position: absolute;
  text-align: center;
  text-shadow: 0.5px 0.5px 1px rgba(0, 0, 0, 0.3);
  width: 100%;
}

Again, feel free to change the background color to suit your needs.

This is where the fiddly part comes in. The text itself needs to be styled in such a way that the number of words and characters work inside the shape. I used these CSS rules to help make it fit nicely:

  • font-size
  • shape-margin (we have two exclusion areas to adjust)
  • line-height
  • letter-spacing
  • font-weight
  • font-style
  • min-width  and min-height (to size of the .quote-wrapper container)

Adding the quote mark for some flourish

Did you see the giant quotation mark in the original demo? That’s what we want to make next.

We’ll take advantage of the ::before  pseudo-element for .quote-wrapper. Yet again, this will take a fair amount of fiddling to make it look right. I found line-height has a huge effect on the mark’s vertical position.

.quote-wrapper::before {
  content: "\201C";
  color: #ccc;
  font-family: sans-serif, serif;
  font-size: 270px;
  height: 82px;
  line-height: 1;
  opacity: .9;
  position: absolute;
  top: -48px;
  left: 0;
  z-index: 1;
}

There’s actually a difference between curly (“smart”) quote marks and straight (dumb) ones. I’d suggest using curly quote marks for dialogue and straight quote marks for coding.

Handling responsive styles

We should probably make our quote bigger on larger screens. I’m setting a breakpoint at 850px, but you may want to use something different.

@media (min-width: 850px) {
  .quote-wrapper {
    height: 370px;
    width: 370px;
  }
  .quote-wrapper::before {
    font-size: 300px;
  }
  .text p {
    font-size: 26px;
  }
  .quote-wrapper blockquote footer {
    bottom: 32px;
  }
}

There we have it!

We set HTML text inside a circular shape using a combination of old and new CSS techniques to make an appealing <blockquote> that commands attention. And we achieved our display goal without any additional dependencies, while still keeping the HTML markup clean and semantic.

I hope this article encourages you to explore new layout possibilities with shape-outside. Stay tuned for shape-inside.

The post Using CSS to Set Text Inside a Circle appeared first on CSS-Tricks.

Float Element in the Middle of a Paragraph

Say you want to have an image (or any other element) visually float left into a paragraph of text. But like... in the middle of the paragraph, not right at the top. It's doable, but it's certainly in the realm of CSS trickery!

One thing you can do is slap the image right in the middle of the paragraph:

<p>
  Lorem ipsum dolor sit amet consectetur, adipisicing 
  <img src="tree.jpg" alt="An oak tree." />
  elit. Similique quibusdam aliquam provident suscipit 
  corporis minima? Voluptatem temporibus nulla
</p>

But that's mega awkward. Note the alt text. We can't have random alt text in the middle of a sentence. It's semantically blech and literally confusing for people using assistive technology.

So what we have to do is put the image before the paragraph.

<img src="tree.jpg" alt="An oak tree." />

<p>
  Lorem ipsum dolor sit amet consectetur, adipisicing 
  elit. Similique quibusdam aliquam provident suscipit 
  corporis minima? Voluptatem temporibus nulla
</p>

But when we do that, we aren't exactly floating the image in the middle of the paragraph anymore. It's right at the top. No margin-top or vertical translate or anything is going to save us here. margin will just extend the height of the floated area and translate will push the image into the text.

The trick, at least one I've found, is to leverage shape-outside and a polygon() to re-shape the floated area around where you want it. You can skip the top-left part. Using Clippy is a great way to get a start to the polygon:

But instead of the clip-path Clippy gives you by default, you apply that value to shape-outside.

That should be enough if you are just placing a box in that place. But if it's literally an image or needs a background color, you might also need to apply clip-path and perhaps transform things into place. This is where I ended up with some fiddling.

See the Pen
Float cutout in middle of paragraph.
by Chris Coyier (@chriscoyier)
on CodePen.

The post Float Element in the Middle of a Paragraph appeared first on CSS-Tricks.

8 Little Videos About the Firefox Shape Path Editor

It sometimes takes a quick 35 seconds for a concept to really sink in. Mikael Ainalem delivers that here, in the case that you haven't quite grokked the concepts behind path-based CSS properties like clip-path and shape-outside.

Here are two of my favorites. The first demonstrates animating text into view using a polygon as a clip.

The second shows how the editor can help morph one shape into another.

Direct Link to ArticlePermalink

The post 8 Little Videos About the Firefox Shape Path Editor appeared first on CSS-Tricks.

People Talkin’ Shapes

Codrops has a very nice article on CSS Shapes from Tania Rascia. You might know shape-outside is for redefining the area by which text is floated around that element, allowing for some interesting design opportunities. But there are a couple of genuine CSS tricks in here:

  1. Float shape-outside elements both right and left to get text to flow between them.
  2. You can set shape-outside to take an image and use shape-image-threshold to adjust where the text flows, meaning you could even use a gradient!


Shapes are in the water recently, as Heydon Pickering recently published a short video on using them. He also covers things like clip-path and canvas and such:


We recently moved our long-time page on (basically faking) CSS shapes over to a blog post so it's easier to maintain.

Robin also wrote Working with Shapes in Web Design that digs into all this. So many tricks!

See the Pen 10c03204463e92a72a6756678e6348d1 by CSS-Tricks (@css-tricks) on CodePen.


When we talk about CSS shapes, it's almost like we're talking about values moreso than properties. What I mean is that the value functions like polygon(), circle(), ellipse(), offset(), path(), etc. are more representative of "CSS shapes" than the properties they are applied to. Multiple properties take them, like shape-outside, clip-path, and offset-path.

I once did a whole talk on this:

The only thing that's changed since then is that Firefox started allowing clip-path: path() behind the flag layout.css.clip-path-path.enabled (demo).


And don't forget Jen Simmons was talking about the possibilities of CSS Shapes (in her lab demos) years earlier!

The post People Talkin’ Shapes appeared first on CSS-Tricks.