How to recreate 2020 Google Maps icon's shape without SVG?
Asked Answered
B

2

7

I'm trying to recreate Google Maps's icon (2020). The colorful background and the donut hole are easy enough: I just need some gradients and a mask.

Here's a snippet that shows my current efforts (and a codepen, if you want to play with it):

:root {
  --1-3: calc(100% / 3);
  --2-3: calc(100% / 3 * 2);
  --sqrt-2: 1.4142135624;
  
  --hole-diameter: calc(100% / var(--sqrt-2) / 3);
  
  --red: #ea4335;
  --yellow: #fbbc04;
  --green: #34a853;
  --blue: #1a73e8;
  --azure: #4285f4;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
}

#wrapper {
  margin: 3em auto;
  width: 10em;
  background: linear-gradient(90deg, #c0392b, #8e44ad);
}

#icon {
  --mask: radial-gradient(
    circle at center,
    transparent calc(var(--hole-diameter) - 1px),
    #000 calc(var(--hole-diameter) + 1px)
  );
  
  border-radius: 50% 50% 50% 0;
  aspect-ratio: 1 / 1;
  background:
    linear-gradient(
      180deg,
      var(--red) var(--1-3),
      var(--yellow) var(--1-3) var(--2-3),
      var(--green) var(--2-3)
    ),
    linear-gradient(
      180deg,
      var(--blue) var(--1-3),
      var(--azure) var(--1-3) var(--2-3),
      var(--green) var(--2-3)
    ) calc(100% - 1px);
  background-size: 50% 100%;
  background-repeat: no-repeat;
  -webkit-mask: var(--mask);
  mask: var(--mask);
  rotate: -45deg;
}
<div id="wrapper">
  <div id="icon"></div>
</div>

However, I can't wrap my head around its peculiar shape. Is it possible to create such a shape with CSS only?

It should be obvious that I'm not looking for an SVG-based solution. I'm doing this as a pet project, so I just need something that works in at least one browser.

Bronchiole answered 22/6, 2023 at 11:23 Comment(11)
To enhance the shape, you can experiment with additional CSS properties like border-radius, transform, and box-shadow to fine-tune the curves and shadows. keep in mind that css has limitation i hope this can be helpfulGlyptograph
@ELMEHDIACHAHED I'm afraid that is not useful at all. If I could find such a combination I wouldn't have to ask.Bronchiole
@Bronchiole In that case you should edit the title of your question to be explicit, e.g. "How can I recreate the 2020 Google Maps logo using only CSS box properties and built-in functions without any SVG?" - because otherwise everyone's going to say "use background-image: url("data:{inline SVG logo}");).Pun
Honestly I prefer your sharp-corner version over Google Maps' official logo :)Pun
That does look nice on its own might, indeed :) Edited the title to clarify the problem.Bronchiole
Can we use CSS Shapes? Or the path() function? Technically it isn't SVG, but it does let you use SVG paths in CSS for things like masking and more.Pun
@Pun That sounds good enough to be posted as an answer, though I prefer not having to resort to a path.Bronchiole
I'm working on something that almost-kinda works btw.Pun
I was thinking that the "tip" of the logo and its general shape connected to the larger circle could be modelled as a metaball-like goo - so I made a blur-based metaball parameter editor on codepen and I get a kiiiinda similar shape with Opacity: 1, Blur: 204, Spread: 100, Contrast 50 - but this approach won't work unless there's a white background - nor can this be used as a mask-image - oh well...Pun
That metaball trick looks so cool; I learn something new today. Thanks for trying.Bronchiole
@Bronchiole I've posted my alternative solution as an answerPun
D
2

An approximation with one element that should work in all the browsers:

