GitHub turns ... turns GitHub ... into elegant Windows 95

  • Tutorial

On Twitter, some time ago, we posted a joke in honor of Microsoft’s acquisition of the GitHub, a website page that was re-styled in the style of Windows 98 . I decided that the joke was too good to be a joke.


The "classic" theme of Windows actually has several iterations. The first versions of Windows (up to 9x) featured white windows, slightly rounded button borders and a very strong pseudo-volume. In Windows 95, the windows became gray, everything became more square, and the lines for creating pseudo-volume were reduced to one pixel. Gradients have been added to Windows 98, but in general the style has remained more or less the same. In Windows 2000, the windows acquired a slightly yellowish tint.

I stopped at Windows 95, and so that colors can be subsequently updated, designed them in the form of CSS variables (well, or "custom properties"):

--color-button-text: rgb(0, 0, 0);
    --color-button-face: rgb(192, 192, 192);
    --color-button-highlight: rgb(255, 255, 255);
    --color-button-shadow: rgb(128, 128, 128);
    --color-button-shadow-dark: rgb(0, 0, 0);
    --color-button-checked: rgb(223, 223, 223);
    --color-window-text: rgb(0, 0, 0);
    --color-window: rgb(255, 255, 255);
    --color-active-caption-text: rgb(255, 255, 255);
    --color-active-caption: rgb(0, 0, 128);
    --color-info-background: rgb(255, 255, 192);
    --color-highlight-text: rgb(255, 255, 255);
    --color-highlight: rgb(0, 0, 128);
    --color-gray-text: rgb(128, 128, 128);
    --color-link: rgb(0, 0, 255);
    --color-hover: rgb(223, 223, 255);


It was not possible to achieve rendering pixel fonts from the browser, so I had to be content with "MS Sans Serif":

