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

iOS 11.2.5下textarea旋转45deg时光标未同步旋转问题求助

解决iOS上旋转textarea光标异常的问题

相信你已经发现了,iOS Safari对应用了CSS旋转的textarea光标渲染有个挺烦人的bug——原生光标不会跟着元素一起旋转,反而显示成一个怪异的大框。这是因为Safari的文本光标渲染逻辑并没有适配CSS transform属性,下面给你几个可行的修复方案:

方案一:用伪元素模拟跟随旋转的光标

我们可以先隐藏原生光标,再用CSS伪元素做一个能跟着旋转的自定义光标,再配合JS实时调整位置:

.rotated-textarea {
  transform: rotate(45deg);
  caret-color: transparent; /* 隐藏原生光标 */
  position: relative;
  --cursor-top: 50%;
  --cursor-left: 50%;
}

/* 模拟光标样式 */
.rotated-textarea::after {
  content: '';
  position: absolute;
  width: 2px;
  height: 1.2em;
  background-color: #000;
  transform: rotate(-45deg); /* 反向旋转,抵消容器的旋转,保持光标垂直 */
  animation: blink 1s step-end infinite;
  pointer-events: none; /* 不干扰输入操作 */
  top: var(--cursor-top);
  left: var(--cursor-left);
}

@keyframes blink {
  50% { opacity: 0; }
}

然后补充一点JS代码,监听输入和点击事件,实时获取光标位置来调整伪元素的偏移:

const textarea = document.querySelector('.rotated-textarea');

// 监听需要更新光标位置的事件
textarea.addEventListener('input', updateCursor);
textarea.addEventListener('click', updateCursor);
textarea.addEventListener('focus', updateCursor);

function updateCursor() {
  const selectionStart = textarea.selectionStart;
  if (!textarea.firstChild) return;
  
  const range = document.createRange();
  const selection = window.getSelection();
  range.setStart(textarea.firstChild, selectionStart);
  range.setEnd(textarea.firstChild, selectionStart);
  const rect = range.getBoundingClientRect();
  const textareaRect = textarea.getBoundingClientRect();
  
  // 计算并设置光标位置的CSS变量
  textarea.style.setProperty('--cursor-top', `${rect.top - textareaRect.top}px`);
  textarea.style.setProperty('--cursor-left', `${rect.left - textareaRect.left}px`);
}

方案二:反向旋转内部内容,规避textarea旋转

这个思路更简单:让外部容器旋转,而textarea本身反向旋转回来,这样textarea实际上没有被旋转,光标就能正常显示,只是视觉上整体是旋转的:

<div class="rotate-container">
  <textarea class="no-rotate-textarea"></textarea>
</div>
.rotate-container {
  transform: rotate(45deg);
  width: 300px;
  height: 200px;
  overflow: hidden; /* 裁剪textarea超出容器的部分 */
}

.no-rotate-textarea {
  width: 100%;
  height: 100%;
  transform: rotate(-45deg); /* 反向旋转,抵消容器的旋转 */
  padding: 20px;
  box-sizing: border-box;
  border: 1px solid #ccc;
  resize: none;
}

这种方法不需要额外JS,原生光标完全正常,你只需要调整容器和textarea的尺寸、内边距,确保内容不会被裁剪,视觉对齐到位就行。

方案三:用contenteditable元素替代textarea

如果你的业务场景允许,可以把textarea换成contenteditable="true"的div,iOS对contenteditable元素的旋转兼容性要好很多,光标会自动跟随元素旋转:

<div class="rotated-editable" contenteditable="true"></div>
.rotated-editable {
  transform: rotate(45deg);
  width: 300px;
  height: 200px;
  border: 1px solid #ccc;
  padding: 10px;
  box-sizing: border-box;
  resize: vertical; /* 可选,模拟textarea的resize功能 */
}

需要注意的是,contenteditable和textarea的行为有差异,比如表单提交时需要手动获取它的内容,还要处理换行、格式保留等问题,需要根据你的实际需求调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:26:07