Home > Net >  how to display span on top of a particular word by calculating its width and margin
how to display span on top of a particular word by calculating its width and margin

Time:07-29

I have a paragraph and sub texts based on the sub text value I need to display the type on top of the word.

enter image description here

as in above image I have 3 sub texts t1,t2,t3 accordingly I need to mark those range of words by keys sentance, noun, adjective.

let t1 = "some human languages in world is very unique";
let t2 = "human";
let t3 = "languages";

Unfortunately, the calculation of width and margin Left is proper but not working. As, one can see, Noun is not exactly above Human and same for languages it is slightly before the words.

How to show the span exactly above the range of word by calculating width and margin?

https://codesandbox.io/s/elegant-monad-xvqs35

import { useEffect } from "react";
import "./styles.css";

export default function App() {
  let w1,
    ml1,
    w2,
    ml2,
    w3,
    ml3 = 0;

  let str = "some human languages in world is very unique";
  let t1 = "some human languages in world is very unique";
  let t2 = "human";
  let t3 = "languages";

  w1 = (t1.length * 100) / str.length;
  ml1 = (str.indexOf(t1) * 100) / str.length;
  console.log(w1, ml1);

  w2 = (t2.length * 100) / str.length;
  ml2 = (str.indexOf(t2) * 100) / str.length;
  console.log(w2, ml2);

  w3 = (t3.length * 100) / str.length;
  ml3 = (str.indexOf(t3) * 100) / str.length;
  console.log(w3, ml3);

  return (
    <div className="App">
      <span
        style={{
          display: "inline-flex",
          alignItems: "flex-end",
          position: "relative"
        }}
      >
        <mark
          id="914_964_2511a4cf-a847-4ae2-ae22-ab253f030b77"
          data-start_offset="914"
          data-end="964"
          style={{
            color: "rgb(0, 0, 0)",
            background: "rgb(245, 245, 245)",
            position: "relative",
            padding: "0px",
            cursor: "default",
            display: "flex",
            flexDirection: "column-reverse",
            opacity: 1,
            lineHeight: "1.5em"
          }}
        >
          some human languages in world is very unique
          <span
            
            style={{
              color: "green",
              width: `${w1}%`,
              marginLeft: `${ml1}%`
            }}
          >
            Sentence
          </span>
          <span
            
            style={{
              color: "red",
              width: `${w2}%`,
              marginLeft: `${ml2}%`
            }}
          >
            Noun
          </span>
          <span
            
            style={{
              color: "blue",
              width: `${w3}%`,
              marginLeft: `${ml3}%`
            }}
          >
            adjective
          </span>
        </mark>
      </span>
    </div>
  );
}
  
.renderLabel {
  font-size: 0.7em;
  line-height: 1.3;
  background: rgb(255, 255, 255);
  font-weight: bold;
  margin: 0px -4px 0px -4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  text-align: initial;
  border-bottom: 1px solid;
  font-weight: 100;
}

.renderLabel:hover {
  background: #efefef;
  font-weight: bold;
  font-size: 0.72em;
}

CodePudding user response:

This is a very interesting question.

I make a less example on Replit. You can find solutions in it.

The points are:

  1. use the same element and the same content, and then get this size by Element.getBoundingClientRect() API, because using charset length to calculate that is not the best way, the font maybe not be a monospaced font.
  2. remember to control the white space.
  3. I think transform is better than margin in this scene.

sry, I visit Codepen slow, so I instead of Replit.

CodePudding user response:

.sentence{
  border-bottom: 1px solid green;
  color: green;
}

.noun{
  border-bottom: 1px solid red;
  color: red;
}

.adjective{
  border-bottom: 1px solid blue;
  color: blue;
}
<table>
  <tr>
    <td >Sentence</td>
    <td >Noun</td>
    <td >Adjective</td>
    <td ></td>
  </tr>
  <tr>
    <td>some</td>
    <td>human</td>
    <td>languages</td>
    <td>in world is very unique</td>
  </tr>
</table>

  • Related