html - 滚动容器内的绝对定位 div 仅相对于未滚动位置定位

标签 html css css-position absolute

我正在创建一个目录侧边栏,我希望正常截断文本,但在悬停时展开以显示列表项的完整文本。 TOC 还应该可以与主要内容分开滚动(例如,TOC 始终可见,并且“主要”内容自行滚动)。

使用一些包装器和 position: absolute 我可以使文本从 TOC 容器中弹出。但是,如果列表项的祖先元素完全滚动,则具有绝对定位的元素会显示在该位置,就像父元素未滚动一样。

我尝试了不同修改的组合,例如在元素或直接父元素上添加 top: 0 ,使任何/所有祖先成为 absolute/relative 。导致以下结果之一:

  1. 没有任何变化
  2. 应该弹出的元素不再突破/可见x,而是位于正确的位置
  3. 我想要分解的元素位于父容器的顶部。

我正在使用一组嵌套网格,但如果有不同的方法来创建相同的容器,我会考虑它。

这是一个没有滚动的屏幕截图,它完成了目标: working without scroll

但是,当元素滚动时,您可以看到绝对位置元素似乎没有考虑父级滚动。

enter image description here

请参阅下面插入的代码。我在 li:hover#testcase 上创建了突破效果。

我目前使用 title 属性作为后备,因为它总是显示在顶部,但我无法设置样式或控制时间,因此在正确位置的突破效果仍然会更好。

/**reset.css*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
    display: block;
}

/** layout.css */

#app {
  margin: 0;
  height: 100vh;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas: 
    'header'
    'content'
    'footer';
}

#content {
  grid-area: content;
  overflow: auto;
}

#content {
  display: grid;
  grid-template-columns: 15vw 1fr;
  grid-template-rows: 1fr; 
  grid-template-rows: 100%; 
  grid-column-gap: 2vw;
}


main {
  max-width: 900px;
  margin-right: 5vw;
}


#toc {

  margin-left: 5px;
  margin-right: 5px;
  align-self: start; 
  height: 100%;


}



#toc{
  display: grid;
  grid-template-rows: auto ;
}

#toc > ul {
  overflow:hidden;
  overflow-y: auto;
  /* height: 100%; */
}



#toc:not(:hover) ul::-webkit-scrollbar{
  visibility: hidden;
}

#toc > ul {

  margin-bottom: 0;
  margin-top:0;

}





#toc h3{
  padding-top: 1em;
  padding-bottom: 1em;
}



header, footer{
  background-color: rgb(241, 248, 255);
}

#toc{
  background-color: rgb(246, 242, 255);
}

#toc ul{
  outline: 1px solid pink;
}

main{
  background-color: rgb(238, 255, 250);
}

/* toc.css */

#toc {
  line-height: 1.3;
}

#toc a::before{
  font-family: 'Noto Emoji', serif;
}

#toc li .toc-item-wrapper {
  display: inline-block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width:100%;
  height:1.3em;
}


/* #toc li:has(a[data-indent-section="true"])::before{ */
#toc li .toc-item-wrapper:has(a[data-indent-section="true"])::before{
  content: '↳';
  margin-left: .3em;
  margin-right: .1em;
}

/***/

#toc li:hover .toc-item-wrapper,
.toc-item-wrapper:has(a#testcase) {
  overflow: visible;
}

#toc li:hover a,
a#testcase
 {
  position:absolute;
  overflow: visible;
  outline: 3px solid #000;
  background-color: var(--jelly-25);
  padding-right:.5em;

}

#toc li{
  height:1.3em;
}
<!DOCTYPE html>
<html  lang="en">

<head>
  <title>TEST</title>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Emoji" type="text/css" media="all" />
  <link rel="stylesheet" href="css/reset.css" type="text/css" media="all" />
  <link rel="stylesheet" href="css/layout.css" type="text/css" media="all" />
  <link rel="stylesheet" href="css/toc.css" type="text/css" media="all" />

</head>

<body id="app">
  <header>
    <div>Header, nav, etc.</div>
  </header>
  <div id="content">


    <aside id="toc">
      <h3>Your Progress</h3>
      <ul>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="AAAAAAA">AAAAAAA 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a  href="#"  title="BBBBBBB">BBBBBBB 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#"  data-indent-section="true"  title="CCCCCCC">CCCCCCC 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a id="testcase" href="#" data-indent-section="true" title="DDDDDDD">DDDDDDD 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="EEEEEEE">EEEEEEE 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="FFFFFFF">FFFFFFF 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="GGGGGGG">GGGGGGG 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="HHHHHHH">HHHHHHH 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="IIIIIII">IIIIIII 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="JJJJJJJ">JJJJJJJ 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="KKKKKKK">KKKKKKK 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="LLLLLLL">LLLLLLL 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="MMMMMMM">MMMMMMM 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="NNNNNNN">NNNNNNN 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="OOOOOOO">OOOOOOO 0123456789 0123456789</a>
          </div>
        </li>        

      </ul>
    </aside>
    <main>
      <section>Main Content</section>
      <section>More Content</section>
    </main>
  </div>
  <footer>Site Footer</footer>
