Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show floating sidebar after main text when small screen

I have a two-column layout. The main text on the left, and a sidebar on the right (float: right; width: 30%).

On small browsers, I'd like to first show the main text, and then the sidebar. But if I remove the float from the sidebar with a media query, it shows up first.

I don't want to make the main text another float, because I want it to wrap around the sidebar if the text is long and the sidebar short.

I'm looking for something that's not Javascript if possible.

like image 604
Johannes Ernst Avatar asked Jan 01 '20 19:01

Johannes Ernst


4 Answers

CSS order Property

When in mobile screen size:

  • Make the containing tag a flex-container (column wise)

  • Remove the float related properties from sidebar

  • Apply order property to the content tag (element with text) and sidebar

  • The number value of the order property belonging to content tag should be less than the order value of sidebar.


The following demo features:

600px+ Width

  • Container - <article>

    • Sidebar - <aside>

      • float: right

      • clearfix hack - article::after {...}

    • Content - <p class="content">

600px Max Width (Mobile)

  • Container - <article>

    • flex-container (column)

    • Sidebar - <aside>

      • float: none

      • clearfix hack - removed

      • order: 3

    • Content - <p class="content">

      • order: 2

Demo

Note: View demo in full page mode not in the initial iframe. Resize the window to see the media query work.

:root {
  font: 400 3vw/6vh Arial
}

html,
body {
  width: 100%;
  height: 100%;
  padding: 1vh 1vw;
}

main {
  width: 90vw;
  height: auto;
  margin: 5vh -6vw 10vh -6vw;
  padding: 3vh 15vw 5vh 5vw;
}

section {
  width: 100%;
  height: 100%;
}


/*
Begin Sidebar Rulesets
*/

aside {
  float: right;
  width: 30%;
  height: 50%;
  border: 3px ridge grey;
  margin-left: 3vw;
  padding: 5vh 1vw 5vh 2vw;
}


/*
Clearfix hack
*/

aside::after {
  content: "";
  clear: both;
  display: table;
}


/* 
End Sidebar Rulesets 
*/

header,
footer {
  padding: 2vh 0 2vh 0;
  margin: 2vh 0;
  line-height: 8vh;
}

header {
  border-bottom: 5px ridge grey;
}

footer {
  border-top: 5px ridge grey
}

h1 {
  font-size: 1.75rem;
  letter-spacing: 1vw;
  margin: 0 0 3vh;
}

h2 {
  font-size: 1.45rem;
  letter-spacing: 0.75vw;
  margin: 0 0 3vh;
}

h3 {
  font-size: 1.2rem;
  letter-spacing: 0.5vw;
  margin: 0 0 3vh;
}

address {
  float: right;
  font-size: 0.85rem;
  margin: 2vh 1vw 5vh 3vw
}

ul {
  list-style: none;
  padding-left: 1vw
}

li {
  margin-bottom: 2vh
}

.content {
  font-size: 0.9rem;
  line-height: 7vh;
}


/*
Begin Mobile Media Queries
*/


/*
Remove float properties from sidebar (aside)
Convert container (article) into a flex container
Use order property to rearrange how the flex-items appear
(header, p.content, aside)
*/

@media screen and (max-width: 600px) {
  article {
    display: flex;
    flex-flow: column nowrap;
    justify-content: center;
    align-items: center;
  }
  article>header {
    order: 1;
  }
  .content {
    order: 2;
  }
  aside {
    float: none;
    width: 100%;
    order: 3
  }
  aside::after {
    content: none;
  }
}


/*
End Mobile Media Queries 
*/
<!DOCTYPE html>
<html>

<head>
  <meta charset='utf-8'>
  <!-- <link> tags go here -->
  <style>
    /* CSS Rulesets go here */
  </style>
</head>

