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

仅当左侧span为单行时在两个span间添加连字符

需求:根据左侧文本是否单行动态显示连字符

我有一个包含两个span元素的容器,两个span的内容不固定,没法只用媒体查询处理——比如左侧span的文本长度有时是20字符,有时是100字符。

要求很明确:当左侧span文本是单行时,在两个span之间加连字符;当左侧文本换行时,移除连字符。

组件代码

import React from "react";
import styled from "styled-components";

const Container = styled.div`
  display: flex;
  height: 44px;
  align-items: center;
  justify-content: center;
  cursor: pointer;
`;

const Wrapper = styled.div`
  display: flex;
  flex-direction: row;
  align-items: center;
  cursor: pointer;
  overflow: hidden;
  padding: 0 10px;
`;

const Text = styled.p`
  font-weight: normal;
  color: #ffffff;
  font-size: 14px;
  display: flex;
`;

const Left = styled.span`
  white-space: pre-line;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-right: 5px;
  background: green;
  &::after {
    content: " - ";
  }
`;

const Right = styled.span`
  background: blue;
`;

const Content = ({ rightText, leftText }) => {
  return (
    <Container>
      <Wrapper>
        <Text>
          <Left>{leftText}</Left>
          <Right>{rightText}</Right>
        </Text>
      </Wrapper>
    </Container>
  );
};

export default Content;

当前遇到的问题:第一个实例的左侧文本已经换行,但右侧还是显示了连字符(这是不需要的);另外两个单行的实例则需要保留连字符。

效果示例

请问能否通过CSS或JS实现仅当左侧文本为单行时添加连字符的效果?


解决方案

方法一:纯CSS实现(依赖现代浏览器特性)

核心思路是利用:has选择器和文本换行逻辑,控制连字符的显示:

  1. 调整组件结构,把连字符单独抽成一个元素:
<Text>
  <Left>{leftText}</Left>
  <Hyphen> - </Hyphen>
  <Right>{rightText}</Right>
</Text>
  1. 修改样式:
const Text = styled.p`
  font-weight: normal;
  color: #ffffff;
  font-size: 14px;
  display: flex;
  flex-wrap: wrap; /* 允许换行 */
`;

const Left = styled.span`
  white-space: pre-line;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-right: 5px;
  background: green;
`;

const Hyphen = styled.span`
  /* 默认显示连字符 */
  display: inline;
  /* 当左侧文本换行后,Left元素会占据整行,Hyphen被挤到下一行,此时隐藏 */
  ${Text}:has(${Left}:nth-child(1):not(:last-child)) & {
    display: none;
  }
`;

这种方法无需JS,完全靠CSS逻辑判断,但:has选择器需要浏览器版本支持(Chrome 105+、Firefox 121+等)。

方法二:JS监听实现(兼容性拉满)

通过计算元素高度和行高的关系,判断是否为单行,动态控制连字符渲染:

  1. 修改组件,添加ref和状态:
import React, { useEffect, useRef, useState } from "react";
import styled from "styled-components";

// 保留原有Container、Wrapper、Text、Right样式,修改Left去掉::after
const Left = styled.span`
  white-space: pre-line;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-right: 5px;
  background: green;
`;

const Content = ({ rightText, leftText }) => {
  const leftRef = useRef(null);
  const [isSingleLine, setIsSingleLine] = useState(true);

  useEffect(() => {
    const checkIsSingleLine = () => {
      if (!leftRef.current) return;
      // 获取行高和元素实际高度,对比判断是否单行
      const computedStyle = window.getComputedStyle(leftRef.current);
      const lineHeight = parseFloat(computedStyle.lineHeight);
      const elementHeight = leftRef.current.offsetHeight;
      setIsSingleLine(elementHeight <= lineHeight);
    };

    // 初始检查+监听窗口变化
    checkIsSingleLine();
    window.addEventListener("resize", checkIsSingleLine);
    return () => window.removeEventListener("resize", checkIsSingleLine);
  }, [leftText]);

  return (
    <Container>
      <Wrapper>
        <Text>
          <Left ref={leftRef}>{leftText}</Left>
          {isSingleLine && <span> - </span>}
          <Right>{rightText}</Right>
        </Text>
      </Wrapper>
    </Container>
  );
};

export default Content;

这种方法兼容性好,能适配所有主流浏览器,同时能响应窗口大小变化和文本内容更新,逻辑清晰易懂。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 07:06:21