skip to Main Content

Image 1 :

Image 2:

I have this element on my site that is supposed to scroll horizontally(overflow-x: scroll) on smaller screens, the issue is, the properties I applied to its children only appear on the parts the were visible before scrolling, in the example images you can see the background color is not the same throughout the elements, also it’s not possible to interact with the area outside the selected part. I’ll add this example to make my problem clearer.

function RenderPedidos() {
  return (
    pedidos.map((pedido, index) => ( <
      div key = {
        index
      }
      id = {
        index
      }
      name = "pedido"
      className = {
        (pedido.finalizado) ? "pedidos-container__content__pedido-finalizado" : "pedidos-container__content__pedido"
      }
      onClick = {
        event => handleClickPedido(event)
      } >
      <
      p > {
        (pedido.id > 9999) ? String(pedido.id).slice(0, 4) + '...' : pedido.id
      } < /p> <
      p > {
        (pedido.nome.length > 20) ? pedido.nome.slice(0, 21) + '...' : pedido.nome
      } < /p> <
      p > {
        (pedido.descricao.length > 35) ? pedido.descricao.slice(0, 36) + '...' : pedido.descricao
      } < /p> <
      p > {
        (pedido.material.length > 20) ? pedido.material.slice(0, 21) + '...' : pedido.material
      } < /p> <
      p > {
        "R$ " + pedido.valor.toFixed(2)
      } < /p> <
      p > {
        pedido.quantidade
      } < /p> <
      p > {
        (pedido.cliente.length > 20) ? pedido.cliente.slice(0, 21) + '...' : pedido.cliente
      } < /p> <
      p > {
        formatDatetime(pedido.prazo, 0)
      } < /p> <
      /div>
    ))
  )
}
&__content {
  margin-top: 25px;
  width: 100%;
  background-color: white;
  border-radius: 5px;
  box-shadow: 4px 4px 5px rgb(214, 214, 214);
  overflow-x: scroll;
  &__header {
    @include flex(1, 0);
    justify-content: start;
    p {
      @include flex(0, 0);
      width: 100%;
      text-align: center;
      height: 100%;
      height: 50px;
      padding-right: 10px;
      border-bottom: 1px solid rgb(202, 202, 202);
      &:nth-child(1) {
        width: 60px;
        min-width: 60px
      }
      &:nth-child(2) {
        width: 100%;
        min-width: 200px
      }
      &:nth-child(3) {
        width: 100%;
        min-width: 350px;
      }
      &:nth-child(4) {
        width: 100%;
        min-width: 200px
      }
      &:nth-child(5) {
        width: 100%;
        min-width: 150px
      }
      &:nth-child(6) {
        width: 60px;
        min-width: 60px
      }
      &:nth-child(7) {
        width: 100%;
        min-width: 200px;
      }
      &:nth-child(8) {
        width: 200px;
        min-width: 200px;
      }
    }
  }
  &__pedido,
  &__pedido-finalizado {
    @include flex(0, 0);
    justify-content: start;
    padding: 10px 0;
    transition: all ease-in-out 125ms;
    &:hover {
      cursor: pointer;
      background-color: rgb(247, 247, 247)
    }
    p {
      @include flex(0, 0);
      text-wrap: nowrap;
      overflow-x: hidden;
      padding-right: 10px;
      pointer-events: none;
      user-select: none;
      &:nth-child(1) {
        width: 60px;
        min-width: 60px
      }
      &:nth-child(2) {
        width: 100%;
        min-width: 200px
      }
      &:nth-child(3) {
        width: 100%;
        min-width: 350px;
      }
      &:nth-child(4) {
        width: 100%;
        min-width: 200px
      }
      &:nth-child(5) {
        width: 100%;
        min-width: 150px
      }
      &:nth-child(6) {
        width: 60px;
        min-width: 60px
      }
      &:nth-child(7) {
        width: 100%;
        min-width: 200px;
      }
      &:nth-child(8) {
        width: 200px;
        min-width: 200px;
      }
    }
  }
  &__pedido-finalizado {
    filter: opacity(25%);
    &:hover {
      background-color: rgb(221, 221, 221)
    }
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
<div className="pedidos-container__content">
  <div className="pedidos-container__content__header">
    <p>ID</p>
    <p>Nome</p>
    <p>Descrição</p>
    <p>Material</p>
    <p>Valor</p>
    <p>Qtd.</p>
    <p>Cliente</p>
    <p>Prazo</p>
  </div>
  <RenderPedidos/>
</div>

I tried to tinker with some properties but I had no meaningful outcome.

2

Answers


  1. Chosen as BEST ANSWER

    It was actually really simple to solve. All I had to do was assign the parent's scrollWidth to the children's width, using JS.

    Check the codepen example.

    const container = document.getElementById("container");
    const text2 = document.getElementById("two");
    text2.style.width = container.scrollWidth + "px";
    * {
      margin: 0
    }
    
    body,
    html {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100%
    }
    
    #container {
      width: 500px;
      height: 200px;
      background-color: #b3b3b3;
      border-radius: 10px;
      padding: 5px;
      margin: 5px;
      overflow: auto;
    }
    
    p {
      text-wrap: nowrap;
    }
    
    p:hover {
      cursor: pointer;
      background-color: white;
    }
    <div id="container">
      <p id="two">The Syrian Democratic Forces (SDF) is a Kurdish-led coalition formed by ethnic militias and rebel groups, and serves as the official military wing of the ...</p>
    </div>


  2. The issue has to do with how block elements work. p tags or paragraph tags are by default block-level elements, and styles applied to block-level elements will only be applied up to the element’s container’s maximum width. In this case (in the example you linked), your container has a width of 500px, so the styles applied to it are only applied up to the point where the content is within the container. Once it overflows, the styles no longer apply to the overflowed content.

    However, not every style behaves this way. For instance, if you change the text color on hover, it would actually work because there is still text in the overflowing area, but there is no background. Therefore, background-color can only apply to the part of the container that actually has a background, which is the 500px width you applied. It would seem that the DOM doesn’t consider the overflow area to have a background until it is rendered (but that is a bit of an educated guess that only someone who can understand the render engine code can know for fact).

    * {
      margin: 0
    }
    
    body,
    html {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100%
    }
    
    #container {
      width: 500px;
      height: 200px;
      background-color: #b3b3b3;
      border-radius: 10px;
      padding: 5px;
      margin: 5px;
      overflow: auto;
    }
    
    p {
      text-wrap: nowrap;
      display: inline;
    }
    
    p:hover {
      cursor: pointer;
      background-color: white;
    }
    <div id="container">
      <p>ID</p>
      <p>The Syrian Democratic Forces (SDF) is a Kurdish-led coalition formed by ethnic militias and rebel groups, and serves as the official military wing of the ...</p>
    </div>

    One last "gotcha" is now the p tags that aren’t the full width of the block, and only highlight to the element’s content width (and not the entire block). You will need to target only the overflowing paragraph tags if you want the highlight to expand the entire block on elements that are not overflowing. For instance, the first paragraph tag with the text "ID" will not fill up the block anymore with position inline because its text is not 500px (or more) in width. However, it does style the paragraph tags with the background-color white in the overflow area. If you wanted to do this, you would need a little JavaScript to help. It might look something like this:

    const isOverflowX = (element) => element.scrollWidth > element.clientWidth;
    
    document.querySelectorAll('#container p').forEach(p => {
      if (isOverflowX(p)) {
        p.classList.add('inline');
      }
    });
    * {
      margin: 0
    }
    
    body,
    html {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100%
    }
    
    #container {
      width: 500px;
      height: 200px;
      background-color: #b3b3b3;
      border-radius: 10px;
      padding: 5px;
      margin: 5px;
      overflow: auto;
    }
    
    p {
      text-wrap: nowrap;
    }
    
    p:hover {
      cursor: pointer;
      background-color: white;
    }
    
    .inline {
      display: inline;
    }
    <div id="container">
      <p>ID</p>
      <p>The Syrian Democratic Forces (SDF) is a Kurdish-led coalition formed by ethnic militias and rebel groups, and serves as the official military wing of the ...</p>
    </div>

    One small last thing that is technically wrong on what I said above. I said that the background area was the 500px that you defined in your CSS, but actually it’s the 500px minus any padding.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search