css、js(vue)进行textarea自适应高度(超详细说明)


需求——如下图

黑色部分——页面布局为上左右下布局
红色部分——在右边有一个文本域,自适应高度,最小高度128px,最大高度不能超过右边屏幕的一半,里面有一个距离右下16px的确认按钮

在这里插入图片描述

一、纯css 的自适应高度(有问题,不推荐)

1.css代码

<style type="text/css">
  body, html{
    height: 100%;
    margin: 0;
    padding: 0;
  }
  .right {
    max-height: 50%;
    width: 50%;
    height: 100%;
    background-color: pink;
  }
  .box {
      
      display: grid;
      word-break: break-all;
  }
  .box::after {
      content: attr(data-replicated-value) " ";
      white-space: pre-wrap;
      visibility: hidden;
  }
  .box>textarea {
      resize: none;
      overflow-x: hidden;
      overflow-y: auto; 
  }
  .box>textarea,
  .box::after {
      border: 1px solid black;
      padding: 10px;
      grid-area: 1 / 1 / 2 / 2;
  }
</style>

2. html代码

<div class="right">
  <div class="box">
    <textarea name="text" id="cssTextarea" class="cssTextarea" onInput="this.parentNode.dataset.replicatedValue = this.value"></textarea>
  </div>
</div>

3. 代码截图说明

在这里插入图片描述

4. 效果和会出现的问题

效果如下图
问题1: 会导致有多余留白
问题2:超出限制的高度也不会出现滚动条(由问题1延申而来)
在这里插入图片描述

css纯样式实现自适应总结:是的,连按钮都没有加上,就已经改不动了,所以这种直接pass了,断了css纯样式实现textarea的自适应高度的念头后,来看看使用js的方式。

二、js 的自适应高度

0.思路

1:首先,将父盒子设置为display: flex,并设置flex-direction: column,使子元素垂直排列。
2: 然后,设置父盒子的最大高度为max-height: 50%,即最大高度为父盒子高度的一半。
3: 之后,给文本域设置最小高度,并隐藏横轴滚动,文本域超出纵轴滚动。
4: 其次,使用使用flex-grow: 1将文本域设置为可伸缩的,并使其占据剩余的空间。
5: 接着,设置resize: vertical,当文本输入时,允许用户根据输入的字符数动态调整垂直方向的高度变化。
6:最后,动态监听输入的内容,使得height等于scrollHiehgt即可。
优化:设置滚动条的优化样式,不需要的可以忽略

1.代码

1. css代码

 body, html{
  height: 100%;
  margin: 0;
  padding: 0;
}
.right {
  width: 50%;
  height: 100%;
  background-color: pink;
}
.textarea_box {
  display: flex;
  flex-direction: column;
  position: relative;
  padding-top: 16px;
  width: 100%;
  max-height: 50%;
  border-radius: 8px;
  border: 2px solid red;
  box-sizing: border-box;
}
.textareaText{
  margin-bottom: 56px;
  padding: 0 24px 0 24px;
  width: 100%;
  min-height: 78px;
  overflow-x: hidden;
  overflow-y: auto;
  box-sizing: border-box;
  color: #333;
  flex-grow: 1; /* 使文本域占据剩余空间 */
  resize: vertical; /* 允许用户调整垂直方向变化 */
}
.btn{
  position: absolute;
  right: 16px;
  bottom: 16px;
  padding: 0 16px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  border-radius: 4px;
  background: #1979ff;
  color: #ffffffe6;
  font-size: 16px;
  cursor: pointer;
}

2. html代码

<div class="right">
  <divclass="textarea_box">
    <textarea name="text" id="textareaId" class="textareaText"></textarea>
    <div class="btn">确认</div>
  </div>
</div>

3. js代码

<script>
 document.getElementById('textareaId').addEventListener("input", function() {
      this.style.height = "inherit";
      this.style.height = `${this.scrollHeight}px`;
    });
</script>

2.代码说明

在这里插入图片描述.

3.注意点导致的问题

(0)发现问题

1: 文本域中的padding会计算到文本域的高度中去,所以尽量给文本域的父盒子设置来达成效果
2:如果不考虑有按钮等的情况,只是需要一个自适应的盒子,就按照上图的六步走即可,根据设计稿达成效果。

