CSS позиционирует липкую боковую панель в сетке

#html #css #css-position #css-grid

#HTML #css #css-позиция #css-сетка

Вопрос:

У меня есть простая страница, на которой я хочу липкий заголовок и липкую боковую панель. Вот скрипка, и здесь тот же код:

 #top {
  position: sticky;
  top: 0;
  border: 1px solid red;
  width: 100%;
}

.container {
  display: grid;
  grid-gap: 50px;
  grid-template-columns: max-content 1fr;
  margin-top: 50px;
  margin-left: auto;
  margin-right: auto;
  max-width: 900px;
}

.sidebar {
  border: 1px solid blue;
  position: sticky;
  top: 0;
}

.content {
  border: 1px solid green;
}  
 <div id="top">
  sticky header
</div>
<div class="container">
  <div class="sidebar">
    sticky sidebar
  </div>
  <div class="content">
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus at ipsum mi. Integer laoreet a nisl quis imperdiet. Etiam sed ligula rutrum, viverra arcu vitae, mattis lectus. Aliquam rutrum eros id quam sodales volutpat. Suspendisse sed neque ut mauris
      luctus hendrerit. Suspendisse auctor aliquam rutrum. Sed sodales placerat est. Donec vel elit vitae ipsum ultrices tristique. Nulla auctor, dolor at porta laoreet, ex nisi auctor orci, in posuere enim arcu at tortor. Etiam sed ante mattis sem pharetra
      condimentum. Nullam a eros nec metus feugiat tincidunt vel sed lectus. Nunc accumsan nisi sit amet auctor rhoncus. Vestibulum diam risus, sodales non diam a, tristique ullamcorper erat.
    </p>
    <p>
      Aliquam posuere libero at felis maximus, quis pulvinar diam dictum. Integer id nisi non turpis bibendum suscipit. Duis pellentesque leo vitae elit mollis malesuada. Duis eget magna et odio mattis bibendum. Ut et rutrum diam, quis luctus mi. Duis in molestie
      elit. Nullam consequat turpis velit, sit amet venenatis tellus bibendum non. Etiam iaculis luctus sem, et aliquam nisl commodo et. In consectetur ac nibh ac porttitor. Nulla euismod facilisis faucibus. Phasellus sed risus convallis, elementum est
      nec, euismod lorem. Nulla sodales auctor dapibus. Curabitur euismod neque dolor, at sagittis arcu congue ultrices. Morbi nec finibus tortor.
    </p>
    <p>
      Aliquam vestibulum dictum nisi non sollicitudin. Integer ac magna viverra, cursus lorem quis, interdum ex. Phasellus id neque pulvinar, dignissim augue ut, lobortis leo. Duis sed elit et ipsum auctor convallis. Donec non orci suscipit, eleifend tellus
      pretium, vehicula turpis. Mauris et justo et est cursus accumsan et vel elit. In egestas lobortis imperdiet. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus
      et ultrices posuere cubilia Curae; Etiam dictum vel lorem in varius. Etiam accumsan nibh at ex mollis, id porta leo sodales. Suspendisse mauris urna, faucibus in turpis et, porttitor lobortis lectus. Cras facilisis feugiat tortor sed laoreet. Nam
      cursus malesuada lorem sed bibendum. Sed dapibus, mi vel elementum vehicula, augue massa pulvinar erat, vitae rutrum eros nisi sed neque.
    </p>
    <p>
      Nulla sodales lectus vitae urna ullamcorper, eu mattis lacus iaculis. Praesent eleifend eu sem nec aliquet. Pellentesque consequat nisl ac odio efficitur, vitae interdum sapien gravida. Proin sed commodo leo. Quisque sem sem, euismod id sapien eget, fermentum
      consectetur turpis. Praesent aliquam eros id ipsum vehicula, aliquam pellentesque massa pellentesque. Etiam nec elit arcu. Donec eget ullamcorper nisl, in porta nibh. In non ante id elit tincidunt convallis. Suspendisse sit amet dictum sapien, vel
      lobortis mi. Mauris eu pharetra ante. Morbi vestibulum orci at augue pulvinar iaculis. Vestibulum quis dui et odio tristique laoreet eget id augue.
    </p>
    <p>
      Nulla finibus lorem in risus efficitur, at cursus nunc molestie. In pellentesque quis quam et sollicitudin. Mauris at turpis felis. Nulla facilisi. Cras pellentesque malesuada felis, sit amet dapibus lectus efficitur auctor. Mauris dictum eu nisl non
      commodo. Quisque at risus eget quam dictum aliquet. Curabitur malesuada magna et efficitur bibendum. Curabitur ultrices luctus lorem. Vivamus sodales elit quis metus mattis, pretium semper mi finibus.
    </p>
  </div>
