0

Given this code:

header {
  text-align: center;
}
/* no necessary, only using it to simulate a big table */
p.text {
  width: 20rem;
  height: 50rem;
}
<html>

<body>
  <header>
    <h1>Page Title</h1>
    <details>
      <summary>Click Me</summary>
      <p>More information</p>
      <p>Even more stuff</p>
    </details>
  </header>
  <table>
    <tr>
      <td><p class="text">Lorem</p></td>
      <td><p class="text">ipsum</p></td>
      <td><p class="text">dolors</p></td>
      <td><p class="text">itamet</p></td>
      <td><p class="text">consectetura</p></td>
      <td><p class="text">dipiscinge</p></td>
      <td><p class="text">litsed</p></td>
      <td><p class="text">doeiusmod</p></td>
    </tr>
    <tr>
      <td><p class="text">Lorem</p></td>
      <td><p class="text">ipsum</p></td>
      <td><p class="text">dolors</p></td>
      <td><p class="text">itamet</p></td>
      <td><p class="text">consectetura</p></td>
      <td><p class="text">dipiscinge</p></td>
      <td><p class="text">litsed</p></td>
      <td><p class="text">doeiusmod</p></td>
    </tr>
  </table>
</body>

</html>

I would like the contents of <header> to stay centered when scrolling horizontally, but scroll out of view when scrolling vertically.

I've tried position: sticky; left: 0; with several variations of display, margin, etc, to no avail. The closest I've gotten it to work is this:

    header {
      text-align: center;
      position: fixed;
      top: 0;
      left: 0;
      width: 100vw;
      z-index: -1;
    }
    table {
      margin-top: 7rem;
    }

but that breaks when opening the <details> element and doesn't work at all in Firefox Mobile.

Trying to stick to a "pure", semantic solution. Not against a little Javascript, but would rather not use a framework.

Thanks in advance for your help.

jáquer
  • 304
  • 1
  • 9

3 Answers3

1

For position sticky to work horizontally (which would seem to be what is wanted here) the containing element must be bigger than the thing you want to stick.

Also, you have to be cautious of the overflow settings for ancestor elements. See position:sticky is not working for further discussion.

<!doctype html>
<html>
<head>
<title>sticking</title>
<style>
body {
  margin: 0;
  overflow: visible;
  width: fit-content;
}
header {
  width: 100vw;
  text-align: center;
  position: sticky;
  left: 0px;
}
/* no necessary, only using it to simulate a big table */
p.text {
  width: 20rem;
  height: 50rem;
}

</style>
</head>
<body>
  <header>
    <h1>Page Title</h1>
    <details>
      <summary>Click Me</summary>
      <p>More information</p>
      <p>Even more stuff</p>
    </details>
  </header>
  <table>
    <tr>
      <td><p class="text">Lorem</p></td>
      <td><p class="text">ipsum</p></td>
      <td><p class="text">dolors</p></td>
      <td><p class="text">itamet</p></td>
      <td><p class="text">consectetura</p></td>
      <td><p class="text">dipiscinge</p></td>
      <td><p class="text">litsed</p></td>
      <td><p class="text">doeiusmod</p></td>
    </tr>
    <tr>
      <td><p class="text">Lorem</p></td>
      <td><p class="text">ipsum</p></td>
      <td><p class="text">dolors</p></td>
      <td><p class="text">itamet</p></td>
      <td><p class="text">consectetura</p></td>
      <td><p class="text">dipiscinge</p></td>
      <td><p class="text">litsed</p></td>
      <td><p class="text">doeiusmod</p></td>
    </tr>
  </table>
</body>

Note: I don't have mobile Firefox to test this on. Let me know whether it works there or not.

A Haworth
  • 30,908
  • 4
  • 11
  • 14
  • That was it! Making the body's width narrower is the piece I was missing. Thank you very much for your help! – jáquer Oct 21 '22 at 14:09
0

Adding a scroll element wrapping the table would work but that would push the scroll bar towards the bottom.

header {
    text-align: center;
  }
  /* no necessary, only using it to simulate a big table */
  p.text {
    width: 20rem;
    height: 50rem;
  }
  .scroll {
    overflow-x: scroll;
  }
<header>
            <h1>Page Title</h1>
            <details>
                <summary>Click Me</summary>
                <p>More information</p>
                <p>Even more stuff</p>
            </details>
        </header>
        <div class="scroll">
            <table>
                <tr>
                    <td><p class="text">Lorem</p></td>
                    <td><p class="text">ipsum</p></td>
                    <td><p class="text">dolors</p></td>
                    <td><p class="text">itamet</p></td>
                    <td><p class="text">consectetura</p></td>
                    <td><p class="text">dipiscinge</p></td>
                    <td><p class="text">litsed</p></td>
                    <td><p class="text">doeiusmod</p></td>
                </tr>
                <tr>
                    <td><p class="text">Lorem</p></td>
                    <td><p class="text">ipsum</p></td>
                    <td><p class="text">dolors</p></td>
                    <td><p class="text">itamet</p></td>
                    <td><p class="text">consectetura</p></td>
                    <td><p class="text">dipiscinge</p></td>
                    <td><p class="text">litsed</p></td>
                    <td><p class="text">doeiusmod</p></td>
                </tr>
            </table>
        </div>
K i
  • 539
  • 5
  • 12
  • I appreciate the contribution, but this would be very confusing for the user. I would have loved to be able to apply `overflow-x: scroll;` tot he table itself, but that doesn't seem to work. – jáquer Oct 21 '22 at 03:25
0

Simplest solution is to put the header outside the element you are trying to scroll horizontally.

<body>
  <header class="fixed"></header>
  <table class="scroll"></table>
</body>

note: don't scroll the body element, this causes all child elements to behave unexpectedly, use .fixed { position: fixed; } .scroll { overflow-x: scroll }

Kuzi
  • 1
  • 1
  • Hi Kuzi. Welcome to SO! Thank you for your help. Alas, my code is already structured exactly how you suggest, and I tried adding the `overflow-x: scroll;` to the table's CSS and it didn't work. – jáquer Oct 21 '22 at 13:40