<body>
  <main>
    <section>
      <header>
        <h1>Main Title</h1>
      </header>

      <!-- Begin Container -->
      <article>

        <header>
          <h2>Topic Title</h2>
        </header>

        <!-- Begin Sidebar -->
        <aside>
          <nav>
            <header>
              <h3>Sidebar Title</h3>
            </header>
            <hr>
            <ul>
              <li>
                <a href='#/'>Link</a>
              </li>
              <li>
                <a href='#/'>Link</a>
              </li>
              <li>
                <a href='#/'>Link</a>
              </li>
            </ul>
          </nav>
        </aside>
        <!-- End Sidebar -->

        <!-- Begin Content -->
        <p class='content'>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae
          est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis
          tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan
          porttitor, facilisis luctus, metus</p>
        <!-- End Content -->

      </article>
      <!-- End Container -->

      <footer>
        <address>
          123 Main St.<br>
          Springfield, IL 12345<br>
          [email protected]
        </address>
      </footer>
    </section>
  </main>
</body>

</html>
like image 164
zer00ne Avatar answered Oct 20 '22 06:10

zer00ne


First Solution using float on Desktop and using flex-direction on mobile Will give the result you want.

.sidebar {
    float: right;
    border: 1px solid;
    width: 200px;
}

@media (max-width:767px) {
 p, 
.sidebar {
  float: none;
width: auto;
}
.main {
    display: flex;
    width: 100%;
    flex-direction: column-reverse;
}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
  
    <div class="main">
    <div class="sidebar"> <h1>Side bar</h1>
molestiae recusandae placeat corporis earum assumenda dolorem! Earum necessitatibus tempora enim nisi officiis in. Ducimus illo placeat eveniet.</div>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloremque explicabo aspernatur delectus voluptate, nesciunt quibusdam ab reprehenderit, non et temporibus. Aut commodi, voluptates nulla deleniti pariatur vitae vel eos sit asperiores aliquid,
        molestiae recusandae placeat corporis earum assumenda dolorem! Earum necessitatibus tempora enim nisi officiis in. Ducimus illo placeat eveniet.Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloremque explicabo aspernatur delectus voluptate, nesciunt quibusdam ab reprehenderit, non et temporibus. Aut commodi, voluptates nulla deleniti pariatur vitae vel eos sit asperiores aliquid,
        molestiae recusandae placeat corporis earum assumenda dolorem! Earum necessitatibus tempora enim nisi officiis in. Ducimus illo placeat eveniet.Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloremque explicabo aspernatur delectus voluptate, nesciunt quibusdam ab reprehenderit, non et temporibus. Aut commodi, voluptates nulla deleniti pariatur vitae vel eos sit asperiores aliquid,
        molestiae recusandae placeat corporis earum assumenda dolorem! Earum necessitatibus tempora enim nisi officiis in. Ducimus illo placeat eveniet.</p>
    
  </div>
  
</div>

Helping Credits goes to @zer00ne

Second Solution if not using text to wrap under sidebar Using flex we can achieve this. As it has many advantages of playing with its properties without changing HTML structure and its more mature then float

.flex-container {
  display: flex;
  flex-direction: column;
}

.main {
  width: 100%;
  order: 1;
  padding: 0 1em;
}


.sidebar-aside {
  width: 100%;
  order: 2;
  padding: 0 1em;
  background-color: #cff;
}

@media (min-width: 40em) {
  .flex-container {
    flex-direction: row;
  }
  
  .main {
    flex: 1;
    order: 1;
  }
  
  .sidebar-aside {
    width: 15em;
    order: 2;
  }
}
<div class="flex-container">
  <main class="main">
    <article>
      <h1>Main Title</h1>
      <p>Some Content to fill the page.</p>
      <h2 id="topic-1">Topic 1</h2>
      <p>Info</p>
      <h2 id="topic-2">Topic 2</h2>
      <p>Info</p>
      <h2 id="topic-3">Topic 3</h2>
      <p>Info</p>
    </article>
  </main>
  <aside class="sidebar-aside">
    <h3>Side Bar</h3>
    <h4>Sidebar Title</h4>
    <p>Lorem epsum text is a dummy text</p>
  </aside>
</div>

You can change the order on different screens that which div comes first

like image 44
Awais Avatar answered Oct 20 '22 06:10

Awais


It can be achieved using css grid

/* Here 2fr for main text and 1fr for side bar */
grid-template-columns: 2fr 1fr;

For screen size 600px or less

/* For mobile devices, it will be 1/1 grid */
grid-template-columns: 1fr;

	*{
		padding: 0;
		margin: 0;
	}
	.container{
		background: #f2f2f2;
		padding: 10px;
		height: 100vh;
	}

	.layout{
		display: grid;
        /* Actual style width 2 grid layout */
		grid-template-columns: 2fr 1fr;
		padding:5px;
	}

    .main-text{
    	padding: 20px;
    }
	.side-bar{
		border: 2px solid #444;
	}
    /* For mobile devices with 1f 1/1 grid */
	@media (max-width:600px){
		.layout{
			grid-template-columns:1fr;
		}
	}
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<div class="container">
	<h3>Resize screen for responsive</h3>
	<div class="layout">
		<div class="main-text">
			<h2>Main text</h2>
			Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce ultrices mollis cursus. Vestibulum aliquam, lorem quis porta sodales, diam mi tincidunt quam, vitae consequat erat neque in turpis. Nam massa libero, feugiat ut laoreet eu, interdum et erat. Morbi quis suscipit nunc, blandit congue sapien. Aenean faucibus nisi sit amet quam interdum, eget mollis enim rutrum. Etiam viverra vel magna quis rutrum. Maecenas ipsum urna, feugiat sed sagittis id, vehicula eu enim. Ut commodo odio vitae nibh posuere blandit. Nunc aliquam metus vitae vehicula tempus. Vivamus semper pharetra felis mollis pellentesque. Vestibulum quis velit feugiat, blandit tortor a, mattis turpis. Mauris varius nisl id ultricies tempus. Vivamus imperdiet euismod pellentesque. Nullam pretium elit id semper convallis.

		</div>
		<div class="side-bar">
			<h2>Side bar</h2>
			Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce ultrices mollis cursus. Vestibulum aliquam, lorem quis porta sodales, diam mi tincidunt quam, vitae consequat erat neque in turpis. Nam massa libero, feugiat ut laoreet eu, interdum et erat. Morbi quis suscipit nunc, blandit congue sapien. Aenean faucibus nisi sit amet quam interdum, eget mollis enim rutrum. Etiam viverra vel magna quis rutrum.
		</div>
	</div>
</div>
like image 38
Sudarshan Rai Avatar answered Oct 20 '22 06:10

Sudarshan Rai


    <!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
    <style>
      body {
        font-family: sans-serif;
      }

      .app {
        display: flex;
        justify-content: flex-start;
        align-items: stretch;
      }
      .main-text {
        flex-basis: 70%;
        background-color: #ddd;
        min-height: 200px;
      }
      .sidebar {
        flex-basis: 30%;
        background-color: #1a1a1a;
        color: white;
        min-height: 100px;
      }
      @media only screen and (max-width: 600px) {
        body {
          background-color: lightblue;
        }
        .app {
          flex-wrap: wrap;
        }
        .main-text {
          flex-basis: 100%;
        }
        .sidebar {
          flex-basis: 100%;
        }
      }
    </style>
  </head>

  <body>
    <div class="app" id="app">
      <div class="main-text">
        Main Text
      </div>
      <div class="sidebar">
        SideBar
      </div>
    </div>
  </body>
</html>
  • simple solution using flexbox, no javascript involved
  • class main-text and sidebar refer to respective components
  • height and background colors are added just for the visual effect,they are not necessary for the solution to work
like image 40
venkatesh ng Avatar answered Oct 20 '22 06:10

venkatesh ng