</div>  

Липкий заголовок работает нормально.

Липкая боковая панель не работает. Боковая панель находится в содержащем элементе, который задает сетку CSS, и центрируется по максимальной ширине. Я читал, что sticky привязывается к своему ближайшему прокручивающемуся предку, поэтому я предполагаю, что это не работает, потому что body прокручивается, а не контейнер div, но я не уверен, что с этим делать.

Если я сделаю что-то подобное height: 100px в контейнерном div, я получу полосу прокрутки в этом div, а не в теле. Я хочу, чтобы прокрутка была в теле.

Если бы я использовал fixed позицию на боковой панели, сетка разорвалась бы (содержимое div теперь занимает 100% контейнера), и мне пришлось бы знать высоту верхней липкой панели, чтобы установить смещение на полосе прокрутки. Если высота верхней панели изменяется, это не сработает.

Каково решение этой проблемы?

Комментарии:

1. Как насчет другого div в боковой панели и придания ему позиции липкости с вершиной 50 пикселей? И, конечно, удалить текущие стили боковой панели . 🙂

Ответ №1:

Вы можете добавить, align-self: flex-start чтобы переопределить поведение растягивания по умолчанию sidebar (поскольку это элемент сетки)

Теперь вы можете явно установить 100vh height на sidebar — смотрите демонстрацию ниже без grid-gap и / или margin или padding

 #top {
  position: sticky;
  top: 0;
  border: 1px solid red;
  width: 100%;
}

.container {
  display: grid;
  /*grid-gap: 50px;*/
  grid-template-columns: max-content 1fr;
  /* margin-top: 50px;*/
  margin-left: auto;
  margin-right: auto;
  max-width: 900px;
}

.sidebar {
  border: 1px solid blue;
  position: sticky;
  top: 0;
  /* ADDED */
  align-self: flex-start; /* override the default stretch */
  height: 100vh; /* set a fixed height */
}

.content {
  border: 1px solid green;
}  
 <div id="top">
  sticky header
