0

I'm trying to customize my blog layout by adding a sticky sidebar. I managed to get position:sticky to work as excepted, but I can't figure out how to position the blocks where I want.

I want the main block to be centered, and the sidebar right beside the main block. here's an example of what I'm aiming for: https://theme-next.js.org/ except I want the main block to be centered. this is the layout I want

I've tried using margin-left with the sidebar, but it doesn't work well in smaller windows, as the left margin is constant and pushes the real content away in smaller windows. this is what happens by using margin-left

(I'm not sure why the sticky dosen't work here, but it works fine on my website. All I'm trying to figure out is how to position them where I want.

.wrapper {
  display: flex;
  justify-content: space-between;
}

.sidebar {
  width: 80px;
  background-color: #FF0000;
  position: webkit-stiky;
  position: sticky;
  align-self: flex-start;
  height: 1000px;
}

.main {
  width: 100px;
  background-color: #CFCFCF;
  margin: auto;
  height: 1600px;
}

.header {
  background-color: #F3FF00;
  width: 150px;
  margin: auto;
}
<div class="header">
  <p>
    this is centered header
  </p>
</div>
<div class="wrapper">
  <div class="sidebar">
    <p> sidebar here</p>
  </div>
  <div class="main">
    <p>
      I want this block to be centered;
    </p>
  </div>
</div>
  • here is why it dont work...(little spoliler..FLEX) https://stackoverflow.com/questions/44446671/my-position-sticky-element-isnt-sticky-when-using-flexbox – Gabriele Feruglio May 12 '21 at 12:46

1 Answers1

0

There's a few things you need to do here:

  1. Set a top property for your sticky sidebar, or it won't stick
  2. Make your main element a flex parent since we'll need to offset its child element to make it centered with your header.
  3. Create an inner element for your main element so you can move it to the left 80px to accommodate for the sidebar width.

.wrapper {
  display: flex;
  position: relative;
}

.sidebar {
  width: 80px;
  height: 1000px;
  background-color: #FF0000;
  position: sticky;
  /* you need a top position set for sticky */
  top: 0;
}

.main {
  height: 1600px;
  background-color: #eeeeee;
  /* This needs to be a flex parent */
  display: flex;
  justify-content: center;
  /* This element needs to be 100% MINUS the sidebar width of 80px */
  flex: 1 0 calc(100% - 80px);
}

.main-inner {
  width: 100px;
  position: relative;
  background-color: #CFCFCF;
  /* Move the inner element 80px to the left */
  margin-left: -80px;
  text-align: center;
}

.header {
  background-color: #F3FF00;
  width: 150px;
  margin: 0 auto;
}
<div class="header">
  <p>this is centered header</p>
</div>
<div class="wrapper">
  <div class="sidebar">
    <p>sidebar here</p>
  </div>
  <div class="main">
    <div class="main-inner">
      <p>I want this block to be centered;</p>
    </div>
  </div>
</div>

However, I believe this is what you really want:

  1. Make the header a flex parent as well.

.wrapper {
  display: flex;
  position: relative;
}

.sidebar {
  width: 80px;
  height: 1000px;
  background-color: #FF0000;
  position: sticky;
  /* you need a top position set for sticky */
  top: 0;
}

.main {
  height: 1600px;
  background-color: #eeeeee;
  /* This needs to be a flex parent */
  display: flex;
  justify-content: center;
  /* This element needs to be 100% MINUS the sidebar width of 80px */
  flex: 1 0 calc(100% - 80px);
}

.main-inner {
  width: 100px;
  position: relative;
  background-color: #CFCFCF;
  /* Move the inner element 80px to the left */
  text-align: center;
}

.header {
  display: flex;
  justify-content: flex-end;
}

.header-inner {
  background-color: #F3FF00;
  text-align: center;
  width: calc(100% - 80px);
  background-color: #F3FF00;
}
<div class="header">
  <div class="header-inner">
    <p>this is centered header</p>
  </div>
</div>
<div class="wrapper">
  <div class="sidebar">
    <p>sidebar here</p>
  </div>
  <div class="main">
    <div class="main-inner">
      <p>I want this block to be centered;</p>
    </div>
  </div>
</div>
disinfor
  • 10,865
  • 2
  • 33
  • 44