Refresh css without reloading the app

Hi, I have a webapp for which I’d like to update the css when some action is performed (like hitting a button). In that use case the new css has to be elaborated on the python side. It is then linked with the panel app with pn.config.raw_css.append(new_css).
The problem is that the page has to be refreshed for the browser to take the new css into account ; which results in the recomputing of all the panes.
Is there a way for this new css to go to the client side without refreshing the page ?

Here is a small toy example:

import panel as pn 
import param

class test(param.Parameterized):
    button = param.Action(lambda x : x.param.trigger('button'))

@param.depends('button',watch = True)
def color(self):
    css = """
        .redbutton .bk-btn-default{
            background-color: red;
        }
    """ 
    pn.config.raw_css.append(css)

viewer = test()
pn.Row(pn.Param(viewer.param), css_classes = ['redbutton']).servable()

refresh_css2 (2)

One work around to do this is send css and js commands via a dummy html pane

import panel as pn 
import param

class test(param.Parameterized):
    button = param.Action(lambda x : x.param.trigger('button'))

    dummy_html = pn.pane.HTML('')
        
    @param.depends('button',watch = True)
    def color(self):
        css = """
            <style>
                .redbutton .bk-btn-default{
                    background-color: red;
                }
            </style>
            
            <script>console.log('changing button style') </script>
            """ 
        #     pn.config.raw_css.append(css)
        dummy_html.object = css

            
viewer = test()

pn.Row(pn.Param(viewer.param), dummy_html, css_classes = ['redbutton']).show()

Maybe someone has a better option, due to the fact that the css option remains defined in the browser, so when you run the application again the button is red.

1 Like

here you have the same option with a selector

import panel as pn 
import param

class test(param.Parameterized):
    button = param.Action(lambda x : x.param.trigger('button'))
    
    colors = ['red','white','blue','yellow']
    x = param.Selector(objects=colors)
    
    dummy_html = pn.pane.HTML('')
    
    @param.depends('button','x',watch = True)
    def color(self):
        css = f"""
            <style>
                .redbutton .bk-btn-default{{
                    background-color: {self.x};
                }}
            </style>
            
            <script>console.log('changing button style') </script>
            """ 
        #     pn.config.raw_css.append(css)
        print (self.x)
        dummy_html.object = css

            
viewer = test()



pn.Row(pn.Param(viewer.param), dummy_html, css_classes = ['redbutton']).show()

button_style

2 Likes

Thank you, that’s exactly what I needed.

1 Like