Find out more CSS tricks at css-tip.com
A quick trick to create any kind of shape having rounded corners.
1. Build the shape
For this task, we simply use clip-path
. You can rely on the following tool to do it: https://bennettfeely.com/clippy/. You will find a lot of predefined shapes and you can build yours using drag & drop.
2. Round the corners
For this task we apply the following SVG filter:
<filter id="round">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" result="blur" />
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" />
<feComposite in="SourceGraphic" in2="goo" operator="atop"/>
</filter>
filter:url(#round);
That's it!
We can apply any kind of background to our shape. The shape is defined using pseudo-element because we cannot directly apply the filter to an element having clip-path
. We need to apply it to a parent container.
We can also control the radius by adjusting the stdDeviation
of the filter.
This trick is not only limited to clip-path
shapes. It can also work with
Multiple elements shapes:
Multiple background shapes:
and so on.
Simply build your shape as you know and apply the filter to the uppermost container
The SVG filter is taking from the following article: https://css-tricks.com/gooey-effect/
Top comments (28)
Why not use an SVG as we are using an SVG filter?
Instead of having patchy support (for example the final shape does not work in Firefox in your examples) you have something that works all the way back to IE10 (and even IE9 if you don't mind losing the rounded corners!!!)
It also means you don't have to rely on padding hacks to make sure the shape occupies the correct space so you don't have to calculate / fiddle with that to make the shape fit correctly.
Not a reflection on the article at all, just a genuine curiosity as to what scenarios this would be a better option than an actual SVG?
SVG shapes are trivial things since SVG is a drawing tool. I won't write an article to explain how to draw something using a drawing tool, we also don't need filter since we can easily have curvature with
path
s.I am giving a trick that apply to CSS shapes since it's now something very common and it's not easy to build them with rounded corners.
I am also giving some trivial examples to illustrate only the shapes. In a real world, that shape will contain texts, images, hover effect, etc which is something not easy to do with SVG. It's easier to build your layout using
div
s and at the end apply a filter like you do with border-radius. SVG would be more suitable if you will only build the shapes and use them as icons or basic images for example but not as a part of a complex layout.A basic example: jsfiddle.net/L4op8kzv/ (you will have a hard time to do the same with only SVG, at least for someone not familiar with SVG)
Another example with a hexagon grid: dev.to/afif/responsive-hexagon-gri...
Some examples from SO: stackoverflow.com/a/62341241/8620333 / stackoverflow.com/a/65726583/8620333
PS: the code works fine on Firefox, clip-path has a good support and the same for filter
PS2: the padding trick is not a hack. it allow me to control the size by changing only one property (the width). Using SVG you will do the same by setting a viewBox and you have to define some explicit value based on the shape there to give an intrinsic ratio (and it's not a hack too)
Great answer!
A couple of scenarios there where CSS is a great choice if you don't care about supporting old browsers / it can fall back gracefully that I hadn't thought about (the hex grid is a great example of something that is far better in CSS, although I would imagine that falls back horribly yet again!).
But I still think SVG would be better for most scenarios.
SVG animation between two states is actually pretty easy as you can use a visual design tool to make the shapes, I would argue doing that in CSS would be more difficult. This can be done without JS too.
The example doesn't work in Firefox as I said, which is another thing to consider for complex shapes (not sure why that last shape doesn't work when the rest do???):
EDIT - the issue is
conic-gradient
on Firefox, removing that it works so it is some interaction between conic gradient and clip-path that isn't working there.And for the second p.s. if you don't add
padding
the shape would collapse and not take up any space. Remove the padding and you will see you do not see an image at all!The exact same technique is use to make space for images that haven't loaded yet to avoid Cumulative Layout Shift and is known as "the CSS padding hack". It is certainly a hack to use padding to give something an intrinsic height, not saying it is a bad thing at all as I have used it before, just an observation!
I just wanted to point out that by the time you are defining polygons in CSS an SVG is better in a lot of scenarios and people need to stop being scared of SVG as it isn't that complicated.
Followed you as can't wait to see what else you put out and with responses like that I am sure I will enjoy reading them / learning from them / debating them with you in the future 😁!
For the firefox thing, I invite you to update your browser because the support of conic-gradient() there is something new but available on the new Firefox Browser.
I am not scared about SVG ;) but I still think there are a lot of cases where CSS can do a better job or let's say an easier one.
Another example without the padding hack and with a responsive behavior (the shape will adjust to the text size and the screen size): jsfiddle.net/8fo9w6s3/ .. I doubt we can easily do this with SVG :)
This said, I am not against SVG but I am a CSS hacker ;)
PS: if you don't like the padding trick we can still consider the use of CSS variables: jsfiddle.net/gxrkqw6d/ or the new
aspect-ratio
property: jsfiddle.net/gxrkqw6d/1/ (still not available on Firefox but works on chrome)Fun debate, I really am sad that I enjoy these types of conversations 🤣🤣
For the firefox thing, I invite you to update your browser because the support of conic-gradient() there is something new but available on the new Firefox Browser.
Firefox is bang up to date, so I am guessing you are on Mac maybe as I am Windows? (the coincidence that your colours nearly match the firefox logo when I took this screenshot made me smile as I am a nerd 😋)
Also looks a bit strange on iPhone browser within dev.to app (guessing Safari based) for some reason (the rounded corners don't work on some parts of the shapes...is very odd I can't pinpoint what is causing that!) but the shapes work fine, that just appears to be some issue with the rounding part.
I am not scared about SVG ;)
I didn't mean you are scared of SVG so apologies there as I didn't phrase that well, I just see loads of posts with people battering CSS to do the job of an SVG and it was meant more as a general observation.
you can easily use media query to adjust the layout
Agree on ease of adjusting layouts, as I said hexagons was a prime example where SVG would not be a logical choice for a layout etc.
I doubt we can easily do this with SVG :)
Also entirely agree on the background jsfiddle with the strange shape "X" with rounded corners, easier in CSS and a prime use case where it would degrade gracefully and not impact the page in any way.
We can rely on CSS variables to easily control the different values (colors, position, size, etc). With SVG most of the control is done with attributes and not all of them have CSS equivalent.
Every single item in SVG can be controlled so not sure what properties you mean here? You can add a class to an item and manipulate it (there is not a single inline style or attribute in the HTML of my old website, which would be near impossible to build in CSS if we are coming up with "SVG can't do that" vs "CSS can't do that" scenarios 😋).
You can translate, scale, change fill colour etc. with no issue. (I may have missed the point you were trying to make here as I am sure there are some things that are difficult).
You can easily add random content when dealing with CSS which is a great thing for accessibility
SVG is great for accessibility though (probably why I am more bothered about support than most as I still have to consider IE11 as a minimum due to 10%+ of screen reader users still using Internet Explorer because of compatibility with their screen reader).
I am also especially in favour of SVG as the preference over CSS as
<title>
and<desc>
provide a lot of baked in support for screen readers if an image has purpose (sadly content: <string> / <alt description> has poor support`. )For decorative only stuff CSS works fine, also for simple shapes it is great too.
if you don't like the padding trick we can still consider the use of CSS variables:
The CSS variable doesn't work for being responsive as it won't resize, so you would have to use some interesting
calc
to make that work in a responsive fashion I presume (or usevw
units I suppose, but that seems messy). In comparison with SVG just set the width to 100% within a container and it will do all the magic for you as you resize the container, maintaining it's aspect ratio unless you tell it otherwise.or the new aspect-ratio property
aspect-ratio
is going to be a game changer, but once again support is the big enemy at the moment. Why we didn't have that years ago is beyond me! I can't wait to be able to use it in production (which at the rate of roll out will hopefully be soon!)I have the same version as yours and I am also on Windows. We are probably facing a strange bug then.
I don’t have any plugins on Firefox so that is the only thing I can think of, maybe there is some strange rendering race conditions going on that a plugin inadvertently fixes?
Either that or display resolution, I’m running 4K monitors? I mean completely grabbing at straws here as same version and same OS should mean consistent results surely lol!
If we get into a position where we can’t even rely on version numbering for feature consistency then we are certainly doomed lol!
I don't know too but try the clip-path and background without the filter. Probably the issue is the filter. Try also outside codepen. Sometimes Codepen & co are buggy
Very healthy and informative debate there, I learned a couple of things from this.
Me too, that’s why I love conversations like this they challenge your perceptions of things you know (or think you know lol!)
I loved you old website @inhuofficial , I was looking for some inspirations for my website and this is great... Can I have a link for your current one please?
Not done yet, we go live in 2 weeks but the url is inhu.co if you want to bookmark it. 10th March is our launch date for the site (and the company!). If you want to drop me a message using the contact form on klu.io I will drop you over the designs as a sneak peak and a few others for inspiration if you want.
Thanks, I really appreciate that. I'll drop you a message :)
how can i remove this strange outline arround the shape?
dev-to-uploads.s3.amazonaws.com/up...
show me the code you are using to get such shape
<div class="svg-container">
<svg viewBox="0 0 202.9 45.5">
<clipPath id="menu" clipPathUnits="objectBoundingBox"
transform="scale(0.0049285362247413 0.021978021978022)">
<path d="M6.7,45.5c5.7,0.1,14.1-0.4,23.3-4c5.7-2.3,9.9-5,18.1-10.5c10.7-7.1,11.8-9.2,20.6-14.3c5-2.9,9.2-5.2,15.2-7
c7.1-2.1,13.3-2.3,17.6-2.1c4.2-0.2,10.5,0.1,17.6,2.1c6.1,1.8,10.2,4.1,15.2,7c8.8,5,9.9,7.1,20.6,14.3c8.3,5.5,12.4,8.2,18.1,10.5
c9.2,3.6,17.6,4.2,23.3,4H6.7z" />
</clipPath>
</svg>
</div>
And there is an empty div that is the real shape
and this is his css
/* The bubble on top */
.menu-border {
position: absolute;
left: 0;
bottom: 99%;
width: 164px;
height: 39px;
/* The magic for the it not being a rectangle */
clip-path: url(#menu);
background-color: var(--bgColorMenu);
}
but you are not using the code I am talking about here. It's something different.
I replied with the code in the previous comment , is it what you asking for ?
Yes but I thought your code was related to the article I wrote. I thought you had an issue after using my code but your code is irrelevant to what I am doing here.
Aw so sorry, I just ran into an issue using clip path so found your article and thought you or someone can help me figure it out !
Can u please help ?
better ask your question on StackOverflow, there you can get help. Here no one will see your comment.
Hi Temani. Great article, thanks!
There is only one issue, this feGaussianBlur filter that rounds the corners removes text from the div to which it's applied.
For me it removed the text from my div. But the text is visible if it's selected.
If there would be text inside these shapes, I think the filter would remove the text. Is that right?
Could you suggest a fix for that?
you should not add any content inside the shape, use the shape as a layer alone and put your content inside another layer on the top of it. Basically 2 divs above each other.
I am not able change the HTML.
It's a div that outputs my post intro text, that is inputted from the WP backend.
I just added the before element to that div.
The div has a clip path applied, and I am successfully rounding its corners with your code, but the text from the div it's gone. But it's still there, it can be selected.
In this case, do you have a recommendation?
You need to make the content outside. This is the only solution. The text should not be inside the div where you apply the filter
Great article! Also, I love that clippy tool you shared too. Will definitely be using that at some point. Cool stuff 😁
Thanks for your article!
But it doesn't work so well for IOS :(