Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I add text at a position that is relative to a pseudo-element?

I am trying to add text that is aligned with a pseudo-element on a div. For reference, I am talking about the .div2::before in my code as that is the dashed line between the inner and outer circle. I want to add a label that says "Wall Thickness" as shown below. The text should adjust with the circle size as the inner/outer circle size will be increasing/decreasing but the text position should adapt. What is the best way to accomplish this?

jsFiddle: https://jsfiddle.net/Kaevonz/cjpkxg6L/6/

enter image description here

.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: start;
  height: 500px;
  border: 1px solid gray;
}

.elem {
  box-sizing: border-box;
}

.div1 {
  border-top: 3px solid #0DA8AA;
  border-left: 1px solid #0DA8AA;
  border-right: 1px solid #0DA8AA;
  height: 60px;
  width: 150px;
  background: white;
}

.div2 {
  border: 1px solid #0DA8AA;
  border-radius: 50%;
  width: 340px;
  height: 340px;
  background: white;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.div2::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50% - 0.5px;
  width: 50%;
  height: 1px;
  border-top: 0.5px dashed black;
  transform: translateY(-50%) rotate(45deg);
  transform-origin: right center;
}

.div3 {
  border: 1px solid #0DA8AA;
  border-radius: 50%;
  width: 120px;
  height: 120px;
  background: white;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 1;
}

.div4 {
  border-top: 0.5px dashed black;
  width: 100%;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) rotate(-45deg);
}

.div5 {
  border: 0.5px dashed black;
  width: 150px;
  height: 50px;
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  left: 50%;
  float: left;
}
<div class="container">
  <div class="elem div1"></div>
  <div class="elem div2">
    <div class="elem div3">
      <div class="elem div5">
      </div>
      <div class="elem div4">
      </div>
    </div>
  </div>
</div>
like image 999
Kaevonz Avatar asked Oct 14 '25 18:10

Kaevonz


1 Answers

We need two elements within each other. Since we can't do that with pseudo elements, we need to add one element to the markup.

The newly added element will serve as a reference for where the text should be placed, so we align it exactly the same way as we would the first pseudo element.

And finally we use a child element or preferably a pseudo element for the text.

Note: for pseudo elements, text can be added via attributes.

DEMO

.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: start;
  height: 500px;
  border: 1px solid gray;
}

.elem {
  box-sizing: border-box;
}

.div1 {
  border-top: 3px solid #0DA8AA;
  border-left: 1px solid #0DA8AA;
  border-right: 1px solid #0DA8AA;
  height: 60px;
  width: 150px;
  background: white;
}

.div2 {
  border: 1px solid #0DA8AA;
  border-radius: 50%;
  width: 340px;
  height: 340px;
  background: white;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.div2::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50% - 0.5px;
  width: 50%;
  height: 1px;
  border-top: 0.5px dashed black;
  transform: translateY(-50%) rotate(45deg);
  transform-origin: right center;
}

.div3 {
  border: 1px solid #0DA8AA;
  border-radius: 50%;
  width: 120px;
  height: 120px;
  background: white;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 1;
}

.div4 {
  border-top: 0.5px dashed black;
  width: 100%;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) rotate(-45deg);
}

.div5 {
  border: 0.5px dashed black;
  width: 150px;
  height: 50px;
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  left: 50%;
  float: left;
}


/* NEW */

.text {
  height: 1px;
  position: absolute;
  left: 0;
  top: 50%;
  width: 50%;
  transform: translateY(-50%) rotate(45deg) translateX(-20%);
  transform-origin: right center;
}

.text:before {
  content: 'WE HAVE TEXT, lots of it';
  transform: translateY(-50%) rotate(-135deg);
  position: absolute;
  right: 100%;
  writing-mode: vertical-rl;
  height: 100px;
  /* height as width */
}


/* Preview */

.div2 {
  animation: x 1s linear alternate infinite;
}

@keyframes x {
  from {
    height: 300px;
    width: 300px;
  }
  to {
    height: 450px;
    width: 450px;
  }
}
<div class="container">
  <div class="elem div1"></div>
  <div class="elem div2">
    <div class="text"></div> <!-- NEW -->
    <div class="elem div3">
      <div class="elem div5">
      </div>
      <div class="elem div4">
      </div>
    </div>
  </div>
</div>

I had to do some text alignment magic, which may or may not be optimal, but at this point I believe the idea is passed across.