Why & How I built css.gg - A life story. 
Tags: html, css, php, webdev
Published: 2019-12-22 21:10:41

Ok, where do I start. 

* First thanks to [Peter Thaleikis](https://peterthaleikis.com) for suggesting this. 
* Second is not very technical. 
* Third is personal.


## 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](https://css.gg) happened at all I need to tell you that one of few things I love 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 world. 

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


## The How ? 
Version control:
Github all day, interface and just the feature set for me top.

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](https://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](https://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 
```html 
<!-- 
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:
```css
.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;
```css
/* 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 
```css
.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
<?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.
```txt
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: 
* https://css.gg/loadbar
* https://css.gg/loadbar-alt
* https://css.gg/loadbar-doc
* https://css.gg/loadbar-sound

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: 
```css
/* 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:  
```php 
    $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: 
```php 
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.

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. 
* 300+ Stars - https://github.com/astrit/css.gg
* Feedback from the man, the one & only [Cole Bemis](https://twitter.com/colebemis) - feathericons.com "The design and execution look stellar 💯" 
* 100+ Upvotes on Product Hunt
* A ton of shares on Twitter
* and much more that I can't list here. 

Reason why I said this is personal was that it really is part of a journey 

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.

If you like please consider becoming a Github sponsor
https://github.com/sponsors/astrit

Peace ✌️
Astrit