WordPress Page Builders Suck for Styling Websites

“Bold headline, Cotton.”

Relax. Don’t get all up in your feelings right away. Could you give me a second to explain?

Page Builders are great. My web design agency uses them exclusively. I teach people how to use them. My favorite is Bricks Builder.

This article isn’t paragraph after paragraph of me shitting on page builders. But I’m not going to thoroughly kiss their ass, either, because there *is* a big problem with them.

And yes, this problem exists even if you’re using a professional page builder rather than one of the Fisher Price builders like Elementor, Divi, or Beaver Builder. And it exists in non-WordPress page builders like Webflow (but I don’t care much about those).

You should agree with me by the end of this article. Or, perhaps not. Either way, you’re free to sound off, and we can still be friends.

Why WordPress page builders are great

Page builders exist to make building websites simpler. They provide a GUI for a situation that typically requires writing line after line of code.

What kind of code? HTML, PHP, and CSS, for the most part.

Professional options like Bricks and Oxygen do a great job writing HTML and PHP. You drag elements onto your page, configure loops, nest things, add attributes, and you can even change the semantic tags.

How do we know these builders are good at this? Because the code output is clean, accurate, and flexible. That’s a massive problem with those kiddie builders I mentioned earlier. The code they produce is a pile of **** an HTML landfill.

The professional builders don’t limit you like the others, either. You can drop in any custom code you want without issue. You more or less have complete control.

If you don’t know how to write HTML (or you find it as tedious as I do), and PHP has you all confused (that’s even me sometimes), then page builders are easily worth their weight in kilobytes.

They also dramatically speed up workflow over the option of writing the code yourself. Accomplishing things you can’t do is one thing, but doing it even faster than someone who *can* do it is another.

Where page builders fall on their face is with the CSS side of things.

<page builder marketing department enters the chat>

All you have to do to style an element in a page builder is click on the element, find the style you want to edit, adjust the value, and save the changes! No CSS knowledge is necessary!

<page builder marketing department exits the chat>

Sounds easy enough. And it is.

The code output is sound, too. Page builders can write A LOT of CSS for you.

If you don’t know CSS, this is a clear benefit. But, unlike with HTML and PHP, this is where the benefits end.

Styling elements in a page builder isn’t faster, cleaner, or more efficient than if you could write the CSS on your own. There are some significant limitations when using a page builder…

Scattered styles

When you write CSS by hand, especially if you use BEM, and even more so if you use Sass, the CSS for any given element is all in one place.

.my-block {
  display: flex;
  flex-direction: column;
  background-color: var(--base);
  font-size: var(--text-s);
  padding: var(--space-m);
  gap: var(--card-gap);
}

.my-block__heading {
  color: var(--base-ultra-light);
  font-size: var(--h2);
}

.my-block__heading::after {
  content: '';
  display: flex;
  background-color: var(--base-ultra-light);
  width: 100%;
  height: 1px;
  padding-top: var(--card-gap);
}

I can see exactly what’s going on by looking at one area, and any changes I need to make can all be completed in one place. And that’s without sass.

In a page builder, though, I cannot see the styling at a glance. Not only do you have to click into panel after panel and accordion after accordion to set the styles in the first place, but you also have to repeat that dance any time you want to make a change.

A simple card with a heading, paragraph, and button means multiple panels across multiple elements. And that assumes everything in the page builder canvas is even clickable. For example, pseudo-elements are typically in a different location and not accessible from the structure panel where all your other elements are.

This is an efficiency nightmare. Something that should take seconds takes minutes and dozens of clicks. Repeat ad nauseam for days on end.

Deciphering styling

Another issue with scattered styling is that it makes styling hard to decipher. If you’re working on a team or with a design set like Frames, it means you’re working with elements you didn’t build yourself.

Any time you’re working with an element someone else built, you first need to figure out how they structured it and styled it to the point it’s currently at.

