I am trying to vertically align some text to a circle having a shape-outside property.
I am looking for a pure css solution.
See jsfiddle: https://jsfiddle.net/dybt94ds/
.wrap {
height: 220px;
width: 400px;
}
.circly {
background: red;
height: 200px;
width: 200px;
border-radius: 50%;
float: left;
shape-outside: circle();
}
<div class="wrap">
<div class="circly"></div>
<div class="text">
I am lots of text. I should always be verticly centered to the middle of the circle.
</div>
</div>
<div class="wrap">
<div class="circly"></div>
<div class="text">
I am lots of text. I should always be verticly centered to the middle of the circle. I am lots of text. I should always be verticly centered to the middle of the circle.
</div>
</div>
<div class="wrap">
<div class="circly"></div>
<div class="text">
I am lots of text. I should always be verticly centered to the middle of the circle. I am lots of text. I should always be verticly centered to the middle of the circle. I am lots of text. I should always be verticly centered to the middle of the circle.
</div>
</div>
To center both vertically and horizontally, use padding and text-align: center : I am vertically and horizontally centered.
To align text vertically on a page, head over to the “Layout” tab and select the small icon in the bottom-right corner of the “Page Setup” group. This opens the “Page Setup” dialog box. Select the “Layout” tab and then click the arrow next to “Vertical Alignment” in the “Page” section. A selection of vertical alignment options will appear.
If you mean you intend to vertically and horizontally center your text in the circle, you can try this method: The <span> element allows us to position the text independently from the circle itself, and I have taken the liberty to convert your text to normal sentence case, and then convert it to uppercase using CSS.
Set the CSS transform property ¶ When we have position: absolute, top: 50%, left: 50%, the calculations are made starting from the upper left corner. To position the text in the center, we must “move” it -50% left and 50% up by setting transform: translate (-50%;-50%). Example of vertically aligning a text with the CSS transform property: ¶
Set the margin to "auto" to make all margins equal and make the child <div> to be centered vertically as well as horizontally. Example of vertically aligning a text with the CSS position property:
js to the rescue... Calculate the top padding for the text by retrieving the text div
offset height.
var elements = document.getElementsByClassName('text');
for (i = 0; i < elements.length; i++) {
var pad = (200 - elements[i].offsetHeight) / 2;
elements[i].style.paddingTop = pad + "px";
}
.wrap {
height: 220px;
width: 400px;
}
.circly {
background: red;
height: 200px;
width: 200px;
border-radius: 50%;
float: left;
shape-outside: circle();
}
<div class="wrap">
<div class="circly"></div>
<div class="text">
I am lots of text. I should always be verticly centered to the middle of the circle.
</div>
</div>
<div class="wrap">
<div class="circly"></div>
<div class="text">
I am lots of text. I should always be verticly centered to the middle of the circle. I am lots of text. I should always be verticly centered to the middle of the circle.
</div>
</div>
<div class="wrap">
<div class="circly"></div>
<div class="text">
I am lots of text. I should always be verticly centered to the middle of the circle. I am lots of text. I should always be verticly centered to the middle of the circle. I am lots of text. I should always be verticly centered to the middle of the circle.
</div>
</div>
Pre-flex, dynamic vertical alignment was one of the major pain points of CSS, so without it (or JS), what you're asking verges on impossible. If JS is an option you can adjust the spacing dynamically (ES6 because it works in browsers shape-outline
does):
EDIT Update on the viability of common CSS vertical centering methods:
As stated in the MDN docs, shape-outside
, applies only to floated elements. This would seem to imply that the text must remain in flow with element you want to apply the shaping to. As far as I can tell, this limits you to only interacting with margin
and padding
properties, because of how positioning effects the text flow. Since the height is not fixed on your text block, you cannot use that value in calc
property. In short, your text container must be statically positioned and display: block
.
Text wrapping is calculated prior to position: relative
and transform
, so those are of no use.
Table cells treat all content of a cell as a single block (for centering), so the text is aligned to the top of the circle, which is vertically centered.
This would seem to eliminate every CSS-only vertical centering method as a candidate (that I'm aware of).
document.querySelectorAll('.text').forEach((text) => {
text.style.paddingTop = `${(200 - text.clientHeight)/2}px`;
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With