circle-flags
circle-flags copied to clipboard
Create square-flags directory and a script to generate them
Also add a gallery of square flags (rendered here).
Background
In commit db685c546c, the strategy used to make the flags circular was changed from a <mask>
to a border-radius
style attribute.
I assumed this would allow users to dynamically change the shape of the flags using just CSS to edit the border radius (perhaps even animating it!).
However, it doesn't seem to be possible to change the border radius of SVG files at embed time in an HTML file. (Expand this for details of what I tried.)
I tried various approaches: copying the
<svg>
file directly into the page, and loading it using<img>
,<object>
and<embed>
, then changing the border radius via CSS:<!DOCTYPE html> <html lang="en"> <head> <style> svg, img, object, object svg, embed, embed svg { border-radius: 0%; } </style> </head> <body> <svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewPort="0 0 512 512" style="border-radius: 50%"> <rect x="0" y="0" width="512" height="512" fill="#eee"/> <circle cx="256" cy="256" r="112" fill="#d80027"/> </svg> <img src="https://hatscripts.github.io/circle-flags/flags/jp.svg"> <object data="https://hatscripts.github.io/circle-flags/flags/jp.svg" type="image/svg+xml"></object> <embed type="image/svg+xml" src="https://hatscripts.github.io/circle-flags/flags/jp.svg" /> </body> </html>
None of them worked. I also tried adding
style="border-radius: 0%"
to the<img>
,<object>
and<embed>
elements, to no avail. The only thing that kinda worked was using!important
in the CSS rule; this worked only for the inlined SVG. But that feels hacky, and in any case copying the SVG content of the flags into the target location is not scalable, unless you use some sort of build step.
So I went ahead and generated square versions of the flags (which are simply the same files without the border-radius
style hardcoded into the SVG), tucked into a separate directory, so that people can use them and apply the border-radius
themselves. So doing e.g.
<img src="https://hatscripts.github.io/circle-flags/square-flags/jp.svg" width="48">
would yield:
I've tested these square icons, and changing the border-radius
via CSS now properly applies to all four methods of embedding the images (<svg>
, <img>
, <object>
and <embed>
)! :tada:
If this PR is accepted, we would support users to generate all sorts of extra shapes, like e.g. the rounded square look (border-radius: 25%
) hinted here.
By the way, in response to the following note from a comment in #11:
One drawback to this approach is of course that applying custom masks (such as a squircle) is no longer possible. A squircle can (hypothetically) be made with pure CSS, but it's far more verbose than just using a
clipPath
.
We can actually use circles, ellipses, and arbitrary polygons using the clip-path property in CSS — see https://bennettfeely.com/clippy/ for a bunch of examples.
What's more, even a squircle is kind of possible, by approximating the shape using SVG-defined curves! For example, see the relatively simple geometry by @nklunder in https://codepen.io/nklunder/pen/ZrxbZO. Unfortunately it doesn't seem to be possible to define the clip-path
as an inline SVG document (encoded as a data URL), like this:
clip-path: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='0' height='0'%3E%3Cdefs%3E%3CclipPath id='squircle' clipPathUnits='objectBoundingBox'%3E%3Cpath d='M .5,0 C .1,0 0,.1 0,.5 0,.9 .1,1 .5,1 .9,1 1,.9 1,.5 1,.1 .9,0 .5,0 Z'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E");
But the separate SVG element as shown in the CodePen link above is certainly viable! And besides, we can always use a linear-segment approximation to a squircle by using a polygon, which does allow a pure-CSS approach to implementing a squircle clip shape, like this:
clip-path: polygon(50% 0%, 36.37% 0.5%, 30.53% 1.19%, 25.31% 2.19%, 20.68% 3.54%, 16.6% 5.27%, 13% 7.42%, 10% 10%, 7.42% 13%, 5.27% 16.6%, 3.54% 20.68%, 2.19% 25.31%, 1.19% 30.53%, 0.5% 36.37%, 0% 50%, 0.5% 63.63%, 1.18% 69.47%, 2.18% 74.69%, 3.53% 79.32%, 5.26% 83.32%, 7.4% 86.87%, 9.98% 89.87%, 12.98% 92.45%, 16.53% 94.59%, 20.53% 96.32%, 25.16% 97.67%, 30.38% 98.67%, 36.22% 99.35%, 49.85% 99.85%, 63.48% 99.35%, 69.32% 98.67%, 74.54% 97.67%, 79.17% 96.31%, 83.17% 94.57%, 86.72% 92.42%, 89.72% 89.83%, 92.3% 86.83%, 94.44% 83.28%, 96.17% 79.28%, 97.52% 74.64%, 98.52% 69.42%, 99.2% 63.58%, 100% 50%, 99.50% 36.37%, 98.82% 30.53%, 97.82% 25.31%, 96.46% 20.68%, 94.74% 16.6%, 92.59% 13%, 90% 10%, 86.95% 7.42%, 83.4% 5.27%, 79.32% 3.54%, 74.69% 2.19%, 69.48% 1.19%, 63.64% 0.5%, 50% 0%);
The difference between this and the SVG shape with the curves is barely noticeable:
(SVG clip-path on the left, polygon approximation on the right)
Regarding what I wrote above:
I've tested these square icons, and the border-radius now properly applies to all four methods of embedding the images (
<svg>
,<img>
,<object>
and<embed>
)! :tada:
...I just pushed a new commit tweaking the square flags to merely have no border-radius attribute, rather than explicitly setting it to zero. That allows even inlined versions of these flags to be restyled using border-radius
in CSS without resorting to the !important
hack :)