HatScripts / circle-flags

A collection of 400+ minimal circular SVG country, state and language flags
https://hatscripts.github.io/circle-flags
MIT License
928 stars 248 forks source link

Create square-flags directory and a script to generate them #51

Open waldyrious opened 2 years ago

waldyrious commented 2 years ago

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 `` file directly into the page, and loading it using ``, `` and ``, > then changing the border radius via CSS: > > ```html > > > > > > > > > > > > > > > > > > > ``` > > None of them worked. I also tried adding `style="border-radius: 0%"` to the ``, `` and `` 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.

waldyrious commented 2 years ago

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:

image

(SVG clip-path on the left, polygon approximation on the right)

waldyrious commented 2 years ago

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 :)