首页 > 解决方案 > Center responsive elements in horizontal scroll container

问题描述

I have created a container (red border with line denoting the center) that scrolls horizontally if there is overflow.

The first child (purple block) of this container is always a button.

enter image description here

When you click this button, it adds additional children to the container.

enter image description here

What I am trying to do is figure out a way with pure CSS, so that the first child is always centered when the app is loaded, and the last child element in the container, if there is more than one child, can also be scrolled to the very center of the container.

I am having difficulties figuring this out because I have applied a min-width (i.e. 100px) in addition to a responsive width (i.e. 25vw) to the child elements.

The way I was initially planning on achieving this was by applying a padding-left to the parent container, and then an ::after pseudo element to :not(.first-child).children:last-child, but then I realized the approach is not sufficient if I want it to be completely responsive. However, I know I can manually calculate at which width min-width will be triggered and then use a @media query, but I am hoping there is a better way.

#container {
  width: 100%;
  height: 100%;
  padding-left: ; /* Half the window width minus half the width of the child. */
  overflow-x: scroll;
  display: flex;
  align-items: center;
  background: skyblue;
  box-sizing: border-box;
  border: solid red 2px;
}

#container::-webkit-scrollbar {
  display: none;
}

.children {
  width: 25vw;
  min-width: 100px;
  height: 50%;
  min-height: 200px;
  position: relative;
  margin-right: 5%;
  display: flex;
  justify-content: center;
  align-items: center;
  background: purple;
}

:not(.first-child).children:last-child::after {
  content: '';
  width: ; /* Half the window width minus half the width of the child. */
  height: 100%;
  position: relative; /* relative or absolute      */
  left: ;             /* and offset appropriately. */
  transform: ;        /*                           */
}

Does anybody have any ideas of how to do this?

标签: htmlcssflexbox

解决方案


You can apply margin-left to the first child and to deal with the min-width you can use media query. When the screen is less than 400px the 25vw will be less than 100px and you change the value to consider the 100px.

#container {
  position: fixed;
  top:0;
  left:0;
  width: 100%;
  height: 100%;
  overflow-x: scroll;
  display: flex;
  align-items: center;
  background: 
    linear-gradient(red,red) center/1px 100% no-repeat,
    skyblue;
  box-sizing: border-box;
  border: solid red 2px;
}

#container::-webkit-scrollbar {
  display: none;
}

.children {
  width: 25vw;
  min-width: 100px;
  height: 40%;
  min-height: 100px;
  position: relative;
  margin-right: 5px;
  display: flex;
  justify-content: center;
  align-items: center;
  background: purple;
  flex-shrink:0; /* don't forget this to avoid the shrink */
}

.children:first-child {
  margin-left: calc(50% - 12.5vw);
}

@media (max-width:400px) {
  .children:first-child {
    width: 25vw;
    min-width: 100px;
    margin-left: calc(50% - 50px);
  }
}
<div id="container">
  <div class="children"></div>
  <div class="children"></div>
  <div class="children"></div>
  <div class="children"></div>
</div>

Without media query you can consider a pseudo element where you will have a max-width constraint:

#container {
  position: fixed;
  top:0;
  left:0;
  width: 100%;
  height: 100%;
  overflow-x: scroll;
  display: flex;
  align-items: center;
  background: 
    linear-gradient(red,red) center/1px 100% no-repeat,
    skyblue;
  box-sizing: border-box;
  border: solid red 2px;
}

#container::-webkit-scrollbar {
  display: none;
}

.children {
  width: 25vw;
  min-width: 100px;
  height: 40%;
  min-height: 100px;
  position: relative;
  margin-right: 5px;
  display: flex;
  justify-content: center;
  align-items: center;
  background: purple;
  flex-shrink:0;
}

#container:before { 
  content:"";
  width: calc(50% - 12.5vw);
  max-width:calc(50% - 50px);
  flex-shrink:0;
}
<div id="container">
  <div class="children"></div>
  <div class="children"></div>
  <div class="children"></div>
  <div class="children"></div>
</div>


推荐阅读