</div>
<div class="container">
  <div class="sidebar">
    sticky sidebar
  </div>
  <div class="content">
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus at ipsum mi. Integer laoreet a nisl quis imperdiet. Etiam sed ligula rutrum, viverra arcu vitae, mattis lectus. Aliquam rutrum eros id quam sodales volutpat. Suspendisse sed neque ut mauris
      luctus hendrerit. Suspendisse auctor aliquam rutrum. Sed sodales placerat est. Donec vel elit vitae ipsum ultrices tristique. Nulla auctor, dolor at porta laoreet, ex nisi auctor orci, in posuere enim arcu at tortor. Etiam sed ante mattis sem pharetra
      condimentum. Nullam a eros nec metus feugiat tincidunt vel sed lectus. Nunc accumsan nisi sit amet auctor rhoncus. Vestibulum diam risus, sodales non diam a, tristique ullamcorper erat.
    </p>
    <p>
      Aliquam posuere libero at felis maximus, quis pulvinar diam dictum. Integer id nisi non turpis bibendum suscipit. Duis pellentesque leo vitae elit mollis malesuada. Duis eget magna et odio mattis bibendum. Ut et rutrum diam, quis luctus mi. Duis in molestie
      elit. Nullam consequat turpis velit, sit amet venenatis tellus bibendum non. Etiam iaculis luctus sem, et aliquam nisl commodo et. In consectetur ac nibh ac porttitor. Nulla euismod facilisis faucibus. Phasellus sed risus convallis, elementum est
      nec, euismod lorem. Nulla sodales auctor dapibus. Curabitur euismod neque dolor, at sagittis arcu congue ultrices. Morbi nec finibus tortor.
    </p>
    <p>
      Aliquam vestibulum dictum nisi non sollicitudin. Integer ac magna viverra, cursus lorem quis, interdum ex. Phasellus id neque pulvinar, dignissim augue ut, lobortis leo. Duis sed elit et ipsum auctor convallis. Donec non orci suscipit, eleifend tellus
      pretium, vehicula turpis. Mauris et justo et est cursus accumsan et vel elit. In egestas lobortis imperdiet. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus
      et ultrices posuere cubilia Curae; Etiam dictum vel lorem in varius. Etiam accumsan nibh at ex mollis, id porta leo sodales. Suspendisse mauris urna, faucibus in turpis et, porttitor lobortis lectus. Cras facilisis feugiat tortor sed laoreet. Nam
      cursus malesuada lorem sed bibendum. Sed dapibus, mi vel elementum vehicula, augue massa pulvinar erat, vitae rutrum eros nisi sed neque.
    </p>
    <p>
      Nulla sodales lectus vitae urna ullamcorper, eu mattis lacus iaculis. Praesent eleifend eu sem nec aliquet. Pellentesque consequat nisl ac odio efficitur, vitae interdum sapien gravida. Proin sed commodo leo. Quisque sem sem, euismod id sapien eget, fermentum
      consectetur turpis. Praesent aliquam eros id ipsum vehicula, aliquam pellentesque massa pellentesque. Etiam nec elit arcu. Donec eget ullamcorper nisl, in porta nibh. In non ante id elit tincidunt convallis. Suspendisse sit amet dictum sapien, vel
      lobortis mi. Mauris eu pharetra ante. Morbi vestibulum orci at augue pulvinar iaculis. Vestibulum quis dui et odio tristique laoreet eget id augue.
    </p>
    <p>
      Nulla finibus lorem in risus efficitur, at cursus nunc molestie. In pellentesque quis quam et sollicitudin. Mauris at turpis felis. Nulla facilisi. Cras pellentesque malesuada felis, sit amet dapibus lectus efficitur auctor. Mauris dictum eu nisl non
      commodo. Quisque at risus eget quam dictum aliquet. Curabitur malesuada magna et efficitur bibendum. Curabitur ultrices luctus lorem. Vivamus sodales elit quis metus mattis, pretium semper mi finibus.
    </p>
  </div>
</div>  

Добавляем обратно grid-gap , margin и padding — вы можете настроить явный набор высоты на sidebar — смотрите демонстрацию ниже:

 #top {
  position: sticky;
  top: 0;
  border: 1px solid red;
  width: 100%;
}

.container {
  display: grid;
  grid-gap: 50px;
  grid-template-columns: max-content 1fr;
  margin-top: 50px;
  margin-left: auto;
  margin-right: auto;
  max-width: 900px;
}

.sidebar {
  border: 1px solid blue;
  position: sticky;
  top: 0;
  /* ADDED */
  align-self: flex-start; /* override the default stretch */
  height: calc(100vh - 30px); /* set a fixed height */
  padding-top: 20px;
}

.content {
  border: 1px solid green;
}  
 <div id="top">
  sticky header
