4
3 Comments

Why & How I built css.gg - A life story

Ok, where do I start.

  • First thanks to Peter Thaleikis for suggesting this.
  • Second is not very technical.
  • Third is personal.
  • Fourth not as usual, stupid but real.

The why ?

Some times is not the reason why you think that drives a project forward.

To give you just some context on why css.gg happened at all I need to tell you that one of few things I love in life is CSS. I have learned all in my own no educational degree so that is why you might see some unusual stuff here and there.

On December 2018 I had to take one of the biggest decisions on my life at the time and that was quitting the company I co-founded because it had turned into a toxic - money chase working environment.

I felt like I was becoming obsolete on the role of the CTO, I felt that I was forgetting the reason why I started to do web on the first place.

I wanted to return again on the very basics.

Web was a passion as kid, luckily enough became a profession and I would not lose this passion for anything in this world.

As a result I did quit and started to work as freelancer and this project.

Now you know why in my own I wrote 506 icons in CSS and 90 waiting to be published.

The How ?

Version control:
Github all day, interface and just the set of features for me is much better than any other solution, I do not care who owns it, people will own my code so.
Check the source: https://github.com/astrit/css.gg

Tool:
VS Code - no explanation needed.

Name:
Initial it was named as "CSSpod" where I would post CSS pod's as codepen style but only CSS, when I saw css.gg was free I decided to go with it and the app would be called same since where ever is shared the domain would be on the brand and no way to lose visitors specially how competitive CSS as keyword is.

Stack:
I challenged first my self that this is not going to be a project guided by trends and built it on React, Vue or any other framework.
I wanted it to be just CSS, HTML & PHP.

Design:
Then I started designing icons one by one directly in CSS no figma, sketch or any other tool at that time I had all in my mind what I wanted to do but did not lay down any practical plan so you get it, I could lie here that I did a style guide page and a system behind it. No I did not.

Time to start:
After quite some research on what style would I follow plus considering what properties I could use, I decided to do a outlined minimalistic set inspired be feathericons.com by Cole Bemis (This guy is a wonderful human being)

Markup:
Markup was one of the obstacles to overcome but in the end it turned out good. Initially I used void tags such as

<!-- 
This was a no go since you must have nothing after it
or it would wrap it. Stupid. 
-->
<gg-icon-name /> 

<!--
Then did this which was simply ugly for icons with long names
-->
<gg-long-icon-name></gg-long-icon-name> 

<!--
In the end decided to do it like font-awesome with the <i></i> tag.
--> 
<i class="gg-icon-name"></i>

Why there are no self-closing void tags >> https://github.com/w3c/webcomponents/issues/624

Also one condition was to have only 1 element with pseudo selectors no more.

Naming:
To name the icons I added "gg-" to prevent duplication and since it was normal CSS it could mix with the rest of style. Also a little bit of branding on each icon.

Why Classes:
Classes because after Id a class is highest on specificity level for more: https://dev.to/emmawedekind/css-specificity-1kca

No general class:
One of the main things I decided right at this time was that I would not do a general class to add on each icon such as "gg-style" or something to contain repeating properties such as:

.gg-icon-name {
    display:block;
    box-sizing: border-box;
    position: relative;
} 

This would complicate things a-lot, icons would not be as depended as they are right now when you select just one or few not as package tho.

Database:
This kind of project of course you need a database, no I did not. I have every icon as single php file which contains main stuff such as tags, name, template. I do list icons from a .json file so practically is a flat file system or static call it how you want.

Coloring:
To color a icon was quite important question since if I applied hex, rgb, or hsl would make it a nightmare for other people to change every single on, replace or god forbid to use !important to overwrite;

/* currentColor to the rescue */ 
.gg-icon-name {
   color: currentColor; 
   background-color: currentColor; 
   border: 0 solid currentColor;
   box-shadow: 0 0 0 currentColor;
}

This way where ever you color the parent it will inherit that color and we are good to go.

Sizing
This along color was something people would tweak for the icons, so my solution was to create a custom CSS variable and resize with transform

