skip to main content
2019-11-01

Theming Legacy SaaS CMS Front-Ends

How I learned to love my necessary funky CSS Selectors

How can you live with yourself?

You have a client who needs this set of pages to match X Y or Z brand guidelines, but the HTML markup on the page wasn’t written by you, and you have no control over it. Most of this comes from the CMS… Sure, go ahead and play with the DOM with JavaScript. Be one of ‘those’ people. You just moved everything around so now you have flashes of content and page jumps, so now you need to add a loader. But the client doesn’t like the loader so you have to go back to square one.

Figure out how to do X with just CSS.

Legacy Markup

So, at Aventri, a lot of code was legacy, with the newer modules being built with Bootstrap 3.

Because the underlying components are based on CMS output, unless you use javascript to change the DOM you are left with some odd and sometimes ugly selector strings to meet the client needs.

I always found myself using their components and then override them with so much CSS it might as well be pointless to use it in the first place, but this is necessary to style the pages to meet brand guidelines.

Except, everything I did at work was based on Bootstrap 3. The back end system was built with it. The front end website builder that clients use relies on it, especially the col-xs, col-sm, col-md grid system to build their columns and layouts. The system widgets use bootstrap 3 based markup with a few customisations on top. So using anything else feels very alien.

So in some newer modules I get to have 80 - 90% control over the markup - even if some of the main elements are generated from Bootstrap 3 elements and unchangeable - which means I get to write some nice code which is meaningful:

header nav.menu-widget.navbar ul.navbar-nav li a {
font: 300 17px/45px, serif;
text-transform: uppercase;
padding: 0;
color: #eff0f2;
}

But in another, legacy module, which may or may not be the primary module of the platform I have control over maybe 5 - 10%. So maybe my code here needs to look like this:

tr.nav-related-vars-container .new-desktop-nav #r-breadcrumbs ul.crumbs li a {
font: 300 17px/22px, serif !important;
text-transform: uppercase;
padding: 0 0 0 30px;
border: 0 !important;
}

Now, this is nothing groundbreaking. But the 2 selectors here that I styled end up on the page looking the same: 2 Navbars with links, but vastly different markup. And yes, some use of SCSS extending % placeholders was used when it could be, but looking at my use of CSS in theming this SaaS product I can find essentially 3 types of CSS Methodology in a single CSS file.
There’s lots of Bootstrap overrides, OOCSS, some BEM mixing ‘-’ and ‘_’ depending on who wrote it that day, and lots of:

#inner_content h3 {
}
#inner_content h2 {
}
body.something p.red {
}

Which kind of equates to no methodology at all. There’s some overriding of bootstrap, some OOCSS, and there’s an id selector in there to override some likely inline !important that was added, or some strange Core SaaS module CSS that was messing with the specificity.

Now, I don’t want to rain on any developers parade and I can see the merits of Utility or Atomic CSS for future development, anything that uses component-based naming, or component-based scoping is really helpful for being able to theme something to look different.

For example:

<header class="site-header">
<div class="logo">
<img src="xx" alt="" />
</div>
<nav>
<ul class="navigation-list">
<li></li>
<li></li>
<li></li>
</ul>
</nav>
</header>

is a lot easier to re-style than:

<header class="flex flex-row flex-wrap">
<div class="logo">
<img src="xx" alt="" />
</div>
<nav class="flex align-center">
<ul class="flex align-center">
<li class="mr-4 hover:underline"></li>
</ul>
</nav>
</header>

My biggest problem with evolving systems that have legacy components is the lack of consistency, in old and new. And the code bloat, mess and hoops and hacks that it requires to make work.