DEV Community

Astrit
Astrit

Posted on • Edited on

Set a Cookie with CSS

I try to learn new stuff by creating challenges for myself and often end up becoming a full fledged project.

This time was the challenge to do a project on CSS, HTML & PHP no database, store the data on json or as flat file system just to give you some context.

Now it came the part where a cookie would solve some issues like storing the data for the user options but I did not like the fact to refresh the page just to setup a cookie.

Right at that moment I remembered:
Crooked Style Sheets - https://github.com/jbtronics/CrookedStyleSheets

This guy did a basically tracking system in CSS by using the background-image url value to call a php link where you can do whatever action you choose.

So here is what I did:

#dark-mode:checked~main [for="dark-mode"]::after {content: url('/?a=dark-mode')}

/* Previous solution looks a bit ugly but it can be set as background-image also*/ 
#dark-mode {background-image: url('/?a=dark-mode')}
Enter fullscreen mode Exit fullscreen mode

Actions on php:

$action = false;

if (isset($_REQUEST['a'])) {
    $action = $_REQUEST['a'];
}

switch ($action) {
    case "dark-mode":
        setcookie("Dark Mode", "active", time() + (86400 * 365), "/");
        break;
    case "light":
        setcookie("Dark Mode", "", time() - 3600);
        unset($_COOKIE['Dark Mode']);
        break;
}
Enter fullscreen mode Exit fullscreen mode

Note that I unset the cookie instead of just changing the content on case:light

The most interesting fact is when you set a cookie this way you see how the cookie will appear directly.

Based on this then I setup a conditional statement for the checkbox

 if(isset($_COOKIE['Dark Mode']) && $_COOKIE['Dark Mode'] == "active") { echo "checked" ; }
Enter fullscreen mode Exit fullscreen mode

And here you are free to refresh and even close the tab with settings stored.

Basically this is just to scratch the surface but it opens doors to a lot more possibilities.

However special attention is needed on macOS Safari.

Right now is not possible to have modifiers on url() but that is subject to change at least will hope so.

Some examples:

.selector { background-image: url(/img/attr(data-bg).webp) }
Enter fullscreen mode Exit fullscreen mode

Or set cookie based on attribute

.selector { content: url(/?action=attr(data-action)) }
Enter fullscreen mode Exit fullscreen mode

"url-modifier" is still a experimental API
https://developer.mozilla.org/en-US/docs/Web/CSS/url()

Bonus:

/* this works too if you want to call action on page load */
body { background-image: url(/?action=action_name) }
Enter fullscreen mode Exit fullscreen mode

Thanks for reading.
Astrit.

Top comments (2)

Collapse
 
alohci profile image
Nicholas Stimpson • Edited

Cute. But when does the url resolve and the cookie get set? e.g. for

#dark-mode:checked~main [for="dark-mode"]::after {content: url('/?a=dark-mode')}

is it the first time the #dark-mode element gets checked?

Collapse
 
astrit profile image
Astrit • Edited

If I understand correctly what you said, yes the cookie is set on the first time so as soon it is checked the the cookie is set.

To unset it you could do:

#dark-mode:checked:active~main [for="dark-mode"]::after {content: url('/?a=light')}

Or if you want to play a bit more clean and you set appearance to none on input you can use the content url directly on input.

#inputId:checked::after { content: url('/?action=action-name') }

/*

This requires the #inputId to have 
appearance:none; or -webkit-appearance:none;

*/

Or if you feel a bit snazzy you can set the cookie even as background-image, I have tested and it works.

#dark-mode:checked {background-image: url('/?action=action-case')}