Bootstrap responsive layout: change order in narrow views

Viewed 70

I have a layout, set up for me in Bootstrap 5, that has, at larger sizes, a sidebar consisting of two parts (site nav, and a longer table-of-contents nav), and the main text area:

+---+-----+
| 1 |  2  |
+---+     |
| 3 |     |
+---+-----+

At narrow sizes, when this is all reduced to one column, it, of course, collapses to a 1-3-2 order. But the table-of-contents nav (#3) is distracting and shouldn't be the main thing that people see on mobile, so I'd like the main area to come before the table-of-contents nav, i.e. in the numbered order above:

+---+
| 1 |
+---+
| 2 |
+---+
| 3 |
+---+ 

The page structure looks more or less like this, except the FOO BAR BAZ section is actually much longer, which is fine as a sidebar but terrible when it's the main thing you see:

layout sample

That was created by ripping away a lot of the more complex stuff on the page but keeping the actual structure. This was all created for me by someone else, and I'm not a designer at all, so if this would require any serious rewriting, I'll end up breaking it all. Is there any simple way to get this to collapse into the desired order in narrow views? (To be perfectly clear, I'd like the "Heading/content" to come before the FOO BAR BAZ.)

Here's the smallest version I feel comfortable reducing it to:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>

    <title>TITLE</title>

  </head>

  <body class="bg-light">

    <div class="container-fluid">
      <div class="row">

        <div class="col-lg-3 col-sm-4 p-0 vh-sm-100 vh-xs-auto overflow-sm-hidden overflow-xs-visible position-sm-sticky position-xs-static top-0 start-0 sidebar-parent">

          <nav class="navbar navbar-expand-xs navbar-dark bg-dark sticky-top">
            <div class="container">

              <div class="vw-100 d-flex justify-content-between align-items-center">
                <a class="navbar-brand" href="/">MYSITE</a>
                
              </div>

              <div class="row w-100 m-0" id="">
                <form id="" class="d-inline-flex p-0" action="/">
                  <input class="form-control pe-2 me-2 typeahead tt-input" id="search" type="search" placeholder="search" aria-label="Search" style="position: relative; vertical-align: top;">
                    
                    <div role="listbox" class="tt-menu" id="search_listbox" style="position: absolute; top: 100%; left: 0px; z-index: 100; display: none;">
                     
                    </div>

                  <button class="btn btn-secondary" type="submit">Search</button>
                </form>
              </div>
            </div>
          </nav>

          <div id="sidebar" class="list-group list-group-flush">

            <div class="sidebar-list" id="sidebar-list"><a href="/" aria-current="true" class="list-group-item list-group-item-action py-0 list-group-item-action">FOO</a><a href="/" aria-current="true" class="list-group-item list-group-item-action py-0">BAR</a><a href="/" aria-current="true" class="list-group-item list-group-item-action py-0">BAZ</a></div>

          </div>
        </div>
        <div id="main" class="col-lg-9 col-sm-8 col-xs-12 p-5">

          <h1 id="">HEADING
          </h1>
          <p>
          Content, content content content.
          </p>

        </div>
      </div>
    </div>

  </body>
</html>

There's a separate fiddle of this here, with slightly more code (it includes the hamburger menu).

1 Answers

For your situation and because you said:

if this would require any serious rewriting, I'll end up breaking it all

I would suggest you to duplicate <div id="main"> and put the duplicated one direct below <nav> then toggle (show/hide) between them.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>

    <title>TITLE</title>

  </head>

  <body class="bg-light">

    <div class="container-fluid">
      <div class="row">

        <div class="col-lg-3 col-sm-4 p-0 vh-sm-100 vh-xs-auto overflow-sm-hidden overflow-xs-visible position-sm-sticky position-xs-static top-0 start-0 sidebar-parent">

          <nav class="navbar navbar-expand-xs navbar-dark bg-dark sticky-top">
            <div class="container">

              <div class="vw-100 d-flex justify-content-between align-items-center">
                <a class="navbar-brand" href="/">MYSITE</a>
                
              </div>

              <div class="row w-100 m-0" id="">
                <form id="" class="d-inline-flex p-0" action="/">
                  <input class="form-control pe-2 me-2 typeahead tt-input" id="search" type="search" placeholder="search" aria-label="Search" style="position: relative; vertical-align: top;">
                    
                    <div role="listbox" class="tt-menu" id="search_listbox" style="position: absolute; top: 100%; left: 0px; z-index: 100; display: none;">
                     
                    </div>

                  <button class="btn btn-secondary" type="submit">Search</button>
                </form>
              </div>
            </div>
          </nav>
        <div id="main" class="d-block d-sm-none p-5">

          <h1 id="">HEADING
          </h1>
          <p>
          Content, content content content.
          </p>

        </div>
          <div id="sidebar" class="list-group list-group-flush">

            <div class="sidebar-list" id="sidebar-list"><a href="/" aria-current="true" class="list-group-item list-group-item-action py-0 list-group-item-action">FOO</a><a href="/" aria-current="true" class="list-group-item list-group-item-action py-0">BAR</a><a href="/" aria-current="true" class="list-group-item list-group-item-action py-0">BAZ</a></div>

          </div>
        </div>
        <div id="main" class="col-lg-9 col-sm-8 col-xs-12 p-5 d-none d-sm-block">

          <h1 id="">HEADING
          </h1>
          <p>
          Content, content content content.
          </p>

        </div>
      </div>
    </div>

  </body>
</html>

IMPORTANT

If this is for a static website it will work perfectly but in case it's a dynamic website (content coming from the database or there is a function using id="main"), this may lead to errors because you have a duplicated id's.

Related