.logo {
  width: 200px; /* control the size */
  aspect-ratio: .7;
  background:
   linear-gradient(130deg,#0000 53%,#34a853 53.5%),
   conic-gradient(from 40deg at 36% 26%, #4285f4 25%,#fbbc04 0 50%,#ea4335 0 75%, #1a73e8 0);
  -webkit-mask:
    radial-gradient(#000 69%,#0000 71%) 
     bottom/10% 9% no-repeat,
    radial-gradient(92% 173% at 100% 116%,#0000 98%,#000) 
     100% 97%/50% 18% no-repeat,
    radial-gradient(92% 173% at 0%   116%,#0000 98%,#000) 
     0%   97%/50% 18% no-repeat,
    conic-gradient(from -35deg at 50% 90%,#000 70deg,#0000 0)
     bottom/100% 43% no-repeat,
    radial-gradient(#0000 27%,#000 28% 70%,#0000 71%)
     top   /100% 70% no-repeat;
  
  display: inline-block;
}

html {
  min-height: 100%;
  background: repeating-linear-gradient(-45deg, #fff 0 20px, #f9f9f9 0 40px);
  text-align: center;
}
<div class="logo"></div>

<img src="https://upload.wikimedia.org/wikipedia/commons/a/aa/Google_Maps_icon_(2020).svg" width="200">
Dorsiventral answered 26/6, 2023 at 10:7 Comment(1)
Looks a bit ruggy. Could you smooth it out?Bronchiole
P
2

Here's the best I could come up with, by abusing multiple radial-gradient, -webkit-mask-image, -webkit-mask-image-composite and, unfortunately: a sibling-element for the "pointy-bit" instead of being able to extend the original #icon, nor use an ::after element (as the ::after element will be clipped by the mask of its parent).

(I suppose this could be re-organized to make the circular part at the top use ::before and the pointy-bit use ::after and otherwise have #icon serve only as a container and bounds for its two psedoelement children, but that's an exercise left for the reader).

This is how it looks in Chrome. I haven't tested in any other browsers:

enter image description here


:root {
    --1-3: calc(30%);
  --2-3: calc(70%);
    --sqrt-2: 1.41421356237;
    --inner-radius: calc(18.4%);

    --red: #ea4335;
    --yellow: #fbbc04;
    --green: #34a853;
    --blue: #1a73e8;
    --azure: #4285f4;
}

* {
    box-sizing: border-box;
}

body {
    margin: 0;
}

#wrapper {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2em;
    margin: 1em;
}

#wrapper > div {
    border-radius: 1em;
    background: linear-gradient(90deg, #c0392b, #8e44ad);
  overflow: hidden;
}
#wrapper > div > h2 {
  font-family: sans-serif;
    text-align: center;
  background-color: white;
  border-radius: 0.25em;
  width: 90%;
  margin-left: auto;
  margin-right: auto;
}

#image > img {
  transform-origin: 50% 35%;
  /*transform: rotate(50deg);*/
}

#icon {
    aspect-ratio: 1 / 1;
  background-image:
        linear-gradient(
            180deg,
            var(--red) var(--1-3),
            var(--yellow) var(--1-3) var(--2-3),
            var(--green) var(--2-3)
        ),
        linear-gradient(
            180deg,
            var(--blue) var(--1-3),
            var(--azure) var(--1-3) var(--2-3),
            var(--green) var(--2-3)
        );
    
    background-position-x: 0, calc(100% - 1px);
    background-position-y: 0, 0;
    
    background-size: 50% 100%;
    background-repeat: no-repeat;

    -webkit-mask-image:
    /* The radius of the circle at 100% is actually the corners of the bounding rect, not the perpendicular top+bottom/side edges, hence the weird numbers. */
    radial-gradient(
      circle at center,
      transparent 28.2%,
      black       calc(28.2% + 1px),
      black       70%,
      transparent calc(70.0% + 1px)
    );
    
    rotate: -50deg;
  
  z-index: 10;
}

#tip {
  aspect-ratio: 26 / 25;
  width: 100%;
  background-color: #47A756;
  margin-top: -14.2%; /* this is relative to the #tip element's *width* btw. */
  z-index: 5;
  background-image:
    linear-gradient(
      130deg,
      var(--yellow) 0% 25.5%,
      var(--green) 25.5%
    );
  
  background-size: cover;
  background-repeat: no-repeat;

  -webkit-mask-repeat: no-repeat;
  -webkit-mask-image:
    radial-gradient( ellipse 127.3% 100% at -85.62% 60.5%, transparent 0%, transparent 100%, black 100% ),
    radial-gradient( ellipse 127.3% 100% at 185.62% 60.5%, transparent 0%, transparent 100%, black 100% ),
    linear-gradient( to bottom, black 55%, transparent 50% ),
    radial-gradient( ellipse 8.4% 8.8% at 50% 55%, black 100%, transparent 100% );

/* https://tympanus.net/codrops/css_reference/mask-composite/ */
  -webkit-mask-composite:
    source-in,
    source-in,
    source-over;
}
<div id="wrapper">
    
  <div id="image">
    <h2>Google Maps Logo SVG</h2>
    <img src="https://upload.wikimedia.org/wikipedia/commons/a/aa/Google_Maps_icon_(2020).svg" alt="Google Maps icon"/>
    </div>
    
  <div id="attempt">
    <h2>Image-Mask Abuse</h2>
    <div id="icon"></div>
    <div id="tip"></div>
    
  </div>
</div>
Pun answered 23/6, 2023 at 15:33 Comment(3)
Looks acceptable. I'm starting a bounty as soon as SO lets me, and if there's no better answer I'll mark this as accepted as well as giving it the bounty.Bronchiole
"...I haven't tested in any other browsers" - this is how it looks in Firefox (114.02/Ubuntu 23.04): i.sstatic.net/Jp5ID.png (and that screenshot is after I correct the apparent margin-top typo in the #tip rule-set)).Hover
@DavidThomas lolPun
D
2

An approximation with one element that should work in all the browsers:

.logo {
  width: 200px; /* control the size */
  aspect-ratio: .7;
  background:
   linear-gradient(130deg,#0000 53%,#34a853 53.5%),
   conic-gradient(from 40deg at 36% 26%, #4285f4 25%,#fbbc04 0 50%,#ea4335 0 75%, #1a73e8 0);
  -webkit-mask:
    radial-gradient(#000 69%,#0000 71%) 
     bottom/10% 9% no-repeat,
    radial-gradient(92% 173% at 100% 116%,#0000 98%,#000) 
     100% 97%/50% 18% no-repeat,
    radial-gradient(92% 173% at 0%   116%,#0000 98%,#000) 
     0%   97%/50% 18% no-repeat,
    conic-gradient(from -35deg at 50% 90%,#000 70deg,#0000 0)
     bottom/100% 43% no-repeat,
    radial-gradient(#0000 27%,#000 28% 70%,#0000 71%)
     top   /100% 70% no-repeat;
  
  display: inline-block;
}

html {
  min-height: 100%;
  background: repeating-linear-gradient(-45deg, #fff 0 20px, #f9f9f9 0 40px);
  text-align: center;
}
<div class="logo"></div>

<img src="https://upload.wikimedia.org/wikipedia/commons/a/aa/Google_Maps_icon_(2020).svg" width="200">
Dorsiventral answered 26/6, 2023 at 10:7 Comment(1)
Looks a bit ruggy. Could you smooth it out?Bronchiole

© 2022 - 2024 — McMap. All rights reserved.