Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to vertically center text within a circle created with shape-outside?

Tags:

html

css

I have a paragraph element with some text that I have contained inside the confines of a circle by relying on the shape-outside CSS property. The HTML and CSS code thus far are as follows:

#testimony-wrapper {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  height: 100%;
  text-align: center;
}

.text {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0%;
  left: 0%;
  margin: 0%;
  font-weight: 500;
}

.text::before {
  content: "";
  width: 50%;
  height: 100%;
  float: left;
  shape-outside: polygon( 0 0, 98% 0, 50% 6%, 23.4% 17.3%, 6% 32.6%, 0 50%, 6% 65.6%, 23.4% 82.7%, 50% 94%, 98% 100%, 0 100%);
  shape-margin: 7%;
}

.text p {
  height: 100%;
  margin: 0;
}

.text p::before {
  content: "";
  width: 50%;
  height: 100%;
  float: right;
  shape-outside: polygon( 2% 0%, 100% 0%, 100% 100%, 2% 100%, 50% 94%, 76.6% 82.7%, 94% 65.6%, 100% 50%, 94% 32.6%, 76.6% 17.3%, 50% 6%);
  shape-margin: 7%;
}
<div id="testimony-wrapper">
  <div class="text">
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
  </div>
</div>

This is all well and good so long as the text occupies the entire height of the paragraph element. However, when there is less content, all the text is concentrated at the top of the circle. In a case like this, I would like to be able to vertically center the text inside the circle.

A lot of the solutions online suggest changing the display property to either table or flex to take advantage of the respective vertical-align and align-items properties these display types give you access to but doing so would break the shape-outside property I'm currently using to keep the content within the circle, which only works on block elements.

Is there any way to vertically align content without using either table or flex display or, if there isn't, is there a way to make the text display inside a circle without relying on the shape-outside property?

like image 386
Lea Avatar asked Sep 20 '25 06:09

Lea


1 Answers

First I would consider a different idea based on this previous answer then I don't think there is a trivial way to center text with shape-outside because all the common technique will break the float porperty.

One idea is to offset the text with some padding that you calculate dynamially on load and on resize:

$('.e').css('padding-top',($('.e').parent().height() - $('.e').height())/2);
$('.e').css('padding-top',($('.e').parent().height() - $('.e').height())/2);

$(window).resize(function() {
  $('.e').css('padding-top',($('.e').parent().height() - $('.e').height())/2);
  $('.e').css('padding-top',($('.e').parent().height() - $('.e').height())/2);
});
div.box {
  background: #333;
  color:#fff;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100vmin;
  height: 100vmin;
  text-align:justify;
  border-radius: 50%;
  overflow:hidden;
}

.box >div {
  height:100%;
}

.box >div > div {
    padding-top: 50px;
}

.box:before,
.box >div:before {
  content: '';
  float: left;
  height:100%;
  width: 50%;
  shape-outside: radial-gradient(farthest-side at var(--d,right), transparent 98%, red 0);
  shape-margin:5px;
}

.box >div:before {
  float: right;
  --d:left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box">
 <div><div class="e">Lorem ipsum dolor sit amet, eget orci, tinci dunt place rat in sociis. Pel lentes que ultri cies. cies. dolor ipsum tinci dunt place rat in sociis. Pel lentes que ultri cies. cies. dolor ipsum</div></div>
</div>

Note that I am calling the same logic twice because the height will change after the first padding adjustment and you we need another iteration to rectify. In reality we may need more iterations until it's dead center but 2 iterations seems to do the job.

I used jQuery for simplicity but you can easily translate it to vanilla JS

like image 156
Temani Afif Avatar answered Sep 23 '25 12:09

Temani Afif