Can't use flex/grid with Slots

Builder content link

Builder public api key
4a52b3b8ac444b998a4f90d60aa6fcc3

What are you trying to accomplish
I want to create a Symbol that enriches a flex (or grid) container with some extra styles.

Problem
The Slot generates an intermediary <div class='css-12m0k8p'> between itself and its children. That means that neither flex nor grid will allow the children to flow properly. There doesn’t seem to be any way to target styles to the direct parent of the children.

If it helps, .css-12m0k8p only adds pointer-events: auto.

I can solve this by adding a CSS class to my Slot (e.g. my-slot) and then adding some custom CSS:

.my-slot > div > .builder-blocks {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

It works, but I see a few drawbacks:

  1. the styles are hidden away in the custom CSS panel
  2. Builder adds the same <style> tag to the DOM for every instance of my Symbol
  3. it will break if Builder changes the DOM structure of a Slot

Hi @balleverte,

By default, Builder adds some default styles to each block/layer (e.g. flexbox layout), but you have the option to turn off adding these default styles and use your own CSS styles if that helps. Turning off Use default styles may make some style controls, such as alignment, not behave as expected.

To turn off Use default styles

  1. Go to the Account Settings
  2. Click on more options for Advanced settings by clicking on the pencil icon
  3. Select the Editor Tab, and
  4. Turn off Use default styles

Let us know if you have. any further questions. Thank you!


That was actually my first guess! But sadly it has no effect on this <div>. I’ve disabled the setting and re-published all the relevant content to be sure.

Hi @balleverte,

Thank you for your feedback! We’re always looking to improve our documentation and product. Currently, I don’t think there is a direct way of achieving this. But maybe you could use some custom code or create your own custom slot component, also if you would like you can submit a feature request at Builder.io Ideas.

Let us know if you have any further questions. Thank you!

Thanks for the link. I added a feature-request.

This code in React SDK suggests that it’s possible to customize the Symbol’s builderBlock.tagName, but I can’t figure out where I would do that centrally. (I can do it on an instance-by-instance basis in whatever documents use the Symbol, but the whole point of the Symbol is that I want editors to be able to use it without having to edit its settings.)

Hi @balleverte,

You may find help on that at Creating a Symbol with a React Component inside

It’s a great doc, but it doesn’t help with this use-case. Perhaps some code would help.

Here’s a plain (non-Builder) version of what I want:

.main-and-sidebar {
  display: grid;
  grid-template-columns: [main-start] 2fr [main-end sidebar-start] 1fr [sidebar-end];
}

/* by default, content shows up in the main column */
.main-and-sidebar > * {
  grid-column: sidebar-start / sidebar-end;
  grid-row: sidebar-start / sidebar-end;
}

/* content marked as "sidebar" shows up in the sidebar */
.main-and-sidebar > aside {
  grid-column: sidebar-start / sidebar-end;
  grid-row: sidebar-start / sidebar-end;
}

@media only screen and (max-width: 992px) {
  .main-and-sidebar {
    grid-template-columns: 1fr;
    grid-auto-rows: [sidebar-start] auto [sidebar-end main-start] auto [main-end];
  }
}
<div class="main-and-sidebar">
  <aside class='sidebar'>This shows to the right on wide devices</aside>
  <div>This shows to the left on wide devices</div>
  <div>This also shows to the left on wide devices</div>
</div>

What I want to do is turn the <aside><Slot /></aside> into a Symbol so editors can just drop them into the flow and have content show up in the sidebar without knowing about grid CSS:

// Builder's Layer View
MainAndSidebar
  SidebarContent
    This shows to the right…
  Box
    This shows to the left…
  Box
    This also shows to the…

If I put the <Slot> into a Symbol and give the Slot tagName=aside, it generates this:

<div class="main-and-sidebar">
  <div class="symbol builder-block">
    <div class="builder-blocks">
      <aside class="slot">
        <div class="builder-blocks">
          <span>
            <p>This shows to the right…</p>

So the .main-and-sidebar > aside CSS rule can’t apply. The <aside> needs to be the direct child of the grid container – without intervening <div>s – in order for grid layout to work.

I could change it to .main-and-sidebar > :is(:has(aside)), but :has isn’t supported on Firefox yet.

Hi @balleverte,

Currently, I’m not sure if this is possible by using the builder blocks because of nested div as you have tested, but maybe you can use custom code blocks to achieve this.

I can absolutely create the structure with a custom code component. The problem is that a single parent-and-children component doesn’t give the editing experience we want. This image shows what we’re looking for:
Screen Shot 2022-11-23 at 9.53.52 AM

The editor can drag in as many Sidebar components as they want and each one shows in the sidebar column.

(The built-in Columns component seems like it would be a good fit, but it editors would have to add a Columns component for each row in order to get the sidebar content to align vertically with the main-column content it corresponds to.)

Hi @balleverte,

How about using custom code blocks to create the parent-and-children components and convert the flex child to builder symbols to give editing experience, will that give you a solution?