You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

带行号的预格式化文本响应式样式异常问题排查

响应式模式下预格式化文本布局错乱,width设置不生效的问题排查与修复

我自己写了一段JS给预格式化文本添加样式,没有使用专门的语法高亮工具,但在响应式模式下出现了布局错乱的问题。我给.code-inner设置了width:80%,但它仍然会占据全屏宽度。想请教这是不是overflow:auto属性导致的溢出问题,还是我的代码存在错误?

以下是我的实现代码:

JavaScript 代码

function preformatted() { var pre = document.getElementsByTagName('pre'), pl = pre.length; if(jQuery(pre).find('.line-number').length){ return; } for (var i = 0; i < pl; i++) { pre[i].innerHTML = '<span class="line-number"></span>' + pre[i].innerHTML + '<span class="cl"></span>'; var num = pre[i].innerHTML.split(/\n/).length; for (var j = 0; j < num; j++) { var line_num = pre[i].getElementsByTagName('span')[0]; line_num.innerHTML += '<span>' + (j + 1) + '</span>'; } } } preformatted();

CSS 代码

.code-inner { position: relative; width: 80%; } pre { overflow:auto; margin:0 0 1em; padding:.5em 2em; white-space: pre-line; } .code-wrap { background: linear-gradient(to right, #264567 60px, #73b9ff 0% 80%); width: 100%; height: 200px; padding: 20px 10px; border-radius: 5px; box-shadow: 0 0 18px -7px #000; overflow-y: scroll; } pre code, pre .line-number { font:normal normal 16px/14px Lato, "Courier New",Courier,Monospace; color:black; display:block; line-height: 30px; } pre .line-number { float:left; margin:0 1em 0 -1em; text-align:right; color:#fff; } pre .line-number span { display:block; padding:0 .5em 0 1em; } pre .cl { display:block; clear:both; } /* Vertical Scroll */ .code-wrap::-webkit-scrollbar { width: 4px; } /* Track */ .code-wrap::-webkit-scrollbar-track { border-radius: 10px; margin: 10px; } /* Handle */ .code-wrap::-webkit-scrollbar-thumb { background: #fff; border-right: 4px #555555 solid; }

HTML 代码

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="code-inner"> <div class="code-wrap"> <pre> <code> ° Vivamus feugiat quam sed ipsum varius aliquam. ° In ac augue eu leo dignissim cursus hendrerit sed nulla. ° Sed dapibus justo id lectus rhoncus pulvinar. ° Aliquam sit amet enim ut nisl gravida lobortis. ° Nunc a sapien non lorem mollis viverra. ° Donec feugiat nunc quis condimentum feugiat. </code> </pre> </div> </div>

问题根源分析

咱们来一步步拆解问题:

  1. 盒模型计算错误导致宽度溢出
    你给.code-wrap设置了width:100%,同时还加了padding:20px 10px。默认情况下,CSS的盒模型是content-box,也就是元素的总宽度=设置的width + padding + border。这就导致.code-wrap的实际宽度会是.code-inner的80%宽度再加上左右各10px的padding,直接撑破了父容器,看起来就像.code-inner占了全屏。

  2. white-space属性设置不当
    你给<pre>设了white-space:pre-line,这个属性会合并连续空格,只保留换行符,但<pre>标签的初衷是保留原始的换行和空格。同时这个设置加上overflow:auto,在内容溢出时会触发横向滚动,但父容器宽度已经计算错误,进一步加剧了布局混乱。

  3. JS行号计数的小bug
    你的JS用pre[i].innerHTML.split(/\n/).length来统计行数,但innerHTML会包含HTML标签,拆分出来的换行数量可能不准确,导致行号多生成或者少生成,间接影响布局对齐。


具体修复方案

1. 统一盒模型(最关键)

给所有元素添加box-sizing:border-box,让padding和border都包含在设置的width里面,避免溢出:

* {
  box-sizing: border-box;
}

2. 调整容器宽度设置

把.code-wrap的width:100%去掉(或者保留也没关系,因为border-box已经让它的宽度计算正确了),同时给.code-inner加个margin:auto让它居中,更符合视觉习惯:

.code-inner {
  position: relative;
  width: 80%;
  margin: 0 auto; /* 新增:让容器居中 */
}
.code-wrap {
  background: linear-gradient(to right, #264567 60px, #73b9ff 0% 80%);
  /* 去掉width:100%,块级元素默认占满父容器 */
  height: 200px;
  padding: 20px 10px;
  border-radius: 5px;
  box-shadow: 0 0 18px -7px #000;
  overflow-y: scroll;
}

3. 修正<pre>的换行行为

把white-space:pre-line改成white-space:pre-wrap,这样既保留预格式化的换行和空格,又能在容器宽度不足时自动换行,避免横向滚动条出现:

pre {
  overflow:auto;
  margin:0 0 1em;
  padding:.5em 2em;
  white-space: pre-wrap; /* 替换pre-line */
}

4. 修复JS的行号计数逻辑

用textContent代替innerHTML来拆分换行,这样就能获取到纯文本的真实行数,避免HTML标签干扰:

function preformatted() { 
  var pre = document.getElementsByTagName('pre'), 
      pl = pre.length; 
  if(jQuery(pre).find('.line-number').length){ 
    return; 
  } 
  for (var i = 0; i < pl; i++) { 
    // 用textContent获取纯文本,统计真实行数
    var lineCount = pre[i].textContent.split(/\n/).length;
    pre[i].innerHTML = '<span class="line-number"></span>' + pre[i].innerHTML + '<span class="cl"></span>'; 
    var line_num = pre[i].getElementsByTagName('span')[0]; 
    for (var j = 0; j < lineCount; j++) { 
      line_num.innerHTML += '<span>' + (j + 1) + '</span>'; 
    } 
  } 
} 
preformatted();

修复后的效果

做完这些修改后:

  • .code-inner的80%宽度会正确生效,不会被子容器撑破
  • 响应式模式下,容器会随屏幕宽度自适应缩放,布局不会错乱
  • 行号和代码的对齐会更准确,滚动条也能正常工作

内容的提问来源于stack exchange,提问作者MAQ Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 01:07:35