Prevent text from outputting from the container if it exceeds 90% of the width

I want the progress text to be inside the progressish container, even if the width is 100%. As of now, the text is pinned to the right of the container, as shown in the first image below.

enter image description here

When the progress bar is 40% wide, it looks like this (as expected):

enter image description here

But when the progress is 90% or 100%, I want the text to get stuck in the far right corner of the progress bar, for example:

enter image description here enter image description here

 section#progressish { width: 300px; } div#text {} div#text>div { margin-bottom: 5px; margin-left: 100%; min-width: 100px; width: auto !important; width: 100px; } div#progressbar { background-color: #d1d1d1; height: 10px; margin-bottom: 15px; width: 100%; } div#progressbar>.progress[data="bar"] { background-color: #111111; height: 10px; margin-bottom: 15px; width: 100%; } 
 <section id="progressish"> <div id="text"> <div>100% avklarat</div> </div> <div id="progressbar"> <div class="progress" data="bar"></div> </div> </section> 

How can i do this? You can see all the source code in jsFiddle: https://jsfiddle.net/a7buqqkk/ .

+8
html css progress-bar
source share
4 answers

If the width of the scroll bar is fixed (300 pixels) and the width of the text (text, not the element) is more or less fixed (about 85 pixels - from 1% to 100%), set the text as an absolutely positioned child of the .progress element and set it width and max-width :

 width: calc(100% + 100px); max-width: 300px; 

If you align the text to the right, it will appear after the line until max-width is reached.

 /** js to demonstrate changing values **/ var progressBar = document.querySelector('.progress'); function progress() { var minmax = [0, 100]; var step = 1; const iterate = (current) => { progressBar.style.width = `${current}%`; progressBar.setAttribute('data-percentage', current); if(current !== minmax[1]) { setTimeout(() => iterate(current + step), 40); } else { minmax = minmax.reverse(); step = -step; setTimeout(() => iterate(minmax[0]), 500); } } iterate(minmax[0]); } progress(); 
 section#progressish { padding: 20px; width: 300px; } div#progressbar { background-color: #d1d1d1; height: 10px; margin-bottom: 15px; width: 100%; } div#progressbar>.progress[data="bar"] { position: relative; background-color: #111111; height: 10px; margin-bottom: 15px; width: 0%; } .progress::before { position: absolute; top: -20px; width: calc(100% + 85px); max-width: 300px; text-align: right; white-space: nowrap; content: attr(data-percentage)"% avklarat"; } 
 <section id="progressish"> <div id="progressbar"> <div class="progress" data="bar" data-percentage></div> </div> </section> 
+5
source share

You can use flexbox for #text > div and a pseudo-element with the desired width . Also add white-space: nowrap for text that cannot be wrapped. Replace id with class es to show multiple progressbar values.

Demo:

 section.progressish { width: 300px; } div.text > div { margin-bottom: 5px; max-width: 100%; min-width: 100px; width: auto !important; width: 100px; display: flex; white-space: nowrap; } div.text > div:before { content: ""; width: 100%; } div.progressbar { background-color: #d1d1d1; height: 10px; margin-bottom: 15px; width: 100%; } div.progressbar > .progress[data="bar"] { background-color: #111111; height: 10px; margin-bottom: 15px; width: 100%; } .progressish:nth-child(1) .text > div:before, .progressish:nth-child(1) .progress[data="bar"] { width: 20%; } .progressish:nth-child(2) .text > div:before, .progressish:nth-child(2) .progress[data="bar"] { width: 40%; } .progressish:nth-child(3) .text > div:before, .progressish:nth-child(3) .progress[data="bar"] { width: 60%; } .progressish:nth-child(3) .text > div:before, .progressish:nth-child(3) .progress[data="bar"] { width: 80%; } 
 <section class="progressish"> <div class="text"> <div>20% avklarat</div> </div> <div class="progressbar"> <div class="progress" data="bar"></div> </div> </section> <section class="progressish"> <div class="text"> <div>40% avklarat</div> </div> <div class="progressbar"> <div class="progress" data="bar"></div> </div> </section> <section class="progressish"> <div class="text"> <div>60% avklarat</div> </div> <div class="progressbar"> <div class="progress" data="bar"></div> </div> </section> <section class="progressish"> <div class="text"> <div>80% avklarat</div> </div> <div class="progressbar"> <div class="progress" data="bar"></div> </div> </section> <section class="progressish"> <div class="text"> <div>100% avklarat</div> </div> <div class="progressbar"> <div class="progress" data="bar"></div> </div> </section> 

Display with animation:

 section.progressish { width: 300px; } div.text > div { margin-bottom: 5px; max-width: 100%; min-width: 100px; width: auto !important; width: 100px; display: flex; white-space: nowrap; } div.text > div:before { content: ""; width: 0%; } div.progressbar { background-color: #d1d1d1; height: 10px; margin-bottom: 15px; width: 100%; } div.progressbar > .progress[data="bar"] { background-color: #111111; height: 10px; margin-bottom: 15px; width: 0%; } div.progressbar > .progress[data="bar"], div.text > div:before { animation: 4s linear 0s infinite alternate progress; } @keyframes progress { from { width: 0 } to { width: 100%; } } 
 <section class="progressish"> <div class="text"> <div>100% avklarat</div> </div> <div class="progressbar"> <div class="progress" data="bar"></div> </div> </section> 
+1
source share

In other answers, if you change the width to a section element, the code doesn't work well. But my answer does not depend on the width of section .

A) rectangle:

 $(document).ready(function(){ var per; var ft = false; var totalWid = $('section').width(); var spanWid = $('.txt').width(); var bor = Math.floor(((totalWid - spanWid)/totalWid)*100) - 2; setInterval(function(){ per = Math.round($('.progChild').width()/totalWid*100); $('.txt').html(per + '% Progress'); if(per > bor && !ft){ $('.txt').addClass('rig').removeClass('arrow'); ft = !ft; } else if(per <= bor && ft){ $('.txt').addClass('arrow').removeClass('rig'); ft = !ft; } },100); }) 
 section { width: 300px; margin-top: 100px; } .progParent { width: inherit; background-color:#000; padding: 1px; position: relative; } .progChild { height: 10px; background-color: red; animation:mov 5s linear infinite alternate; width: 0%; float: left; } .progParent:after { clear: both; content: ''; display: block; } .txt { position: absolute; top: -30px; white-space: nowrap; background-color: #000; color: #FFF; border: 1px solid #FFF; margin-left: -5px; padding:0 2px; font-weight: bold; } .arrow:before { content: ''; width: 0; height: 0; border:5px solid; border-color: #000 transparent transparent transparent; bottom: -10px; left: 0; position: absolute; } .rig { right: 0; } @keyframes mov { from {width: 0} to {width: 100%;background-color: green} } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <section> <div class="progParent"> <div class="progChild"></div> <span class="txt arrow">0% Progress</span> </div> </section> 

B) circle:

 $(document).ready(function(){ var per; var ft = false; var totalWid = $('section').width(); var spanWid = $('.txt').width(); var bor = Math.floor(((totalWid - spanWid)/totalWid)*100); setInterval(function(){ per = Math.round($('.progChild').width()/totalWid*100); $('.txt').html(per + '%'); if(per > bor && !ft){ $('.txt').addClass('rig').removeClass('arrow'); ft = !ft; } else if(per <= bor && ft){ $('.txt').addClass('arrow').removeClass('rig'); ft = !ft; } },100); }) 
 section { width: 400px; margin: 100px 0 0 50px; } .progParent { width: inherit; background-color:#000; padding: 1px; position: relative; } .progChild { height: 10px; background-color: red; animation:mov 5s linear infinite alternate; width: 0%; float: left; } .progParent:after { clear: both; content: ''; display: block; } .txt { position: absolute; top: -60px; white-space: nowrap; background-color: #000; color: orange; border: 1px solid #FFF; margin-left: -25px; padding:0; font-weight: bold; width: 50px; height: 50px; border-radius: 100%; line-height: 50px; text-align: center; } .arrow:before { content: ''; width: 0; height: 0; border:5px solid; border-color: #000 transparent transparent transparent; bottom: -9px; left: 20px; position: absolute; } .rig { right: 0; } @keyframes mov { from {width: 0} to {width: 100%;background-color: green} } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <section> <div class="progParent"> <div class="progChild"></div> <span class="txt arrow">0%</span> </div> </section> 
+1
source share

Just give the container for the text the max-width property, for me it works with 69%, but you can also specify in px. check my code: https://codepen.io/Juanito/pen/LjxKBa

  <section id="progressish"> <div id="text"> <div>100% avklarat</div> </div> <div id="progressbar"> <div class="progress" data="bar"></div> </div> </section> section#progressish { width: 300px; } div#text {max-width:69%} div#text>div { margin-bottom: 5px; margin-left: 100%; min-width: 100px; width: auto !important; width: 100px; } div#progressbar { background-color: #d1d1d1; height: 10px; margin-bottom: 15px; width: 100%; } div#progressbar>.progress[data="bar"] { background-color: #111111; height: 10px; margin-bottom: 15px; width: 60%; } 
0
source share

All Articles