</body>

</html>

最佳答案

您可以创建一个不在带有 overflow: auto; 的 block 中且具有 position:fixed; 的自定义工具提示。然后您需要在 onscroll 事件发生后更改其位置。

或者您可以使用工具提示库,例如 Tippy.js :

例如,像这样:

document.querySelectorAll('.toc-item-wrapper a').forEach(el => {
  tippy(el, {
    content: el.textContent,
    placement: 'top-start',
    arrow: false,
    maxWidth: 'none',
    offset: [0, 0],
    duration: [0, 0],
  });
});
/**reset.css*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
    display: block;
}

/** layout.css */

#app {
  margin: 0;
  height: 100vh;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas: 
    'header'
    'content'
    'footer';
}

#content {
  grid-area: content;
  overflow: auto;
}

#content {
  display: grid;
  grid-template-columns: 15vw 1fr;
  grid-template-rows: 1fr; 
  grid-template-rows: 100%; 
  grid-column-gap: 2vw;
}


main {
  max-width: 900px;
  margin-right: 5vw;
}


#toc {

  margin-left: 5px;
  margin-right: 5px;
  align-self: start; 
  height: 100%;


}



#toc{
  display: grid;
  grid-template-rows: auto ;
}

#toc > ul {
  overflow:hidden;
  overflow-y: auto;
  /* height: 100%; */
}



#toc:not(:hover) ul::-webkit-scrollbar{
  visibility: hidden;
}

#toc > ul {

  margin-bottom: 0;
  margin-top:0;

}





#toc h3{
  padding-top: 1em;
  padding-bottom: 1em;
}



header, footer{
  background-color: rgb(241, 248, 255);
}

#toc{
  background-color: rgb(246, 242, 255);
}

#toc ul{
  outline: 1px solid pink;
}

main{
  background-color: rgb(238, 255, 250);
}

/* toc.css */

#toc {
  line-height: 1.3;
}

#toc a::before{
  font-family: 'Noto Emoji', serif;
}

#toc li .toc-item-wrapper {
  display: inline-block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width:100%;
  height:1.3em;
}


/* #toc li:has(a[data-indent-section="true"])::before{ */
#toc li .toc-item-wrapper:has(a[data-indent-section="true"])::before{
  content: '↳';
  margin-left: .3em;
  margin-right: .1em;
}

/***/

#toc li{
  height:1.3em;
}

#toc li a{
    color:blue;
}

/* tippy */

.tippy-box{
    transform:translateY(100%);
    background:none;
    color:inherit;
    outline: 3px solid #000;
    background-color: var(--jelly-25);
    padding:0;
    font:inherit;
}

.tippy-content{
    padding:0;
    background-color:rgb(246, 242, 255);
    line-height:inherit;
    color:blue;
    text-decoration:underline;
}
<body id="app">
  <header>
    <div>Header, nav, etc.</div>
  </header>
  <div id="content">


    <aside id="toc">
      <h3>Your Progress</h3>
      <ul>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="AAAAAAA">AAAAAAA 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a  href="#"  title="BBBBBBB">BBBBBBB 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#"  data-indent-section="true"  title="CCCCCCC">CCCCCCC 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a id="testcase" href="#" data-indent-section="true" title="DDDDDDD">DDDDDDD 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="EEEEEEE">EEEEEEE 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="FFFFFFF">FFFFFFF 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="GGGGGGG">GGGGGGG 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="HHHHHHH">HHHHHHH 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="IIIIIII">IIIIIII 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="JJJJJJJ">JJJJJJJ 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="KKKKKKK">KKKKKKK 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="LLLLLLL">LLLLLLL 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="MMMMMMM">MMMMMMM 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="NNNNNNN">NNNNNNN 0123456789 0123456789</a>
          </div>
        </li>
        <li>
          <div class="toc-item-wrapper">
            <a href="#" title="OOOOOOO">OOOOOOO 0123456789 0123456789</a>
          </div>
        </li>        

      </ul>
    </aside>
    <main>
      <section>Main Content</section>
      <section>More Content</section>
    </main>
  </div>
  <footer>Site Footer</footer>
</body>

<script src="https://unpkg.com/@popperjs/core@2"></script>
<script src="https://unpkg.com/tippy.js@6"></script>

关于html - 滚动容器内的绝对定位 div 仅相对于未滚动位置定位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76058359/

相关文章:

css - 如何使用CSS属性位置:fixed with top:50px and height:100%?

html - Bootstrap 导航栏对齐(3 列,带有响应式菜单)

javascript - 如何在 HTML 元素上创建函数而不是将元素作为参数传递

php - 301重定向到同名文件,同服务器,不同域名

javascript - css columns/flexbox 元素之间没有间隙

html - 文本对齐子元素不起作用

html - CSS相对定位和流程

javascript - 在 JQuery 或 JavaScript 中用 span 元素包裹高亮文本

单元格中的 HTML div - 拉伸(stretch)、定位等

html - 真的很困惑如何为我的旋转木马设置高度和宽度的百分比