使用viewport meta标签致keyframes动画文本截断及移动端卡顿问题
解决方案
一、修复文本自动换行与截断问题
原代码中导致文本截断且无法换行的核心原因是.output设置了white-space: nowrap(强制文本不换行)和overflow: hidden(超出内容隐藏),同时基于width的动画逻辑不适用于多行文本场景。具体修改如下:
调整
.output基础样式:- 移除
white-space: nowrap,允许文本自动换行 - 添加
max-width: 100%,限制内容不超出视口宽度 - 保留
overflow: hidden,配合新动画实现逐步展开效果 - 移除
display: inline-block,改用块级元素适配多行布局
- 移除
重写动画逻辑:
放弃基于width的动画(不支持多行文本展开),改用max-height+opacity+transform的组合,实现多行文本的平滑展开:
.output { border: 0px solid #ddd; padding: 10px; max-width: 100%; overflow: hidden; max-height: 0; opacity: 0; transform: translateY(10px); animation: answer 4s ease-out forwards; } @keyframes answer { from { max-height: 0; opacity: 0; transform: translateY(10px); } to { max-height: 2000px; /* 设置足够大的值,容纳所有可能的文本行数 */ opacity: 1; transform: translateY(0); } }
- 修正容器对齐与布局:
- 将
body中的align-items: left改为align-items: flex-start(left不是合法属性),避免内容被强制垂直居中导致截断 - 用
min-height: 100vh替代height: 100vh,确保内容超出时可正常滚动 - 给
body添加左右内边距,避免内容贴紧屏幕边缘:
- 将
body { display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; flex-direction: column; font-family: Tahoma, sans-serif; padding: 0 15px; box-sizing: border-box; }
二、提升移动端动画流畅度
移动端卡顿的主要原因是动画使用了触发重排的属性(如width),且未启用GPU加速。优化方案:
- 启用GPU加速:
在.output中添加以下样式,强制浏览器将元素放入GPU层渲染,减少重排压力:
.output { /* 原有样式 */ will-change: max-height, opacity, transform; transform: translateZ(0); }
优化动画属性:
- 避免使用
width、height、margin等触发重排的属性做动画,优先使用transform和opacity(仅触发合成,不触发重排重绘) - 将动画缓动函数从
linear改为ease-out,让动画结尾更自然,降低移动端渲染负载
- 避免使用
适配移动端表单:
原输入框的size="100px"会在移动端超出视口,改用CSS控制宽度:
input[name="user_input"] { width: calc(100% - 80px); /* 留出提交按钮空间 */ max-width: 600px; /* 限制桌面端最大宽度 */ }
修改后的完整HTML代码
<!doctype html> <html> <head> <title>ChatGPT project</title> <style> body { display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; flex-direction: column; font-family: Tahoma, sans-serif; padding: 0 15px; box-sizing: border-box; } .container { display: flex; align-items: flex-start; margin-top: 15px; } .image { margin-right: 20px; } .output { border: 0px solid #ddd; padding: 10px; max-width: 100%; overflow: hidden; max-height: 0; opacity: 0; transform: translateY(10px); will-change: max-height, opacity, transform; transform: translateZ(0); animation: answer 4s ease-out forwards; } @keyframes answer { from { max-height: 0; opacity: 0; transform: translateY(10px); } to { max-height: 2000px; opacity: 1; transform: translateY(0); } } input[name="user_input"] { width: calc(100% - 80px); max-width: 600px; } </style> <meta name="viewport" content="width=device-width, initial-scale=1" /> </head> <body> <p> Some blurb here...</p> <form method="POST"> Your question: <input type="text" name="user_input" autocomplete="off"> <input type="submit" value="Ask"> </form> {% if result %} <div class="container"> <div class="output">{{ result }}</div> </div> {% endif %} {% if end_result %} <p>{{ end_result }}</p> {% endif %} </body> </html>
内容的提问来源于stack exchange,提问作者medic_dev
相关产品推荐
相关产品推荐

