CSS styling not working for anywidget based widget in marimo
Describe the bug
I'm working on updating buckaroo to use anywidget. It renders to the dom in marimo, but the styling is really off. Some of my divs aren't the correct width
Does marimo do anything special to css included with an anywidget widget that I should know about
I put the orange border in that div. but the rest is scrunched up against the left side.
Here is the same widget rendered in jupyter lab
I'm usre theres something that I can change in my code, I was curious if I was bumping up against a known bug. or there is a recommended workaround.
Environment
{
"marimo": "0.10.8",
"OS": "Darwin",
"OS Version": "22.6.0",
"Processor": "arm",
"Python Version": "3.12.8",
"Binaries": {
"Browser": "131.0.6778.205",
"Node": "v18.20.4"
},
"Dependencies": {
"click": "8.1.8",
"docutils": "0.21.2",
"itsdangerous": "2.2.0",
"jedi": "0.19.2",
"markdown": "3.7",
"narwhals": "1.19.1",
"packaging": "24.2",
"psutil": "5.9.0",
"pygments": "2.18.0",
"pymdown-extensions": "10.13",
"pyyaml": "6.0.2",
"ruff": "0.8.4",
"starlette": "0.43.0",
"tomlkit": "0.13.2",
"typing-extensions": "4.12.2",
"uvicorn": "0.34.0",
"websockets": "14.1"
},
"Optional Dependencies": {
"anywidget": "0.9.13",
"pandas": "2.2.3",
"polars": "1.18.0",
"pyarrow": "17.0.0"
}
}
Code to reproduce
pip install buckaroo
import pandas as pd
from buckaroo import BuckarooWidget
num_df = pd.DataFrame(
{'a':[111_111, 77_777, 777_777, 1_000_000, 2_111_111, 1_235_999],
'b':[111_111, 555_555, 0, 28_123, 482_388, 5_666]})
BuckarooWidget(num_df)
We put our anywidget elements on shadow doms for better encapsulation of styling to avoid polluting the global namespace. That could be it, but not sure without looking into the stylesheets. I can take a look, if you can link them.
Sorry, I missed this. I made some progress, I'm running into a different problem now, but still related to marimo. I'm not sure the best way to describe reproduction steps.
Currently Buckaroo inside marimo isn't picking up the same styles that it is in jupyter lab. The css is compiled / concatenated in the anywidget build step.
The core problem seems to come down to not picking up a theme from the included ag-grid styles
(marimo on the left, jupyter on the right. notice the lack of dark background in marimo).
The css for both platforms is the same because that is the only css in the buckaroo wheel. The injected dom classes seem to be identical. To look at the bundled css you can follow theses steps. Sorry if this is an awkward way to describe reproduction
curl https://files.pythonhosted.org/packages/bd/a6/793ceddd4bda93ec2ef5bb61c09d9823386aaff46169ff1170b79c88df66/buckaroo-0.8.3-py3-none-any.whl > buckaroo-0.8.3-py3-none-any.whl
tar xvzf buckaroo-0.8.2-py3-none-any.whl
cat buckaroo/static/widget.css | grep .ag-theme-alpine-dark | wc -l
this shows that widget.css includes css referencing .ag-theme-alpine-dark
the selectors for .ag-theme-alpine-dark class isn't prefixed by any other selector from what I can see (discounting the possibility of a different parent div name in marimo vs jupyter.
I'm talking through possible explanations for the different styling, but right now I'm drawing a blank.
Happy to try other approaches, hopefully this bug will be useful to future devs that want to build for marimo
@paddymul this is likely still because of the shadowdom. the ag styles might be being placed on the global css scope and are not passed to the shadowdom. how are you importing these styles? are you using the _css prop from anywidget?
yes I am using the _css prop. What should I use instead?
A sample anywidget with different types of css inclusion, and how they behave in marimo vs jupyter would be helpful.
Using the _css prop is correct. I dont have sample anywidgets, but there are plenty on this page: https://anywidget.dev/en/community/
If you can share the code or a reproduction, i am happy to take a look
Ok. I will make some examples and play with some stuff to see what works and what doesn't soon.
I have tried a series of debugging steps
Steps I tried included
- trying the basic anywidget example. which worked.
- pointing the
BuckarooWidget._cssat a hard coded fully specified path file which displayed exactly as the BuckarooWidget was displaying, I wanted to verify that it wasn't some type of packaging issue. - editting that hardcoded file to put some borders around elements I could see inside the shadow dom. This worked
- putting the border debugging at different points in the 7000 line file, still worked
- carefully inspecting the css as applied to elements. I think I found something here.
Here are screenshots from the dom inspector.
constructed.css seems to come from marimo, inline comes from Buckaroo. You can see that all relevant styles other than the blue border (which does display) are dashed out meaning they aren't applied
It looks like marimo also includes ag-grid based styling. https://github.com/marimo-team/marimo/blob/33d6e58487b4d5fa5801b8a0b300bd0fecbd35a4/frontend/package.json#L87-L88 Marimo points at ag-grid 32.2.2, Buckaroo uses ag-grid 32.3.2 . bumping buckaroo back to 32.2.2 didn't fix the problem
Do you have any recommendations to give the Buckaroo css priority?
Yes this is definitely the conflict.
My div with ag-theme-alpine-dark looks like this
<div className={`df-viewer ${hs.classMode} ${hs.inIframe}`}>
<div style={hs.applicableStyle} className={`theme-hanger ag-theme-alpine-dark`}>
<AgGridReact
I updated a single rule in the anywidget referenced stylesheet to add theme-hanger
.theme-hanger.ag-theme-alpine-dark {
border:5px solid orange;
--ag-background-color: #181d1f;
--ag-foreground-color: #fff;
Because of increased specificity that rule took precedence.
Sorry for being overly verbose. It helps to keep track of things I have tried, while writing this, I thought of other approaches to try.
I guess the generic question is: How do I make sure that css injected from anywidget has precedence over any other rules from the outer page.
Is there a setting or attribute on the shadowDOM? Would you recommend a CSS build step? Something else obvious?
I see, our ag-grid styles shouldn't pollute the global CSS. I have a fix for that here: https://github.com/marimo-team/marimo/pull/3601. I also made the anywidget CSS styles use constructed style sheets (and come last) so they take precedence.
If you are running marimo locally, can you let me know if this fixes it. If not, I plan to release today
I pulled the most recent main, and that fixes the problem. Thanks for the quick response, and bearing with me as I debug it.
There are still some other styling issues, but I will assume they are on my end, until I do more research.
awesome, glad it works! let me know if I can help debug further with the CSS changes. (here or Discord)