Black Lives Matter. Please consider donating to Black Girls Code today.

How to serve up css without static or assets directory?

Is there a way to serve up the contents of a css file from a basic dash app but to do it without the traditional method of serving it from a local or remote file? My hypothetical scenario is one where I might want to import my dash app as a class into an ipython shell and say, for example, it is running in an environment where I don’t have access to the file system to create the assets or static directory. I also can’t serve it up externally. My thought is that my css data could just be a string variable in my dash app python file but I am not sure how to get that string blob loaded to the web page as css content. Perhaps use dcc.Link() or simialar?

You could embed raw html with dash dangerously set inner html. you might also be able to use html.Link, but i haven’t tried this.

Thanks for the quick response. I understand its dangerous. :slight_smile: Two questions then. Is the below code snippet somewhat correct? Also, if I add this to my main layout, are there any concerns about efficiency in terms of this string blob being uploaded to the web page after every callback execution? I think not but just checking. (Note the diplay none - I think that is necessary so it does not display.)

# This is an example css blob. Actual blob will be much larger - 150K perhaps.
my_css_data = """body {
  margin: 25px;
  background-color: rgb(240,240,240);
  font-family: arial, sans-serif;
  font-size: 14px;
}
"""
innerHtmlText = "<style>%s</style>" % my_css_data
app.layout = html.Div([dash_dangerously_set_inner_html.DangerouslySetInnerHTML(innerHtmlText''', 
                      style={"display":"none"}),
])

Yes, that looks about right. app.layout isn’t fired on every callback execution, only on page load. So, this isn’t any less performant than serving the CSS as an actual file separately: instead of two requests (one for css, the other for the JSON-ified layout), you’ll have one slightly larger request for the JSON-ified layout.

There could be a bit of a loading glitch as the CSS will be processed clientside via JavaScript. So the app might initially be unstyled for a moment until the CSS string is evaluated and inserted into the DOM at which point it the app will become styled. You’d have to test this to see if it’s an actual issue though.

I don’t think that you need display none either as <style/> doesn’t actually display anything on the screen. The div will be there, but it’s contents will be invisible. Not a big deal either way.

I have been having trouble getting it to work. I am actually trying to load boostrap.min.css (a rather large file). After searching the internet, I feel like this needs to be loaded in the head part of the page so it will apply to everything. However, app.head is not available any more. Should I just read the contents of the bootstrap file, save it as innerHtmlText, then feed it to DangerouslySetInnerHTML? The additional question here is where should it be inserted so that it is part of the head of the page?

Hi @vonf,

I created a demo that loads your my_css_data example as well as the Bootstrap CSS from https://www.bootstrapcdn.com/. I hope it serves you well. If you can’t see the embedded browser in the iframe below, you can hopefully view a demo on https://dangerouslysetstyle.wbrgss.repl.co.

I feel like this needs to be loaded in the head part of the page so it will apply to everything

This is a convention as well as a W3 standard, but as far as I know it isn’t strictly necessary.