.gg-icon-name {
    transform: scale(var(--ggs),1);
}
/* 1 is for fallback reasons if some one is mad enough to use this on IE* /

For me using em or other units wasn't feasible at the time and depend the icon sizing on the paragraph, wanted to have something to control it directly since the variable can be added on the parent, body or :root.

Disclaimer: this article https://css-tricks.com/css-gg/ when it was written I think it wasn't very clear how the sizing works so I added now a box on the https://css.gg/app directly how to resize.

Main page:
I did the page as simple as I could with focus to explicitly explain what this library is about, would show icons on random order each time page is refreshed.

App page:
Or web app if I may call it was built as a simple grid with options to select a single icon alla Google Fonts style read the markup or download the same icon with filters and a simple search.
BTW the sidebar and filter is hidden with CSS, it sets a cookie via CSS and on the next time you visit based on cookie style will be applied.

I highly recommend to check the source.

Color preview:
This feature wasn't a must but nice addition to just check on how they look with other colors plus it was like a customization proof and a why not moment.

Single icon page:
This was designed with as much information as possible, you would see the icon before coming to the page but here you would see all specs and lear on the right side preview how it was done and why not copy the style directly.

In future I will add on some of them videos how I built as tutorial for beginners.

Also on page are related to the icon section for a better experience.

NPM
For those who use react, vue or any other framework could take advantage plus the CDN availability.

API or json object, XML
This is not quite an API but somewhat since it is public, no token and just the data is provided as json and easy way to transfer data between apps, for React, Vue & Angular projects.
https://css.gg/json is a php page not a real json file.

<?php
  header('Content-Type: application/json');
  $data = array();
  $i = 0;
  $cont = array();

  // icon loop

  echo json_encode($data);
?>

Same applies to "CSS" - https://css.gg/c and "XML" - https://css.gg/xml

CDN
I was aware that I could not provide a high end server to host it so I had gone with these alternatives which come any way after you publish on NPM.

JSON
https://unpkg.com/css.gg
https://cdn.jsdelivr.net/npm/css.gg

CSS
https://unpkg.com/css.gg/icons-compressed/icons.css
https://cdn.jsdelivr.net/npm/css.gg/icons-compressed/icons.css

XML
https://unpkg.com/css.gg/icons-xml/icons.xml
https://cdn.jsdelivr.net/npm/css.gg/icons-xml/icons.xml

Animations
Well they are CSS-only so it is possible to animate at the end of the day so check some examples:

Tracking:
Ok this is the most nuts thing on the project.
I came to this point with no JS keep in mind so now comes the time when you have to do it, as I have said to my first article here I used Crooked Stylesheet method where I set a cookie from PHP as content on css

Like this:

/* Track download: increment on a .log file */  
a:active::before { content: url(/action?=download-icon-name); }

/* Track selection: set a cookie */ 
#icon-name:selected~main .gg-icon-name::before { content: url(/action?=select-icon-name); }

/* Track sizing: set a cookie */
#size-xl:selected~main [for="size-xl"]::before { content: url(/action?=size-xl); } 

Page views, json calls, xml calls, css calls are recorded on a log file when you call the url, single page example:

    $namer = pathinfo($_SERVER["SCRIPT_FILENAME"], PATHINFO_FILENAME);
    $counter_name = $_SERVER["DOCUMENT_ROOT"] . "/one/log/" . $namer . ".log";
    if (!file_exists($counter_name)) {
        $f = fopen($counter_name, "w");
        fwrite($f,"0");
        fclose($f);
    }
    $f = fopen($counter_name,"r");
    $counterVal = fread($f, filesize($counter_name));
    fclose($f);
    $counterVal++;
    $f = fopen($counter_name, "w");
    fwrite($f, $counterVal);
    fclose($f);

Minify
I did minify all content with a php function along gzip compression on htaccess:

function ob_html_compress($buf){
	return preg_replace(
        array('/<!--(.*)-->/Uis',"/[[:blank:]]+/", '/(\>)\s*(\<)/m'),
        array('',' ', '$1$2'),
        str_replace(array("\n","\t"),'',$buf));
}
ob_start("ob_html_compress");

Marketing:
All I did when launching this project was to just stay active on the communities here at dev.to, indiehackers.com, reddit.com etc. That's it no boosted posts, no paid articles nothing.