</div>
<div class="container">
  <div class="sidebar">
    sticky sidebar
  </div>
  <div class="content">
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus at ipsum mi. Integer laoreet a nisl quis imperdiet. Etiam sed ligula rutrum, viverra arcu vitae, mattis lectus. Aliquam rutrum eros id quam sodales volutpat. Suspendisse sed neque ut mauris
      luctus hendrerit. Suspendisse auctor aliquam rutrum. Sed sodales placerat est. Donec vel elit vitae ipsum ultrices tristique. Nulla auctor, dolor at porta laoreet, ex nisi auctor orci, in posuere enim arcu at tortor. Etiam sed ante mattis sem pharetra
      condimentum. Nullam a eros nec metus feugiat tincidunt vel sed lectus. Nunc accumsan nisi sit amet auctor rhoncus. Vestibulum diam risus, sodales non diam a, tristique ullamcorper erat.
    </p>
    <p>
      Aliquam posuere libero at felis maximus, quis pulvinar diam dictum. Integer id nisi non turpis bibendum suscipit. Duis pellentesque leo vitae elit mollis malesuada. Duis eget magna et odio mattis bibendum. Ut et rutrum diam, quis luctus mi. Duis in molestie
      elit. Nullam consequat turpis velit, sit amet venenatis tellus bibendum non. Etiam iaculis luctus sem, et aliquam nisl commodo et. In consectetur ac nibh ac porttitor. Nulla euismod facilisis faucibus. Phasellus sed risus convallis, elementum est
      nec, euismod lorem. Nulla sodales auctor dapibus. Curabitur euismod neque dolor, at sagittis arcu congue ultrices. Morbi nec finibus tortor.
    </p>
    <p>
      Aliquam vestibulum dictum nisi non sollicitudin. Integer ac magna viverra, cursus lorem quis, interdum ex. Phasellus id neque pulvinar, dignissim augue ut, lobortis leo. Duis sed elit et ipsum auctor convallis. Donec non orci suscipit, eleifend tellus
      pretium, vehicula turpis. Mauris et justo et est cursus accumsan et vel elit. In egestas lobortis imperdiet. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum ante ipsum primis in faucibus orci luctus
      et ultrices posuere cubilia Curae; Etiam dictum vel lorem in varius. Etiam accumsan nibh at ex mollis, id porta leo sodales. Suspendisse mauris urna, faucibus in turpis et, porttitor lobortis lectus. Cras facilisis feugiat tortor sed laoreet. Nam
      cursus malesuada lorem sed bibendum. Sed dapibus, mi vel elementum vehicula, augue massa pulvinar erat, vitae rutrum eros nisi sed neque.
    </p>
    <p>
      Nulla sodales lectus vitae urna ullamcorper, eu mattis lacus iaculis. Praesent eleifend eu sem nec aliquet. Pellentesque consequat nisl ac odio efficitur, vitae interdum sapien gravida. Proin sed commodo leo. Quisque sem sem, euismod id sapien eget, fermentum
      consectetur turpis. Praesent aliquam eros id ipsum vehicula, aliquam pellentesque massa pellentesque. Etiam nec elit arcu. Donec eget ullamcorper nisl, in porta nibh. In non ante id elit tincidunt convallis. Suspendisse sit amet dictum sapien, vel
      lobortis mi. Mauris eu pharetra ante. Morbi vestibulum orci at augue pulvinar iaculis. Vestibulum quis dui et odio tristique laoreet eget id augue.
    </p>
    <p>
      Nulla finibus lorem in risus efficitur, at cursus nunc molestie. In pellentesque quis quam et sollicitudin. Mauris at turpis felis. Nulla facilisi. Cras pellentesque malesuada felis, sit amet dapibus lectus efficitur auctor. Mauris dictum eu nisl non
      commodo. Quisque at risus eget quam dictum aliquet. Curabitur malesuada magna et efficitur bibendum. Curabitur ultrices luctus lorem. Vivamus sodales elit quis metus mattis, pretium semper mi finibus.
    </p>
  </div>
</div>