This weekend, I set out to make a little Personal Home Page, and what better way than to use old-school PHP, HTML, and CSS to make something gimmicky and fun. I decided to make a page that looks kinda like a Windows desktop. And just for fun, I decided to do it with no JS, just to see how far I could get.

Taskbar and iFrames

I had already made a few simple HTML/PHP minigames on their own web pages, so I thought it would be fun to load them into iframes for the "windows" on the desktop. I used the <details> tag to represent both a window and its button in the taskbar.

The <details> tag is a newer HTML tag with "click-to-open" functionality. If you write the following:

<details>
    <summary>Open me...</summary>
    <p>Hello world!</p>
</details>

You'll see that you can click what's inside <summary> to display the rest of the contents, as below:

Open me...

Hello world!

Naturally, the <summary> tag will be used for the taskbar buttons, and the windows will be what they "open" and "close". The general format looks something like this:

<div id="os">
    <div id="taskbar">
        <details>
            <summary>Window Title</summary>
            <div class="window">
                ...
            </div>
        </details>
    </div>
</div>

To style this, I absolutely position all of the windows (.window) relative to the #os div, but leave the rest of the elements (including the #taskbar) unpositioned. Then, I use flexbox to align #taskbar to the bottom of #os. What results is that the <summary> elements remain aligned inside of #taskbar at the bottom of the screen, and the .window elements can be positioned freely within #os.

Each "window" is simply another <details> element. I positioned the windows according to what I felt looked nice and well utilized the space. Sure, they don't have close buttons and you can't drag and drop them, but I still got pretty far forgoing JS!

Radio Button Tabs

One of my windows is a fake web browser - there's no URL bar, but there will be tabs where it can load a couple external web pages, including this blog. I used radio buttons to mimic the functionality of browser tabs.

There were three parts to this:

  1. The radio buttons (<input> elements)
  2. The radio button labels (<label> elements)
  3. The actual tabs (.tab elements containing the iframes)

The key is that all of these must be siblings, so that we can write CSS for the selected tab using input:checked ~ .tab. (The ~ here means "a sibling of" in CSS.)

Once this structure is in place, I added CSS to hide the radio buttons (we only want to see their labels), position the tabs on top of each other, hide tabs by default, and unhide the selected tab. With that, tabbing functionality was in place. The rest was just a little styling and polish to make it look good.

The Clock

I wanted to add a clock to the right-hand corner of the page just like a real desktop, but without using setInterval() or any JS. To do this, I created a time.php page containing a meta tag to auto-refresh on the minute.

The following meta tag will cause a page to refresh itself every 30 seconds. The number of seconds to wait is determined by the content attribute.

<meta http-equiv="refresh" content="30">

To make it refresh on the minute, I used PHP to calculate how many seconds are left until the next minute, and use this for the content attribute.

<meta http-equiv="refresh" content="<?= 60 - date('s') ?>">

Then, I simply write out the time on the actual page.

<?php
    date_default_timezone_set('America/New_York');
    echo date('h:i A');
?>

Finally, I loaded time.php inside an iFrame in the "taskbar" on the actual home page. The contents of the iFrame refresh on the minute, forming a dynamic clock!

You can see the finished version, with all of its other bells and whistles, at cheshire.gay.

AI Note

As an aside, cheshire.gay was one of my first projects where I used AI in its creation:

  • Stable Diffusion generated the background images for all of the themes except for the Webmaster theme.
  • ChatGPT generated all of the code for the guestbook page, including code for a secret admin page where I can delete guestbook entries.
  • I also used ChatGPT throughout as a Google alternative for general coding questions, or when I didn't feel like consulting documentation.

It's really cool how AI can help you code and create, and I'm excited to see how the future with AI will look as a developer.