Also this is on Product Hunt: https://www.producthunt.com/posts/css-gg

Again this article: https://css-tricks.com/css-gg/ shows clearly on how it was written the main tagline "The 🌎's first icon library designed by code." obviously that is removed now since I realized is not fair at all, thanks to Chris Coyer for bringing it up.

Thumbs up to Nicolas Gallagher - http://nicolasgallagher.com/pure-css-gui-icons/demo/ who did it similarly not quite the same 10 years ago.

Description
I made on the end of each icon a automated description which would rotate depending on the properties used and some fancy words for the sake of SEO.

For who is this:
For those who love CSS for those who care to the bit for the page speed and want to have something out of ordinary.

I would love to know what Addy Osmani thinks about this.

What I was looking for:
No views, no likes, no recognition no nothing just needed to put it out there and be me. But I got way more.

Outcome

  • Is this perfect? Hell NO, some might say stupid. I welcome suggestions.
  • I learned a ton of things from this project.
  • 150 Stars github >> https://github.com/astrit/css.gg
  • Feedback from the man, the one & only Cole Bemis - feathericons.com "The design and execution look stellar 💯"
  • 81 Upvotes on Product Hunt
  • A ton of shares on Twitter
  • and much more that I can't list here.

The reason I said this is personal is that I am trying to express how I felt on the beginning of the year and where I am now on the best just HAPPY, freelancing and full of energy to continue on 2020 and I want to inspire you do the same, make the difference make what you love no matter what it is, feel fulfilled and don't listen any thing else that will make you stop.

If nothing this gave me confidence.

At the end of the day this is just another icon set in CSS not the first for sure, not the best but is part of me and something that made me write 17,000+ lines CSS like it was nothing, all manually.

Thanks to all of you here on Indie Hackers for being part of this.

  1. 2

    I was absolutely stoked about your website when a friend of mine shared it recently!

    I looked through it, the design is so slick, and your pricing is so awesomely designed that if i would use it in a project, i wouldn't hesitate to send $10 dollars your way.

    But what's holding me back to consider using it is that i can't use the icons in sketch where I'm designing my software.

    Reading this post gave me the idea of transforming css to SVG so i could use it in sketch. But that wasn't possible.

    Then i thought of the illustrator feature of making a picture into vector, and i thought, this would work perfectly with icons.

    So i quickly found https://www.pngtosvg.com/ took a screenshot of one of your icons, pasted it on the site and clicked generate. And the outcome was a perfect SVG representation of the icon! https://res.cloudinary.com/histudios/image/upload/v1577141412/image2vector_txkmcn.svg

    I guess you could automate this process using a Continuous Integration tool, a puppeteer browser to spin up a single icon, take a screenshot and transform it to SVG using something like this https://github.com/Iwasawafag/node-potrace.

    Then you could provide an SVG alternative as well for the designers who are using conventional design tools with correct naming, and the developers and the users of the websites would be pleased with the Lightweight, Accessible, Agile, Retina Ready'ness of the CSS icons they load.

    Just a thought :)

    But i will check out your icons again with my newfound knowledge, it's not a lot of work to transform the icons i'm interested in myself so i can use them in sketch :)

    1. 1

      Wow , this is awesome, thanks for taking the time to do this research and I think I will do exactly this, if you do a pull request with the same idea on the repo I will make sure when this is done to add you as contributor.

      It is a matter of time when this will be done. Thank you once more.

      1. 1

        you’re very welcome :)

        If you haven’t gotten around it after New Years, i will take a look at it :) I’m going afk for snowboarding the next week. I think I have a good idea on how to pull it off :)

        And again, thank you for making such beautiful icons

Trending on Indie Hackers
After 10M+ Views, 13k+ Upvotes: The Reddit Strategy That Worked for Me! 42 comments Getting first 908 Paid Signups by Spending $353 ONLY. 24 comments 🔥Roast my one-man design agency website 21 comments I talked to 8 SaaS founders, these are the most common SaaS tools they use 20 comments What are your cold outreach conversion rates? Top 3 Metrics And Benchmarks To Track 19 comments Hero Section Copywriting Framework that Converts 3x 12 comments