Determining structure in a page builder is easy, thanks to the structure panel. Determining styling instructions? Not so much.

Sure, most builders have these styling indicators:

Page Builder Styling Indication
Bricks Builder Styling Indication

But first, that requires that you click the class. And maybe before you click the class, you have to note anything done at the ID level.

Once you see that styling was done to the “layout” tab at the class level, you still need to open that tab and see what’s happening. And guess what? Other nested panels may very well live inside that tab.

Oh, there’s a pseudo-element in play? Well, that’s not accessible from the structure panel or these class tabs. That lives somewhere else entirely (in its own set of panels)!

Now you can scroll back up to that block of sample code I posted earlier. See how everything is in one place? And since I use BEM, you can tell how a block is structured by looking at the CSS class names.

Speaking of BEM…

Page builders aren’t really BEM or compound selector compatible

I know. I teach BEM. In page builders! And here I am saying page builders aren’t fully compatible with BEM.

First, let me clarify that they’re “compatible enough.” It’s not a total lost cause. They could be better, though (and I’m lobbying hard for Bricks to be better at it).

See, page builders really only work with primary selectors:

.my-card {
  background-color: var(--base-light);
}

They can’t handle compound selectors:

.my-card--dark .my-card__heading {
  background-color: var(--base-light);
}

This is a common scenario in BEM. When you modify a block, you often create compound selectors to modify that block’s elements.

Can you do this in a page builder? Nope, you have to write CSS for it. And guess what? The minute you write CSS, you’ve made the “scattered styles” problem even worse. Now there’s a third or fourth place you or others may need to look to understand how a component was styled.

It’s not just BEM, either. Complex selectors are tremendously important in CSS, and page builders can’t handle them *at all* (other than writing your own CSS).

Need to select all direct children of an element (.selector > *)? Can’t do that.

Need to do a lot of :nth-child work? Can’t do that, either.

Need to use powerful new features like :where()? Nope.

Need to style siblings? Good luck.

Need to style adjacent siblings? Why are you so needy?

Target attributes (in any capacity)? Nah.

Style children on hover? Pfff. Calm down fancy pants!

There’s no native support for locally scoped variables

A locally scoped variable is a variable whose value is only accessible to the element that defines it as well as that element’s children.

.custom-block {
   --local-variable: value;
}Code language: CSS (css)

When a variable is locally scoped, it can only be used within that specific element or within its children.

One significant advantage of locally scoped variables is that you can name them whatever you want. You can even use very generic names that might get repeated elsewhere.

Why use locally scoped variables?

  1. DRY methodology. As a principle, any time you’re about to repeat a style instruction, consider using a variable instead. This is just good practice in general for efficiency and maintainability purposes.
  2. Style & behavior editing from a central location (efficiency). By placing locally scoped variables in a parent, you can establish a single source of control for that element and all its children.
  3. Simplification of complex styling/behavior (simplicity & efficiency). Providing variables allows anyone to quickly change style values without deciphering complex CSS code.
  4. Simplification of mobile adjustments (simplicity & maintainability). When adjusting elements on mobile, locally scoped variables can be redefined at a different breakpoint rather than re-writing the full styling instructions over again.

There are more benefits, of course, but this is an article on something other than locally scoped variables. The bottom line is that you can’t create locally scoped variables in page builders without writing CSS. In some page builders, this is a complete no-go.

Don’t even get me started on the fact that many page builders still don’t support variables at all. The Fisher-Price builders don’t support variables, nor does Gutenberg, WordPress’ native dumpster fire. It’s shameful.

Okay, enough. What’s the takeaway?

As I said in the beginning, I love page builders. They’re great for many reasons.

I clearly don’t love the CSS/styling limitations and issues.

What’s the solution? What should we do about it?

Well, for those of you who are comfortable writing CSS, I’m going to propose a question:

Should we use page builders exclusively for HTML and PHP efficiency and then do ALL styling by hand in a tool like WPCodeBox?

