1

I have a HTML structure with given CSS.
Both caption and progress elements should be rendered in same line. caption elements should not have fixed width and progress elements should fill up the rest of the space next to caption based on their inline-set width, which means that every progress element will have a different total pixel-width but should fill up only the given percentage of available space.
HTML structure and CSS rules can be changed in any way.

Is it possible to solve this problem with CSS only?

.table {
    padding: 15px;
    width: 280px;
    border: 1px solid black;
    font-family: sans-serif;
    font-size: 12px;
}

.caption {
    float: left;
}

.progress {
    height: 14px;
    border: 1px solid white;
    border-radius: 4px;
    background-color: green;
    overflow: hidden;
}

.value {
    margin-left: 5px;
}
<div class="table">
    <div class="row">
        <div class="caption">Short text: </div>
        <div class="progress" style="width:11.65%">
            <span class="value">11.65</span>
        </div>
    </div>
    
    <div class="row">
        <div class="caption">A bit longer text: </div>
        <div class="progress" style="width:100%">
            <span class="value">100.00</span>
        </div>
    </div>
    
    <div class="row">
        <div class="caption">X: </div>
        <div class="progress" style="width:45.50%">
            <span class="value">45.50</span>
        </div>
    </div>
</div>
Huangism
  • 16,278
  • 7
  • 48
  • 74
errata
  • 5,695
  • 10
  • 54
  • 99

3 Answers3

1

Have you considered using Flexbox?

Just add this rule:

.row {
    display: flex;
}

If your are concerned about browser support, an alternative would be using display:table. You should change your markup and CSS, like this:

.table {
        border: 1px solid black;
        font-family: sans-serif;
        font-size: 12px;
        padding: 15px;
        width: 280px;
    }
    .inner-table {
        display: table;
    }
    .row {
        display: table-row;
    }
    .caption {
        display: table-cell;
        white-space: nowrap;
        width: 1%;
    }
    .progress {
        background-color: green;
        border: 1px solid white;
        border-radius: 4px;
        display: table-cell;
        height: 14px;
    }
    .value {
        margin-left: 5px;
        display:block;
        width:0;
        overflow: visible;
    }
<div class="table">
        <div class="inner-table">
            <div class="row">
                <div class="caption">Short text: </div>
                <div style="width:1.65%" class="progress">
                    <span class="value">1.65</span>
                </div>
                <div class="remainder"></div>
            </div>
        </div>
        
        <div class="inner-table">
            <div class="row">
                <div class="caption">A bit longer text: </div>
                <div style="width:100%" class="progress">
                    <span class="value">100.00</span>
                </div>
                  <div class="remainder"></div>
            </div>
        </div>
        
        <div class="inner-table">
            <div class="row">
                <div class="caption">X: </div>
                <div class="progress" style="width:45.50%">
                    <span class="value">45.50</span>
                </div>
                <div class="remainder"></div>
            </div>
        </div>
    </div>
ncardeli
  • 3,452
  • 2
  • 22
  • 27
  • I see... Didn't know about flexbox, really... However it doesn't solve my problem. If I add only this rule, the second line gets a line break before the last word in `caption` for some reason. Although the browser support for flexbox is questionable (thinking about IE, as usual), I will definitely take a look at it! – errata Sep 17 '14 at 03:41
  • Thanks for the effort, but there is a small problem with this one also, that is, if `.value` text is wide enough, the `progress` width will not reflect the actual percentage. E.g. try replacing the first `progress` with 1.65% and enter the same value in `span.value` and you will notice that the `progress` bar won't reflect 1% width but it will stay wide as much as text width. – errata Sep 17 '14 at 14:18
  • @errata I improved the answer to let the text overflow. Tell me if this works for you. – ncardeli Sep 17 '14 at 17:02
0

Please try this - padding-right: 5px; display:inline; add these properties in progress class and also remove width in progress.

Zulu
  • 28
  • 7
  • I cannot remove the inline width because I need it to draw a specific width for each `progress` element. Each of them will be drawn with different widths eventually... – errata Sep 17 '14 at 12:34
0

Well, just for the future reference, I was playing a bit with the flexbox thingie and came up with this:

.table {
    padding: 15px;
    width: 280px;
    border: 1px solid black;
    font-family: sans-serif;
    font-size: 12px;
}

.row {
    display: flex;
}

.caption {
    margin: 1px 5px 1px 0;
}

.progress {
    flex-grow: 1;
   margin: auto;
}

.progress-content {
    height: 14px;
    border-radius: 4px;
    background-color: green;
}

.value {
    margin-left: 5px;
}
<div class="table">
    <div class="row">
        <div class="caption">Short text:</div>
        <div class="progress">
            <div class="progress-content" style="width:11.65%">
                <span class="value">11.65</span>
            </div>
        </div>
    </div>
    
    <div class="row">
        <div class="caption">A bit longer text:</div>
        <div class="progress">
            <div class="progress-content" style="width:100%">
                <span class="value">100.00</span>
            </div>
        </div>
    </div>
    
    <div class="row">
        <div class="caption">X:</div>
        <div class="progress">
            <div class="progress-content" style="width:45.50%">
                <span class="value">45.50</span>
            </div>
        </div>
    </div>
</div>

If I get a solution without flexbox, will accept it as an answer :)

errata
  • 5,695
  • 10
  • 54
  • 99