(1)发现问题

如果你完全按照上面的代码查看效果后,你会发现,明明没有到父盒子的50%也有滚动条

在这里插入图片描述

(2)找到问题

如下图,父盒子的高为181px,文本域的高为105,减去底部按钮的56,父盒子的头部的padding-top: 16px
181-105-56-16 = 4 ,高度差了了4px,所以出现了滚动条
在这里插入图片描述

(3)解决问题

结合上面内容来看,如下图,是由于border的距离导致的,解决方式也很简单,删除这行即可
在这里插入图片描述

(4)其他解决问题

思考:如果不是border导致的,而是多出来的padding或者margin导致的,是否有别的解决方式?
解决方式:给滚动高度加上少的距离即可
在这里插入图片描述

4. 滚动条优化样式(可忽略)

注意点:滚动条前面的变量 需要和文本域的类名或者id名一致即可

.textareaText{
  margin-bottom: 56px;
  padding: 0 24px 0 24px;
  width: 100%;
  min-height: 78px;
  overflow-x: hidden;
  overflow-y: auto;
  box-sizing: border-box;
  color: #333;
  flex-grow: 1; /* 使文本域占据剩余空间 */
  resize: vertical; /* 允许用户调整垂直方向变化 */
}
/* 滚动条的优化样式,可忽略 */
/*滚动条整体样式*/
.textareaText::-webkit-scrollbar {
  width:4px;
  height:4px;
}
.textareaText::-webkit-scrollbar-thumb{
  border-radius:5px;
  box-shadow: inset005pxrgba(0,0,0,0.2);
  -webkit-box-shadow: inset005pxrgba(0,0,0,0,0.2);
  background: rgba(0,0,0,0,0.2);
}
.textareaText::-webkit-scrollbar-track{
  box-shadow: inset005pxrgba(0,0,0,0,0.1);
  -webkit-box-shadow: inset005pxrgba(0,0,0,0,0.1);
  border-radius: 0;
  background: rgba(0,0,0,0,0.1);
}

在这里插入图片描述

优化滚动条的详细教程,可以看我之前写的文章滚动条如何设置样式和滚动条悬浮显示与隐藏

三、vue 的自适应高度

按照js的改就好了,把监听input事件改成watch文本域输入的值就好,思路都是一样的。

总结

1:没有纯css能完美完成文本域的自适应高度
2:html+css+js 完成文本域的自适应高度思路

  1. 首先,将父盒子设置为display: flex,并设置flex-direction: column,使子元素垂直排列。
  2. 然后,设置父盒子的最大高度为max-height: 50%,即最大高度为父盒子高度的一半。
  3. 之后,给文本域设置最小高度,并隐藏横轴滚动,文本域超出纵轴滚动。
  4. 其次,使用使用flex-grow: 1将文本域设置为可伸缩的,并使其占据剩余的空间。
  5. 接着,设置resize: vertical,当文本输入时,允许用户根据输入的字符数动态调整垂直方向的高度变化。
  6. 最后,动态监听输入的内容,使得height等于scrollHiehgt即可。
    优化:设置滚动条的优化样式,不需要的可以忽略

补充——resize: vertical;

(1)取值: resize: none | horizontal | vertical | both | initial | inherit;
(2)作用:
none此属性的值,不允许调整元素的大小。
horizontal:此值允许用户调整元素宽度的大小。它将在水平方向上调整元素的大小。有一种用于控制元素宽度的单向水平机制。
vertical::它允许用户调整元素高度的大小。它将在垂直方向上调整元素的大小。有一个用于控制元素高度的单向垂直机制。
both::它允许用户调整元素的宽度和高度。
initial:。将属性设置为默认值。
inherit:它从其父元素继承属性。
(3)文本域使用和不使用resize: vertical的区别
如下图:不使用的话横轴纵轴可以同时修改宽高,使用了允许用户只能修改高度
不使用的话

若你对文本域自适应高度还有疑问,请查看我的文章:textarea自适应高度二——(设置隐藏div获取高度和仿element-ui组件)https://blog.csdn.net/weixin_44784401/article/details/131597784

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值