body {
    background: var(--color-button-face) !important;
    font: 12px/1.2 MS Sans Serif, MS Reference Sans Serif !important;

In the Windows interface, the font size was almost the same everywhere, so many elements have to be added font: inherit !important;. The color of the text selection can be overridden by n ::selection, but in Firefox for some reason it is still supported only with a prefix.

::selection {
    color: var(--color-highlight-text) !important;
    background: var(--color-highlight) !important;

And since the main font turned out to be readable, I decided to leave the standard font for the code alone and not change it to "Courier New".


The next problem is drawing volume. The borders borderin CSS can still be only in one layer, so for double contours I had to use them box-shadow.

ListBox, TextBox, TreeView ...

For example, paint leafboxes and other white embedded elements:

  .issues-listing > div[class^=border] {
    background: var(--color-window) !important;
    border: solid 1px black !important;
    border-color: var(--box-3d-border-color) !important;
    border-radius: 0!important;
    box-shadow: var(--box-3d-box-shadow) !important;


      0 -1px 0 0 var(--color-button-shadow),
      -1px 0 0 0 var(--color-button-shadow),
      -1px-1px 0 0 var(--color-button-shadow),
      -1px 1px 0 0 var(--color-button-highlight),
      1px 0 0 0 var(--color-button-highlight),
      1px 1px 0 0 var(--color-button-highlight);

This number of shadows is required so that one-pixel “roundings” do not appear on either side (if one shadow goes left up and the other goes right down, then one empty pixel will appear on the right above and below on the left).


We do the same with buttons:

  .pagination > :not(.gap),
  .js-menu-close {
    font: inherit !important;
    font-weight: normal !important;
    background: var(--color-button-face) !important;
    color: var(--color-button-text) !important;
    border: solid 1px transparent !important;
    border-color: var(--button-3d-border-color-exact) !important;
    border-radius: 0!important;
    box-shadow: var(--button-3d-box-shadow-exact) !important;
    margin: 1px2px!important;


      0 -1px 0 0 var(--color-button-highlight),
      -1px 0 0 0 var(--color-button-highlight),
      -1px-1px 0 0 var(--color-button-highlight),
      -1px 1px 0 0 var(--color-button-shadow-dark),
      1px 0 0 0 var(--color-button-shadow-dark),
      1px 1px 0 0 var(--color-button-shadow-dark);

But the elements of the buttons are bigger, when you click, the border style changes, and there is also a dotted focus rectangle. Focus draw already using outline- the third CSS property for "borders".

  .js-menu-closesvg {
    fill: var(--color-window-text) !important;
  #user-links.dropdown.dropdown-caret {
    color: var(--color-window-text) !important;
    border-top-color: var(--color-window-text) !important;
  [open] > .btn,
  .pagination > :active,
  .js-menu-close:active {
    border-color: var(--color-button-shadow) !important;
  .subnav-item:focus {
    outline: dotted 1pxvar(--color-button-text) !important;
    outline-offset: -4px!important;


Tabs have rounded tabs. Fortunately, browsers can draw rounded corners, and you can set roundness for each corner.

  .select-menu-taba {
    font-size: 12px;
    font-weight: normal !important;
    color: var(--color-button-text) !important;
    background: var(--color-button-face) !important;
    border: solid 1px transparent !important;
    border-color: var(--button-3d-border-color) !important;
    border-bottom: none !important;
    border-radius: 2px2px00!important;
    margin: 01px -1px0!important;
    padding: 4px6px!important;
    min-height: 26px;

Little things are left: the gray text of the disabled tabs and the absence of a border on the current ones (the absence of a border is realized by lowering the eye under the tab contents using negative indents):

  .select-menu-taba.selected {
    margin: -2px1px1px0!important;
    min-height: 28px;
  .tabnav-tabsspan:not(.Counter) {
    color: var(--color-gray-text) !important;


Borders around element groups are drawn depressed. It would seem that you can use all sorts of grooveand ridge, but no, the specific colors for them can not be set, and rendering in different browsers is very different. We return to the proven method:

  .commit-tease {
    font: inherit !important;
    color: inherit !important;
    line-height: 20px!important;
    background: var(--color-button-face) !important;
    border: solid 1px black !important;
    border-color: var(--group-3d-border-color) !important;
    border-radius: 0!important;
    box-shadow: var(--group-3d-box-shadow) !important;
    position: relative !important;
    padding: 12px8px4px8px;
    margin-top: 2px!important;

However, a group of elements without a title no longer looks like a group. Let's add headlines in at least some places.

.js-notice > .border::before,
  .commit-tease::before {
    color: var(--color-button-text) !important;
    background: var(--color-button-face) !important;
    position: absolute;
    left: 6px;
    top: -11px;
    padding: 03px;
  .js-notice > .border::before {
    content: "Notice";
  .commit-tease::before {
    content: "Last commit";


There are more windows, tooltips and more, but they are unremarkable.


We will extract the icons in the old old-fashioned way, which all old people will surely remember - with the help of Resource Hacker . You will not believe: the program is still alive, still honest frivara and still evolving. So we take the Windows 95 distribution and go through all the binaries, choosing beautiful icons ...

Now, many hours later, it's time to put the icons in CSS. To do this, we extract individual icons from ICO to PNG (I used the Imagine plugin for Total Commander, but in general any program that understands the format will do), optimize to the last bit (I used ) and encode it as a Data URI in CSS ( Base64 service was quite convenient). It turns out like this:


.octicon-file-directory, .octicon-file {
    fill: transparent !important;
    width: 16px!important;
    height: 16px!important;
  .octicon-file-directory { background: var(--image-folder) !important; }
  .octicon-file { background: var(--image-file-text) !important; }

Finishing touches

The site has a huge number of styles, so you have to go everywhere and stylize everything. Both the “buttons” and the “listboxes” have rather different classes. There are also a lot of little things like round-sized meters that would be logical to convert to bare text, as you would have done in the days of Windows 95:

.Counter {
    background: inherit !important;
    font: inherit !important;
    color: inherit !important;
    padding: 0!important;
  .Counter::before {
    content: "(";
  .Counter::after {
    content: ")";


Since we are modern people, we will issue a "standardized" header for UserCSS, which is supported by Stylus:

/* ==UserStyle==
@name        GitHub Windows Edition [Ath]
@version     0.5.0
@description Transforms GitHub's pages into GUI resembling Windows 9x.
@author      Athari
@license     MIT
==/UserStyle== */

Now, if you open such a file in the browser, the extension will offer to apply the style and will follow the updates. And you do not need any dubious


Well, more or less. The style is rather in the stage of proof-of-concept / alpha, because many pages are not completely re-arranged. But a start has been made!

If you have extensions for user-styles, then here are the direct links to the installation:

PS Carefully, Stylish has recently been removed from the list of Firefox and Chrome extensions for spying. I advise you to switch to the modern open-sorted expansion of Stylus, if you have not already done so.

Also popular now: