74

I want text inside my div to remain same size in % percentage ratio to a parent div. I.E. I want my text to have font-size of 50% of parents div width. So when page size is changing, text always remains the same size in %.

Here Is what I'm talking about:

.counter-holder{	display: block;	position: absolute;	width:90%;	height:20%;	top: 70%;	left: 50%;	/* bring your own prefixes */	transform: translate(-50%, -50%); } .counter-element-box{	position:relative;	vertical-align: text-top;	border-style: solid; border-width: 1px; width: 20%; height: 100%; float:left; margin: 6%; } .counter-element-text{	position:absolute;	top:50%;	width: 50%;	max-width:50%;	display: inline-block;	height:100%;	margin-left:50%;	font-size : 80%;overflow: hidden; } .counter-element-value{	position:absolute;	top:50%;	width: 50%;	max-width:50%;	display: inline-block;	height:100%;	padding-left:30%;	font-size : 80%;overflow: hidden; }
<div class="counter-holder">	<div class="counter-element-box">	<div id="years" class="counter-element-value">	0	</div>	<div class="counter-text counter-element-text" > Years	</div>	</div>	<div class="counter-element-box">	<div id="missions" class="counter-element-value">	0	</div>	<div class="counter-text counter-element-text" > Missions	</div>	</div>	<div class="counter-element-box"> <div id="team" class="counter-element-value"> 0 </div> <div class="counter-text counter-element-text" >	Team </div>	</div> </div>

Run this snippet in full screen and try resizing the page and see how text size is changing and not fitting inside the div borders. How can I prevent it from happening, so it always remains inside the borders?

3
  • Are you sure you want ta change the font-sizeand not the width? Commented Jun 7, 2015 at 13:17
  • I did both, it doesn't help. As well as leaving one of the options. Text is still being resized. Commented Jun 7, 2015 at 13:19
  • There is a similar question with a variety of good answers at stackoverflow.com/q/10292001/2615878. Commented Feb 14, 2018 at 16:03

9 Answers 9

58

You can use container query units: cqw, cqh, cqi, cqb, cqmin, cqmax. They are supported by all modern browsers.

This will allow to adjust font-size and other properties not only to the direct parent, but to any ancestor defined as a container, as well as target not only horizontal but also vertical size of the container if necessary.

.container { /* Define a container */ /* Use `inline-size` instead of `size` if you are only interested in inline size, which is horizontal for Latin and many other layouts. */ container-type: size; /* Other styles */ height: 3em; border: solid 2px; overflow: hidden; } .horizontal { resize: horizontal; } .vertical { resize: vertical; } .both { resize: both; } .horizontal .child { font-size: 10cqw; } .vertical .child { font-size: 30cqh; } .both .child { font-size: 30cqmin; }
<div class="container horizontal"> <div class="child">Resize me horizontally!</div> </div> <div class="container vertical"> <div class="child">Resize<br>me<br>vertically!</div> </div> <div class="container both"> <div class="child">Resize me<br>in all<br>ways!</div> </div>

Sign up to request clarification or add additional context in comments.

3 Comments

This is a God-send and should be the accepted answer! Every major browser supports it, minus IE, and it makes my components look so good without the need of an additional JavaScript framework like big-text.js
This is almost what I'm looking for, but I can't get it to actually decrease the font size depending on the amount of text and the size of the parent container. For instance, if you add a lot of characters but no spaces to the container horizontal div, it will overflow and fail to resize the text to fit in the box.
Did you find the fix?
29

The way I solved this problem was to use javascript to measure the container and then set the font size in px on that container. Once that baseline is set for the container then the relative font sizing of all the content will scale correctly using em or %.

I'm using React:

<div style={{ fontSize: width / 12 }} > ... </div> 

CSS:

div { font-size: 2em; } 

4 Comments

I am using Angular and this helped me
Can you add the JS you used to get the width?
you can use window.screen to get the current screen details and use whatever width you prefer.
Where did 12 come from?
13

There's no way to achieve what this question is asking for in CSS. A font size can only be set in a certain number of ways, and any setting that is a percentage value is relative to the size of the font, not a width or height of a block.

So, while this doesn't offer a solution to your problem, it is an answer to the question of whether this can be done in CSS: it can't.

There are a lot of answers here which appear to answer the wrong question, and recommend the use of the vw unit, which is relative to the viewport and not the parent element's size. There are also some which resort to Javascript, which is doable if you don't mind that sort of thing. Then there is slaviboy's answer which advocates the use of CSS user variables which is a creative solution that I admire, even though it can't achieve the end effect asked for by the OP.

In many cases, when you want to set font size relative to the parent element's width, you have enough information to be able to do this with some math: work out how the parent element's width is calculated, and see if you can re-use a calculation like that in your font size setting.

For example, if parent element's width is the viewport width or a known percentage of it, then the answers based on vw will work, you just have to do the math to work out the right ratio. If parent element's width is some absolute value such as 500px, then that's even easier. Only if the parent element's width is completely unpredictable will this be difficult, though presumably the OP's situation is exactly that. For example, if the parent element's width is based on content, and content may be user-submitted or its size is otherwise not predictable.

Comments

6

If you talk about responsive scaling, then you can implement it, but all depends on what you are trying to achieve. In the code below i have created a div container with ratio (height/width = 1/2). When you change the size of the browser window, container and text will scale responsively.Depending on the window size it will change the font according to VW(viewport width) and VH(viewport height). To add new font size you have to set it twice once according to the -vw and second time according to -vh. I have used CSS variables(var), that way its easier to understand the code.

Example

body { background-color: #000; padding: 0; margin:0; } /* position element in the middle */ .middle { position: absolute; top:50%; left: 50%; transform: translate(-50%, -50%); } /* Ratio: height/width */ :root { --ratio: 0.5; --reverse-ratio: 2; --container-width: 50vw; --container-height: 50vh; --font1-sizeVW: 15vh; --font1-sizeVH: calc(var(--ratio) * 15vw); --font2-sizeVW: 6vh; --font2-sizeVH: calc(var(--ratio) * 6vw); } #container { background-color: pink; width: var(--container-width); height: calc(var(--ratio) * var(--container-width)); max-width: calc(var(--reverse-ratio) * var(--container-height)); max-height: var(--container-height); } #span1 { font-size: var(--font1-sizeVW); } #span2 { font-size: var(--font2-sizeVW); } /* max-width: (reversRatio * 100vh) */ @media all and (max-width: 200vh) { #container { background-color: green; } #span1 { font-size: var(--font1-sizeVH); } #span2 { font-size: var(--font2-sizeVH); } }
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <style> </style> </head> <body> <div id="container" class="middle"> <span id="span1">Hello</span> <span id="span2">Hello again</span> </div> </body> </html>

4 Comments

That is relative to the viewport, not the parent element.
Make sure you make your parent size relative to the viewport too. That way you can set ratio between the child and parent elements, and when page size changes both elements keep there ratio and scale responsively.
@slaviboy I feel that your above example might be the solution to my problem, but unfortunately I am missing something. I have an svg that scales on window resize, and some divs that don't. I want them to scale all together and keep their relative positions. I tried setting the top property like this top: calc(var(--container-height) * 5%); with no success. Is there a way to acheive this? Also can you explain, what is the purpose of the transform property on the middle class? Here is a blitz of what I am trying to do.. <stackblitz.com/edit/lock-resizing-divs-wsemvn>
The way I see it is by calculation indeed. In my case, I use React, and it's easier, but the CSS variables provide the native way to do it. Nice answer!
1

I don't know if that's helpful or not. It's maybe just crap. The idea is to manually take the width of the element and to calculate the font-size from it. I used some JavaScript because I don't know if maths are possible with CSS variables. Code in comment works but is not dynamic.

const resize_ob = new ResizeObserver(function(entries) { let rect = entries[0].contentRect; let currWidth = rect.width; let fontSize = rect.width / 10; /* let testDiv = document.querySelector("#test_div"); let testDivStyle = getComputedStyle(testDiv); let testDivRawWidth = testDivStyle.getPropertyValue('width') let fontSize = parseInt(testDivRawWidth .substring(0, testDivRawWidth .length - 2)) / 10; */ testDiv.style.setProperty('--fontSize', fontSize+"px"); })
div { background-color: lightblue; height: 75vh; width: 75vh; font-size: var(--fontSize, 15vh); }
<div id="test_div"> testing just a thing... </div>

Comments

-2

A simpler and pure CSS solution would be to set the parent Div's width in vw.

Then, use the calc() css function to multiply the parent width in vw by .5 (50%) to achieve the desired result.

body { background-color: #F9F1F0; height:100vh; width:100vw; } .parent-div { background-color: #FF7F50; height:100vh; width:50vw; /* The key here is selecting vw, as it is a relative measurement */ text-align: center; } .child-h1 { font-size: calc(50vw * .5); /* We can then use the relative measurement here and calculate 50% of the div's width and translate that to font size */ }
<!DOCTYPE html> <html lang="en"> <head></head> <body> <div class="parent-div"> <h1 class="child-h1">50</h1> </div> </body> </html>

Comments

-3

I found this to work pretty well, and it has the advantage of simplicity:

font-size: min(3vh,1.7vw); 

just tweak the proportions according to your font.

This works because it takes the shorter side of your viewport as the limiting factor in sizing your font. You can also set this on a parent div and then reference it with em units in its children.

like so

.parent{ font-size: min(3vh,1.7vw); } .child { font-size: 2.2em; }
<div class="parent"> <div class="child"> <p>Hello there</p> </div> </div>

2 Comments

Instead of taking a min(), you can use the vmin (viewport min) unit, which is another unit like vw and vh but is based on the shorter of the width and height of the viewport.
My guess is because the question is asking for something different - OP wants to have a text string, and size the text relative to the parent element's width. While you can use vw to size the text according to the viewpoint width, you can't do it according to the parent element width. So I don't think what OP wants is possible without modifying their approach, as most answers are suggesting. But I think they're downvoted because they don't provide exactly what OP wanted.
-8

Responsive Font Size/ Text responsive according to the browser window :-

The text size can be set with a vw unit, which means the "viewport width".

That way the text size will follow the size of the browser window:

For Example

<div> <h2 style="font-size:10vw;">Ganesh Pandey</h2> </div> 

Resize the browser window to see how the text size scales.

1 Comment

That is relative to the viewport, not the parent element.
-18

Using font-size: x% is not relative to the width of the parent but the font-size the element would normally have.

So if your element's parent sets font-size: 12px then font-size: 50% in element means that element has a font-size of 6px

What you want to use is viewport percentage: vw

for example: font-size: 2vw

.counter-holder{	display: block;	position: absolute;	width:90%;	height:20%;	top: 70%;	left: 50%;	/* bring your own prefixes */	transform: translate(-50%, -50%); } .counter-element-box{	position:relative;	vertical-align: text-top;	border-style: solid; border-width: 1px; width: 20%; height: 100%; float:left; margin: 6%; } .counter-element-text{	position:absolute;	top:50%;	display: inline-block;	margin-left:40%;	font-size : 2vw;overflow: hidden; } .counter-element-value{	position:absolute;	top:50%;	width: 50%;	max-width:50%;	display: inline-block;	height:100%;	padding-left:30%;	font-size : 2vw;overflow: hidden; }
<div class="counter-holder">	<div class="counter-element-box">	<div id="years" class="counter-element-value">	0	</div>	<div class="counter-text counter-element-text" >	Years	</div>	</div>	<div class="counter-element-box">	<div id="missions" class="counter-element-value">	0	</div>	<div class="counter-text counter-element-text" >	Missions	</div>	</div> <div class="counter-element-box">	<div id="team" class="counter-element-value">	0	</div>	<div class="counter-text counter-element-text" >	Team	</div>	</div> </div>

5 Comments

Great explanation, never heard of vw before.
Isn't vw and vh the size of the viewport window, not it's parent?
Indeed, this answer should not have been marked as valid! I'm guessing you would need some javascript to size text relative to a parent, but viewport units are definitely not the way to achieve this.
Absolutely agree - I can't imagine a real example when it's necessary to have text size relative to the size of a browser viewport. It's much more common to have a situation when text size should be relative to a size of a parent block. And one of the solutions is to use JavaScript similar to github.com/davatron5000/FitText.js
I have a perfectly good use case for this - I have an element that can be configurable by an admin for display on an ordinary user's page. For the user, this element is the width of the screen, scaling using vw and vh works great. I would like the admin to have a smaller preview of this which may be some variable proportion of the width of the page, for example 6 bootstrap columns, switching responsively to full width at the medium breakpoint. Scaling to a percentage of the enclosing box's width would be ideal here.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.