Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent the text going out of the container if it's over 90% width

I want to get the progress text to be inside the container progressish, even if the width is for an example 100%. As it is right now, the text is fixed to the right of the container, as seen in the first image below.

enter image description here

When the width of the progress bar is for an example 40%, it looks like this (as expected):

enter image description here

But when the progress is either 90% or 100%, I want the text to stuck to the far right of the progress bar, like this:

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 accomplish this? You can see the whole source code at jsFiddle: https://jsfiddle.net/a7buqqkk/.

like image 490
Airikr Avatar asked Aug 07 '17 13:08

Airikr


People also ask

How do I stop text from overflowing outside Div box?

To fix this problem, avoid using vw for your max-width and use a max-width of 100% instead. This will transfer the width of the parent container to the width of the child container.

What is the process that prevents text from overflowing the right margin?

The overflow-wrap CSS property applies to inline elements, setting whether the browser should insert line breaks within an otherwise unbreakable string to prevent text from overflowing its line box.


3 Answers

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

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

If you align the text to the right, it will appear after the bar, 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>
like image 86
Ori Drori Avatar answered Oct 17 '22 08:10

Ori Drori


In other answers,if change width on section element, code dont work well.but my answer ,not depend on 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> 
like image 30
Ehsan Avatar answered Oct 17 '22 08:10

Ehsan


You can use flexbox for #text > div and pseudoelement with needed width. Also add white-space: nowrap for text to not wrap. Replaced ids with classes 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>

Showing 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>
like image 1
Vadim Ovchinnikov Avatar answered Oct 17 '22 09:10

Vadim Ovchinnikov