I Meant To Write Something Else, But I Can't Stop Playing with Pico.css
I have plenty of articles in my //TODO list, but I found something that really brings the dopamine for a serial side project starter that isn't as good at css as he'd like to be.
I was taking a look at Tailwind
After all the discussion, and having my eye on it for quite some time, I decided to finally take a look at Tailwind CSS, and while watching a video to get a high level view of it, the creator said something that started a free fall into my latest obsession. "I usually reserve Tailwind for larger projects and use Pico for small projects and prototypes"
Now I had something else to look up, and boy am I glad I did. You see, I love semantic html. I pine for the days when navbars were made with <nav>
. When we knew that just because something had an onclick
event, it didn't mean you should use it as a <button>
. The days when, if you had tabular data, you put that in a <table>
!
So you can imagine my delight when I found Pico CSS, a small, mostly classless stylesheet that used semantic html to build simple, but very pleasant web UI's. I couldn't stop myself from pulling up VS Code, and tooling up a quick greeting page for a sample Blackjack app.
No joke, the following took me < 5 minutes:
In about a half hour, I'd tooled out most of the actual game UI:
With a little work and my own custom CSS, I probably could have gotten unicode card characters to work with a better font and larger size, but out of the box, they didn't render well with Pico.
Okay, So Now What
None of this means anything if we can't actually play BlackJack, let's try and add this to a Blazor app. A simple blackjack app has no persistence, so as standalone WASM app will work fine for our purposes.
My first approach was to continue using Pico as I had been, simply linking the cdn. When I did a few things felt... off.
Firstly, the padding between my bank/betting <header>
and my <main>
playmat looks all wrong, and there was this strange white border around the "Bank $975" <h1>
.
The weird outline kept going away as soon as I clicked anywhere on the page, so I decided to tackle the padding first.
Semantic Layout and Root Elements
Pico is built around semantic html, and by default it applies styles to <header>
, <main>
, and <footer>
tags that are immediate children of <body>
. This works great for static html, this does not work great for Blazor WASM. Blazor needs a root element, and by default it's a <div id="app">
at the top of <body>
, which means when my content was moved to the Home
component, <header>
and <main>
where immediate children to a <div>
, so the styling wasn't correct.
Pico has a fix for this.
When you import Pico CSS with Sass, you can specify your root element, what we need in Blazor is something like this:
@use "pico" with (
$semantic-root-element: "#app",
$enable-semantic-container: true,
);
Just one problem. I'm not using Pico with Sass.
Sassy Blazor
I didn't want to hack together a solution. I am after all trying to lay the groundwork for a system which will help me reliably get up and running with my next side project. So I set out to find out how adding Sass to Blazor works. I found this article written by Adrian Hall, and it was just what I was looking for. Using this as a guide, I added the WebCompiler extension for Visual Studio, and compiled a sass file into app.min.css
, which I have since renamed customPico.min.css
Once that was done, I needed to get the Pico .scss
source files, and they provided instructions on how to do this with npm or yarn.
npm install @picocss/pico
Just one problem. I don't want to use npm or yarn.
First, I simply went to the Pico CSS github repo, and downloaded the latest release, and stuffed the .scss
files into my project. Worked well enough, but not exactly maintainable.
LibMan to the Rescue
While clicking around my project, I noticed something very curious I've never noticed before.
Recent versions of Visual Studio ship with a client side library manager, all I had to do was point it at the unpkg
source, do a quick search for @picocss
and I even got to select only the .scss
files I needed instead of the whole package.
Sure the resulting folder structure was picocss/pico/scss
but I can live with that all things considered.
Adding the finishing touches
Once I had that setup, I ended up with a very short customPico.scss
file
@use "picocss/pico/scss/pico" with (
$semantic-root-element: "#app",
$enable-semantic-container: true,
$theme-color: "cyan"
);
Then, I linked it to the index.html
file of my wwwroot
folder
<link rel="stylesheet" href="customPico.min.css" />
That just left that weird white border, and that turned out to be a one line fix after consulting the oracles on r/Blazor, simply removing this from my App.razor
file did the trick
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
And now my Blazor app matched my static html
Conclusion
I plan on building out the rest of this BlackJack app using Blazor and Pico CSS, but in getting set up I learned some valuable lessons for using this wonderful classless (read: less classes) css framework with Blazor.