Theming Semantic UI with create-react-app

Semantic UI’s default styling is great, but it’s not the end-all/be-all of web design. Semantic’s versatility in terms of build options is great for quickly deploying something beautiful, but it’s confusing when you want to customize it with your own fonts/colors/etc.

This blog post contains the recipe I used for going from default Semantic UI settings to a “Hello World” page using Arial instead of Lato as the site-wide font- kind of a “Hello World” for styling. It assumes you already have experience deploying React apps with create-react-app and have some familiarity with Semantic UI.

Create the React App

Run create-react-app to build your basic front-end. Nothing unusual here.

Install Gulp

Gulp is Semantic UI’s task runner. In layman’s terms: when you customize your Semantic Build, Gulp will merge and minify it into semantic.min.css, etc. so your app can refer to a single file for custom styling or other tweaks.

Run npm install gulp to install it.

Install Semantic UI

Semantic has various configurations of how to do this, depending on your level of customization.

Run npm install semantic-ui-react to use Semantic as a library of React components.

Run npm install semantic-ui to deploy a fully-customizable Semantic build. The docs suggest doing a yarn add instead of npm install, but Yarn failed to actually install Semantic (it’s a known issue right now).

Choose Express Setup when Semantic prompts you. The create-react-app build right now requires you to install Semantic UI in your project’s example-app/src/ directory (as opposed to your root example-app/ directory, which is the Automatic install setting).

Semantic UI needs to live inside example-app/src/semantic/ because your create-react-app instance won’t have permission to look outside the example-app/src/ directory.

Build Your Semantic Library

Run gulp build inside example-app/src/semantic/ to create your default Semantic install.

Run gulp watch inside example-app/src/semantic/ to have Gulp automatically update Semantic when you make changes to your theme.

Customize your Site theme

Now we’re operating within example-app/src/semantic/. The docs can get confusing because Semantic UI has its own /src/ directory as well. For brevity at this point, keep in mind when I refer to /semantic/src/ I’m talking about example-app/src/semantic/src.

You can customize the site theme at src/site/. This can be confusing because you’d think your theming should take place in src/themes/ cuz logic.

Without diving down a rabbit hole about theming options, I choose to customize the site theme because it has the final say on how your CSS comes out. The site theme overrides everything that comes before it.

Inside /site/globals/ you’ll find a file called site.variables, which is where we’ll finally change some base styles.

Drop in this snippet to change the theme font to Arial:

@emSize: 13px;
@fontSize: 13px;
@fontName: 'Arial';

Import Semantic UI CSS

Within your app’s src/index.js file, add the following import line:

import './semantic/dist/semantic.min.css';

This is the minified CSS file your Gulp task runner will build whenever you make changes to your site theme.

Errors? Outta Luck.

Don’t expect any indication you’ve done something wrong when editing your Semantic UI theme. If it doesn’t like your CSS for any reason, Semantic will default back to its original settings.

Mailing it in

I’ve wanted to put out tons more ideas and content than I’ve managed to produce. The problem is rarely lack of ideas or even lack of time. What’s held me back so often has been over-design of my former portfolio site.

It’s hardly a secret most designers will do almost anything to avoid learning how to code. For my part, I can definitely own up to stuffing in way too many plugins, auto-generating some smelly freaking code to try and save time. Case in point:

<!-- .et_pb_section -->

<!-- Wow much Div! Such classes! -->
<div class="et_pb_section  et_pb_section_1 et_section_regular">
<div class=" et_pb_row et_pb_row_0">
<div class="et_pb_column et_pb_column_4_4  et_pb_column_0 et-last-child">
<div class="et_pb_text et_pb_module et_pb_bg_layout_light et_pb_text_align_center  et_pb_text_0">
<div class="et_pb_text_inner">

<!-- OMGGG AN H1 SPLENDID -->
<h1>This is my flow state</h1>


</div>
</div> 
<!-- .et_pb_text -->

The old portfolio site is an example of something that outwardly looks great (IMHO) but fails beneath the hood. I built it using Divi- a modular builder (now with the option of a full visual builder). Divi is simple enough for designers who want to avoid coding, and robust enough to let someone with medium-level CSS skills bang out something gorgeous pretty quickly.

Easy design led to over-design for me though, and ultimately stagnation. I’d find myself painstakingly tweaking margins and padding on Every. Single. Div. This meant every post had to be a masterpiece to justify the time I spent laying it out. I could never “just write”.

So now for the redemption story:

At the Flatiron School I’ve completed upwards of 200 labs, and each has simple, appealing formatting applied to a readme written in markdown. I had heard of markdown but never explored it until I saw the “back-end” of these readme.md files in Atom.

Flatiron School requires students to blog on various tech/coding-related topics, so the issue of over-designed blog posts came to a head soon after I started coding bootcamp. I already knew my old Divi code smelled to High Heaven, so the idea of redesigning from the ground up was already on my roadmap.

I built this new site on a base theme called Underscores, which is little more than bare-bones scaffolding for a WordPress install. Being pressed for time I wanted to write as much pure, repeatable CSS as I could, with the least amount of vendor functionality/design conflicts.

and the coup-de-grace:

Markdown integration, with email-to-post functionality. This is the inaugural post. I wrote it entirely on the Notes app on my iPhone and fired it off to WordPress!

I do my best thinking and writing on the train, so prepare for a whole lot more from me 🤗

(Not gonna lie- I went back in on the computer to add code and images I couldn’t easily drop in from my phone. Writing the content like this and emailing in saved me a boatload of time on putting this together though…)

Mark Bello

Mark Bello