html - 使绝对定位的 child 随着他们的上级动态调整大小

标签 html css css-position pdfjs mupdf

(请忽略空方块。)

  • 没有 CSS view { height: 45em; } ,我得到:enter image description here (位置重叠)
  • 使用 CSS view { height: 45em; } ,我得到:enter image description here (不需要,位置不匹配)

  • 我怎么会有蓝色<span>元素在第二种情况下正确定位?
    <view style="height: 45em;">
      <pdf-page>                                                    <!-- position: relative -->
        <text class="textLayer">                                    <!-- position: absolute -->
          <span style="left: 417.34px; top: 37.8391px; ..."></span> <!-- position: absolute -->
        </text>
        <svg width="595px" height="842px" preserveAspectRatio="none" viewBox="0 0 595 842" xmlns="http://www.w3.org/2000/svg" version="1.1">
          <g ⋯><g ⋯><text><tspan></tspan></text></g></g>
        </svg>
      </pdf-page>
    </view>
    
    这是 stackoverflow 中的完整案例(请参阅单击“显示代码片段”后第二个 Pane 中的 /* ← */):

    @namespace     url(http://www.w3.org/1999/xhtml);
    @namespace svg url(http://www.w3.org/2000/svg);
    
    /*pdf.css*/
    :root {
      --pdf-page-outline-color: #aaa;
      --pdf-page-background-color: #fcfcfc;
    }
    
    pdf-file { display: contents; }
    pdf-page {
      display: inline-block;
      outline: 1px solid var(--pdf-page-outline-color);
      background-color:  var(--pdf-page-background-color);
    }
    
    pdf-page { position: relative; }
    
    /* text.css */
    .textLayer {
      position: absolute;
      left: 0; top: 0; right: 0; bottom: 0;
      width: 100%; height: 100%;
     -overflow: hidden;
      opacity: 1;
     -line-height: 1;
    }
    
    .textLayer > span {
      color: transparent;
      position: absolute;
      white-space: pre;
      cursor: text;
      -webkit-transform-origin: 0% 0%;
              transform-origin: 0% 0%;
    }
    
    /**/
     view      { background: green; }
    .textLayer { background: rgba(0, 255, 0, .1); }
     svg|svg   { background: rgba(255, 0, 0, .1); }
    <style>
      view {
        height: 45em; /* ← */
        display: flex;
        overflow: auto;
        flex-direction: column;
        place-items: center;
        scroll-snap-type: y mandatory;
        overflow: auto;
      }
    
      pdf-page { height: 100%; scroll-snap-align: start; }
      svg { height: 100%; width: auto; }
    
      text { overflow: visible; background: rgb(0, 0, 0, .1); }
      text > span { background: rgba(0,0,255,.1); }
    </style>
    
    <view -onclick="this.requestFullscreen()">
      <pdf-page of="f" no="+1" svg="">
        <text class="textLayer">
          <span style="left: 417.34px; top: 37.8391px; font-size: 12px; font-family: sans-serif; transform: scaleX(1.07482);">Plenarprotokoll 16/3</span>
        </text>
        <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="595px" height="842px" preserveAspectRatio="none" viewBox="0 0 595 842">
          <g transform="matrix(1 0 0 -1 -8 850)">
            <g transform="">
              <text transform="matrix(12 0 0 12 425.34 801.2976) scale(1, -1)" xml:space="preserve">
                <tspan x="0 0.6672 0.9454 1.5016 2.1128 2.669 3.0582 3.6694 4.0586 4.6698 5.003 5.6142 6.1704 6.7816 7.0598 7.6132 8.1694 8.7256 9.0038" y="0" font-family="g_d0_f1" font-size="1px" fill="rgb(0,0,0)"></tspan>
              </text>
            </g>
          </g>
        </svg>
      </pdf-page>
    </view>

    (也可在 codepen 上查看:https://codepen.io/cetinsert/pen/MWeVxLe?editors=1100)

    最佳答案

    更精确的方法是 transform: scale(x, y) <text>图层一次调整大小,没有任何 <span style>位置值重新计算/单位更改。

    这个答案触发了我的商业元素的启动。
    WebPDF.prohttps://WebPDF.pro

    零依赖、真正的 HTML 原生 PDF Web 组件。


    const t = document.querySelector('text');
    const r = new ResizeObserver(textResize(t));
          r.observe(t);
    
    const textResize  = t => ([ a ]) => {
      const         e = t.parentNode.lastElementChild; // <svg> | <canvas>
      const         i = PDFPageElement.image(e);       // { height, width };
      const     h = e.clientHeight;
      const x = h / i.      height;
      const     w = e.clientWidth;
      const y = w / i.      width;
                        t.style.setProperty('transform', `scale(${x}, ${y})`);
    };
    
    PDFPageElement.image = i => { if (!i) return;
      switch (i.tagName) {
        case 'CANVAS':   return { height: i.height,               width: i.width               };
        default: /*SVG*/ return { height: i.height.baseVal.value, width: i.width.baseVal.value };
      }    
    };
    
    带有 1 个额外的 CSS 规则
    .textLayer { overflow: visible; }
    
    之前/之后
    before after

    关于html - 使绝对定位的 child 随着他们的上级动态调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64621411/

    相关文章:

    html - 我怎样才能在这段代码 css html 中像评级明星一样做悬停效果?

    html - 使用 CSS3 将 div 切换为复选框

    html - 了解堆叠在其他 z-index 中时的 css z-index

    javascript - 为一行中的每个单元格分配随机值

    php - 输入 RSS 链接并阅读标题(链接)并保存到数据库中的用户

    html - 位置 :fixed not working on chrome but works in firefox

    CSS:让一个高度和位置可变的子元素绝对结束在父元素的顶部?

    javascript - 禁用输入字段中的某些字符

    css - 在标题内垂直对齐 Bootstrap 徽章

    html - 将子 div 从父 div 中推出