✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚡️ Concerned about the grid? Kyle Baranko teaches how to predicting peak loads using XGBoost. Register for the August webinar!

How to get a responsive layout

I have the feeling I am just missing something, but how do you make a layout mobile responsive? I am using bootstrap’s css.

Here is the minimum example:

import dash
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash()

app.layout = (
  html.Div(
    html.Div(
      html.Div(
        html.Button('Some very long text so we can see centering and styling', className='btn btn-secondary'),
      className='col-md-6 col-xs-12'),
    className='row justify-content-center'),
  className='container')
)

app.css.append_css({
    "external_url": "https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
})

if __name__ == '__main__':
    app.run_server(debug=True)

I am using:

dash==0.35.2
dash-core-components==0.42.1
dash-html-components==0.13.5
results from pip freeze
certifi==2018.11.29
chardet==3.0.4
Click==7.0
dash==0.35.2
dash-core-components==0.42.1
dash-html-components==0.13.5
dash-renderer==0.16.2
decorator==4.3.0
Flask==1.0.2
Flask-Compress==1.4.0
gunicorn==19.9.0
idna==2.8
ipython-genutils==0.2.0
itsdangerous==1.1.0
Jinja2==2.10
jsonschema==2.6.0
jupyter-core==4.4.0
MarkupSafe==1.1.0
nbformat==4.4.0
plotly==3.5.0
pytz==2018.9
requests==2.21.0
retrying==1.3.3
six==1.12.0
traitlets==4.3.2
urllib3==1.24.1
Werkzeug==0.14.1

These are the screenshots from Firefox, full screen:

Resizing the browser manually:

And using dev tools, viewport control:

You can see how that is way off. Any help is greatly appreciated and thanks in advance!

1 Like

If you were doing this in html, you would probably have something like this in your header

<meta name="viewport" content="width=device-width, initial-scale=1.0">

The easiest way to achieve the same in a Dash app is to use the meta_tags argument when creating your app object

app = dash.Dash(
    meta_tags=[
        {"name": "viewport", "content": "width=device-width, initial-scale=1"}
    ]
)

If you prefer, Dash also lets you override the default html template into which your app gets injected, check out the docs.

Finally, since you’re using Bootstrap, you might be interested in checking out dash-bootstrap-components (full disclosure, I’m one of the developers working on it),

4 Likes

Thanks a lot. Simple but so essential!

I am using dash-bootstrap-components, but wanted to keep the example basic!

1 Like

I am running into the same issue. When I try to resize my browser, the css isn’t responsive. I am using a bootstrap styling sheet:

import dash_bootstrap_components as dbc

app = dash.Dash(
            meta_tags=[
                {"name": "viewport", "content": "width=device-width, initial-scale=1"}
            ],
            external_stylesheets=[dbc.themes.SLATE],
      )

Screenshot for reference:

How have you constructed the layout? Those meta tags will only ensure that the CSS responds to the real viewport size rather than a virtual one (mobile devices generally pretend their screen is larger than it is then scale content down so that non-responsive websites don’t look terrible). To make the layout reorganise itself appropriately on small screens you need to tell it how to do that.

I see. I am on desktop running the app on chrome web browser. The meta-tags are in app.py and my layout code is in index.py:


app.layout = html.Div([

    # header
    html.Div([

        html.H2("Stroom Product suite ®", style={"float":"center",
                                                                      "margin-left":"40%",
                                                                      "margin-top":"30px"}),

        html.Div(
            html.Img(src='https://logo-white.png',height="100%")
            ,style={"float":"right","width":"170px","height":"100px","margin-top":"-14px"})
        ],
        className="row header"
    ),

    # body
    #html.Div(className='background')

    # tabs
    html.Div([

        dcc.Tabs(

            id="tabs",
            vertical=True,
            className="mb-3",
            #style={"height":"60", "verticalAlign":"middle", "font-size":"0.9375rem"},
            children=[

                 dcc.Tab(label="Portfolio", value="portfolio_tab"),
                 dcc.Tab(label="Smart Leads", value="market_tab"),
                 dcc.Tab(label="Spaces", value="reporting_tab"),
                 dcc.Tab(label="Revenue", value="revenue_tab",
                         children=[dcc.Tabs(id="subtabs", value="subtabs", style={"margin-left":"50px"},
                         children=[dcc.Tab(label='Comps', value='subtab1'),
                                   dcc.Tab(label='Analysis', value='subtab2')

                 ])
            ]),
                 dcc.Tab(label="Deal", value="deal_tab")

            ],
            value="revenue_tab",
        )

        ],

        className="row tabs_div"
    ),

        # Tab content
        html.Div(id="tab_content", style={"margin": "-32% 11%","float":"left"})

])

I would suggest using dbc.Row and dbc.Col to control the layout rather than setting float property in your style arguments. They can be configured to take up different widths on different screen sizes. More generally to achieve responsiveness you’ll need to use CSS (whether bootstrap or your own) rather than inline style arguments as generally you need to make use of media queries to achieve different behaviour on different screen sizes.

Take a look at the layout documentation for dash-bootstrap-components and perhaps something like this responsive sidebar example.

1 Like