johnwalley / allotment

A React component for resizable split views
https://allotment.mulberryhousesoftware.com/
MIT License
943 stars 52 forks source link

Control z-index of allotment sash and separator border #366

Open adri1wald opened 2 years ago

adri1wald commented 2 years ago

Hi I need to be able to control the allotment sash and separator border z-index.

Can I do this by overriding allotment css classes?

Edit: can't figure this out without using data attrs. Would be awesome if you exposed some css variables to control the z-index of these.

johnwalley commented 2 years ago

Hi @adri1wald. Thanks for reporting this. As you have discovered there is no way to do this currently.

I will add something that lets you style the sashes.

johnwalley commented 2 years ago

You can track progress in #375.

johnwalley commented 2 years ago

I've released this as v1.15.0. There should now be a sash class on the sash element.

I'd be grateful if you could let me know how you get on. I'm particularly interested in if people run into specificity problems.

adri1wald commented 2 years ago

Thank you @johnwalley. Will give this a test today or tomorrow!

adri1wald commented 2 years ago

Hey @johnwalley it seems the exposed classes are placed before the internal ones so it's not possible to override z-index without applying !important

johnwalley commented 2 years ago

Thanks for trying it out.

I'm not a css expert but I'll try to explain what I think is going on. For selector rules with the same specificity it's basically last one wins. Therefore it's important that your custom css for .sash {} appears after that for the internal styles allotment defines. Usually, this is as simple as making sure import "style.css" appears after import "allotment/dist/style.css".

There are also some allotment css rules with higher specificity which will just be hard to override without increasing the specificity of your own rules.

I'll write up some documentation: #397

adri1wald commented 2 years ago

Heya thanks for clarifying. I've now made sure to import our css after allotment. The .sash selector is now taking precedence over the internal one, but my .split-view-view:not(:first-child)::before selector is not. Maybe it's not specific enough.

Also would be awesome if you could namespace the classes so that there's minimal risk of overlap with other classes: e.g. allotment-sash, allotment-split-view-view, ...

Cheers!

johnwalley commented 2 years ago

I'm struggling to find the time to do the documentation for applying styles. The specificity thing is a pain. Material UI have the same issue: https://mui.com/material-ui/guides/interoperability/#deeper-elements. Ultimately, you need your rule to be more specific, or the same specificity and appear later.

For example, the selector which is overriding your .split-view-view:not(:first-child)::before is probably

.splitView.separatorBorder
  > .splitViewContainer
  > .splitViewView:not(:first-child)::before

which has a specificity of 3(4?) (the algorithm is involved: https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity#how_is_specificity_calculated).

Looking at the above I think I've spotted a bug because I'm not adding a separator-border class to the 'split-view' element. Which means you can't replicate the compound selector exactly.

johnwalley commented 2 years ago

D'oh! Of course I should have namespaced the classes. I already have an issue open to namespace css variables so I just forgot to do this.

I might leave this for v2 as it probably deserves to be a breaking change and I don't want to maintain the namespaced and non-namespaced values in the same version.

adri1wald commented 2 years ago

yeah I tried to replicate that selector but noticed separator-border isn't exposed. No worries though, we're just keeping the !important around for now

johnwalley commented 2 years ago

I've added separator border in the latest release.

clintharris commented 3 months ago

Hi, I'm having a similar issue (i.e., the separator being shown above other content because of its z-index).

Here's the style I need to override, specifically:

.allotment-module_splitView__L-yRc.allotment-module_separatorBorder__x-rDS > .allotment-module_splitViewContainer__rQnVa > .allotment-module_splitViewView__MGZ6O:not(:first-child)::before {
    background-color: var(--separator-border);
    content: " ";
    left: 0;
    pointer-events: none;
    position: absolute;
    top: 0;
    z-index: 5; /* 👈 this is what I want to change */

Since the classnames from allotment's dist/styles.css file use hashes due to how the CSS module namespacing is configured, you can't easily override them in a way that will work for future releases. This leaves you with needing to use !important--in my case, the following

.split-view-view::before
  z-index: 0 !important;
}

Would you be open to considering modifying the post-css config so that the class names are generated without hashes (so that people can override styles without needing to use !important)?

I think it's just a matter of modifying rollup.config.mjs like this:

postcss({
      autoModules: true,
      // See https://www.npmjs.com/package/rollup-plugin-postcss#modules
      modules: {
          // see https://github.com/madyankin/postcss-modules?tab=readme-ov-file#generating-scoped-names
          generateScopedName: "[name]__[local]"
      },
      extract: path.resolve("dist/style.css"),
}),

It seems like the hashes are unnecessary since the class names already include allotment- (i.e., a nice namespace prefix for the library).

tubs-coder commented 3 weeks ago

Also hitting the same issue here.

The following code works nicely for me. I'm just wondering if the z-index 5 is needed at all.

.split-view-view::before { z-index: unset !important;}