Let me ask that again after reminding you that my fifth argument (which I spared you from having to read) was going to be the lack of Sass support in page builders. A tool like WPCodeBox has the benefit of letting you write Sass for maximum power and efficiency. Does this influence your answer in any way?

I’m seriously considering doing this for my next build. No styling whatsoever in the page builder.

What say you?

join the conversation

14 comments

  • The solution you propose at the end is actually the way we’ve always done it when building websites with a page builder:

    1. Use the page builder to construct the page layouts, content, widgets, etc.
    2. Handle all styling through the theme’s (or child theme’s) CSS.

    This always seemed like the most logical way to keep *most* of the CSS organized in one place, be able to easily override CSS from any plugins used, and most importantly – not have to go make changes to element styling on every single page in the event some type of element or style needs to be updated. (This is less of concern nowadays, but in the older days of something like Elementor, there were no global style settings). But we also love writing CSS. Obviously someone who doesn’t would not want to work this way.

  • I thought about doing all styles in WPCodeBox but never pulled the trigger. Kevin, in one of your more recent videos you commented about wanting to keep the styles and CSS within the builder as much as possible instead of going outside the builder (e.g. WPCodeBox). Is this so it’s better for your target audience or is there another reason?

  • Let’s not ignore the fact that on any given website with a page builder, it’s impossible to not also have separate CSS. There is just no way to do ALL CSS in the editor, but it is true we can pretty much do ALL CSS not using the editor. Given the editor will likely set some global defaults and what not, but beyond that, we don’t need it except to assign the classes themselves.

    We still get the most power from strait SCSS files organized in a folder structure where proper partials/includes can happen and complete and proper parsing, compiling, minifying, prefixes can happen.

    It’s impossible to use only the editor when we start adding other plugins and shortcodes and things into the design. Inserting forms or anything else complex. We are forced to style those suckers and override their styles through our own CSS due to the long complex selectors and other tricks.

    I still mix the two and just try to use classes with BEM names, then only style the basic settings in the editor. Only the advanced CSS ends up living elsewhere, which is ok to me because then my custom CSS isn’t completely bloated with all the base level and simple styles, it just focuses on the more difficult stuff, making it smaller to deal with. An entire website might only have one external style sheet with a couple hundred lines that couldn’t go in the editor. It’s still pretty easy to manage.

    Whenever I need to troubleshoot CSS, I go to web dev tools first, because whatever style I find will either be loaded from the pagebuilder compiled CSS, or my external one, so it’s easy to tell where to look for the style.

  • Anthony DeCrescenzo

    I’ve settled on my workflow in WP and I’m very happy with it, even as a WP Codebox Agency license holder.

    I do my local/SCSS development in Visual Studio Code, auto-watching and auto-compiling my SCSS. My child theme (always —ALWAYS— a child theme) functions.php enqueues the minified output and, voila, it’s done. If I preview the site via VSC’s Live Server, then the changes auto-update the same way WP Codebox promises to.

    I’ve used WP Codebox but found it a bit finicky and less responsive than this setup, and found that the auto-update/refresh sometimes simply refuses to work. I revisit it with every new project to see if my opinion changes any, but right now I’m happy with this arrangement.

    Given how much my ADD likes to tinker its way down rabbit holes, I’ll take any win that begins with “right now I’m happy with this arrangement.” 😉

  • Michael

    I agree with most of this and am pretty much down to using either Cwicly or Bricks for most of my work. Some things Cwicly does that I like and are lacking in most other builders are:

    – Relative styles for building complex selectors, including pseudo elements/classes, nth-child, etc… which allows you to use the visual styling tools for selectors that are relative to the one you’re currently working on. Selectors can be applied downstream and upstream, which is incredibly handy.
    – SCSS support is built into their global stylesheets, which is actually better than WPCodeBox’s current implementation in some ways because it autoprefixes everything that needs it and minimizes the output. It doesn’t support partials yet, but I prefer having autoprefixer more than partials personally. It also works well if you want style everything via CSS rather than the visual styling tools, while keeping all CSS in one place within the builder.
    – It allows you to separate classes into groups. You have global styles, which are similar to how Bricks implements styles, but Cwicly also allows you to import selectors that can be used as Virtual Classes. This allows you to import the CSS or selectors from a framework, such as ACSS, where it will strip out all of the classes (it doesn’t keep the actual CSS, so that can be added via WPCodebox or the ACSS plugin), but lets you pick the classes from a list that you can easily manage within the builder. So global classes that are styled within the builder, or virtual classes which are used for CSS that exists outside the builder. You can also group stylesheets, global classes, and virtual classes into folders to keep everything organized and tidy.

    Now Cwicly isn’t perfect, but it’s come a long way and is continuing to improve all the time. It offers a built-in fluid typography “creator” for creating clamp scales if you don’t use something like ACSS, but doesn’t offer this for other sizing fields like margins and padding yet. It offers built in interactions, conditions, and tons of dynamic data options, full site templating, role management, custom fonts, custom icons, etc…, so definitely worth checking out.

    Bricks is also great, but also has some things that make it a little clunky. Either one, though, is better than most of the other options out there that I’ve looked into.

  • Patrick

    Hey Kevin, great article.

    Writing inside the builder soon becomes a nightmare as the site grows. It doesn’t pass the 3 months rule and it’s not maintainable and scalable on the long run.
    For all those reasons, I stick to wpcodebox, which also brings sass functionality and cloud saving.
    P.

  • Love this! I will definately be trying to style things exclusively with WP Codebox. A few sites I had to hand code a few pages because they weren’t in Wordpress and I will say I found it monumentally simpler.

    • Kareem

      Already Done that!
      The day I decided to move to Bricks and got my hands on WPCodebox, I did that all in it.
      Main Reasons:
      – If I want to transition to any builder, it won’t be hard if it’s a Pro tool.
      – I write RTL & LTR. It’s very complex to deal with on the same site etc…
      So I use Sass & WPCodebox instead of the builder stylesheet! Was WOW.

      Regards
      P.S. I’ve never used Bricks to write CSS code. and I was from time to time using the Pseudo settings in it after the last video from Kevin I decided to keep it all in WPCodebox too cuz it’s sucks and a waste of time and confusing to manage/edit😅.

      • Pedro Bartulihe

        Do you still think that keep all the style in WPcodebox better than use the editor? I tested a little simple things and seems faster to use the bricks instead wpcodebox, but I don’t know in the long curve to maintenance. In wpcodebox it’s more organized, but I don’t know if worth the time.

    • A

      I’ve yet to do a full site exclusively in Codebox, but I plan too very soon.

      • Amanda

        Making a series about the WPCodebox process would make great Inner Circle content.

      • Michael

        I haven’t done one exclusively in WPCodebox either, but I recently did one that’s half and half, where the custom classes were all hand coded in it. I agree with you on the simplicity of keeping everything in one place. I think we try to improve things with new tools, but in the process, end up making things more complicated than they need to be. Then we end up keeping the parts of the new tools that are actually useful and going back to the original ways of doing things for the parts that become more cumbersome.

        Builders like Bricks and Cwicly absolutely make it much faster and easier to build websites, but by the time you click here and there on every block to try and style it, you could have just hand-coded it and been done with it. Plus you have complete control over everything. This is another reason I like the idea of using frameworks like ACSS for their variables, where you can set your settings and then hand-code using variables to keep everything consistent and easier to manage in the future.

Leave your comment

Kevin Geary

Kevin is the CEO of Digital Gravy, creator of Automatic.css, creator of Frames, and a passionate WordPress educator. If you're interested in learning directly from Kevin, you can join his 1500+ member Inner Circle.

More articles like this

related posts