2

Each row of the tree is nested inside a div with flex display. The whole tree is inside a fixed width (200px) div - the one with the gray background.

I want all the blue buttons to only take up as much width as needed to fit the text. When text wraps into multiple lines, the divs stretch to fill up the whole row. Can it be prevented without setting a constant width to the div?

divs stretch unnecessarily in the tree row

https://jsfiddle.net/nLcgym5z/2/

<div class="filter-panel">
<div class="filter-tree">
    <div class="filter-category">
        <div class="filter-row-container">
            <div class="filter-row">
                <div class="tree-button-guide"></div>
                <div class="tree-button">-</div>
                <div class="filter-name selected">Karpaty</div>
            </div>
        </div>
        <div class="filter-branch">
            <div class="filter-category">
                <div class="filter-row-container">
                    <div class="filter-row">
                        <div class="tree-button-guide"></div>
                        <div class="tree-button">-</div>
                        <div class="filter-name selected">Karpaty Zachodnie</div>
                    </div>
                </div>
                <div class="filter-branch">
                    <div class="filter-category">
                        <div class="filter-row-container">
                            <div class="filter-row">
                                <div class="tree-button-guide"></div>
                                <div class="tree-button">-</div>
                                <div class="filter-name">Zewnętrzne Karpaty Zachodnie</div>
                            </div>
                        </div>
                        <div class="filter-branch">
                            <div class="filter-category">
                                <div class="filter-row-container">
                                    <div class="filter-row">
                                        <div class="tree-button-guide"></div>
                                        <div class="filter-name selected">Karpaty Austriacko-Morawskie</div>
                                    </div>
                                </div>
                                <div class="applied-filters"></div>
                            </div>
                            <div class="filter-category">
                                <div class="filter-row-container">
                                    <div class="filter-row">
                                        <div class="tree-button-guide"></div>
                                        <div class="filter-name selected">Karpaty Środkowomorawskie</div>
                                    </div>
                                </div>
                                <div class="applied-filters"></div>
                            </div>
                            <div class="filter-category">
                                <div class="filter-row-container">
                                    <div class="filter-row">
                                        <div class="tree-button-guide"></div>
                                        <div class="tree-button">+</div>
                                        <div class="filter-name selected">Beskidy Zachodnie</div>
                                    </div>
                                </div>
                                <div class="applied-filters"></div>
                            </div>
                            <div class="filter-category">
                                <div class="filter-row-container">
                                    <div class="filter-row">
                                        <div class="tree-button-guide"></div>
                                        <div class="filter-name">Beskidy Środkowe</div>
                                    </div>
                                </div>
                                <div class="applied-filters"></div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="filter-category">
                <div class="filter-row-container">
                    <div class="filter-row">
                        <div class="tree-button-guide"></div>
                        <div class="filter-name">Karpaty Wschodnie</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

CSS:

.filter-name {
    font-size: 0.85em;
    line-height: 1;
    padding: 3px;
    margin: 1px;
    cursor: pointer;
    user-select: none;
    align-self: flex-start;
    width: auto;
}
.filter-name:hover {
    color: royalblue;
}

/* selected filter names - collapsed or open view */
.filter-name.selected {
    background: royalblue;
    border-radius: 4px;
    color: white;
}
.filter-name.selected:hover {
    background: #5179f1;
}

/* blue selected filters buttons - collapsed branch view */
.applied-filters {
    display: flex;
    flex-wrap: wrap;
    margin-left: 10px;
}

/* Displays filter name, plus/minus button and button horizontal tree branch centered in a row */
.filter-row {
    display: flex;
    align-items: center;
}

.filter-branch {
    margin-left: 12px;
    position: relative;
}

/*Tree vertical branches display */
.filter-row,
.filter-category {
    position: relative;
}
.filter-category:not(:last-child)::before {
    z-index: 1;
    content: '';
    position: absolute;
    top: -15px;
    left: 0px;
    bottom: 10px;
    border-left: 1px solid royalblue;
}
.filter-category:last-child .filter-row-container .filter-row::before {
    z-index: 1;
    content: '';
    position: absolute;
    top: -15px;
    left: 0px;
    bottom: 50%;
    border-left: 1px solid royalblue;
}

/* Tree horizontal branches display */
.tree-button-guide {
    line-height: 0.6;
    height: 1px;
    width: 5px;
    margin-right: 2px;
    border-top: 1px solid royalblue;

    flex-shrink: 0;
}

/* Plus / minus tree buttons */
div.tree-button {
    z-index: 3;
    font-size: 0.8em;
    text-align: center;
    line-height: 10px;
    width: 10px;
    height: 10px;
    padding: 2px;
    margin: 2px;
    margin-left: -3px;
    background-color: royalblue;
    border-radius: 2px;
    color: white;
    cursor: pointer;

    flex-shrink: 0;
}



body {
    font-family: sans-serif;
    font-size: 90%;
    background-image:url("../img/bg.jpg");
    background-size: cover;
    background-attachment: fixed;
}

.filter-panel {
    width: 200px;
    background: lightgray;
}
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Adam Jagosz
  • 1,484
  • 14
  • 13
  • This is the problem you're having: http://stackoverflow.com/a/37413580/3597276 – Michael Benjamin Apr 21 '17 at 14:58
  • 1
    Thanks, you're right! I tried the JS solution, but is caused a bug on one div by changing its width to almost zero. And I'm using React.js for this project which makes me uncertain about how I should add old plain JS code messing with the DOM. Anyway, the containing div is only as narrow as 200px when I have the Chrome Console opened, so in normal conditions most children are short enought to fit in one line. – Adam Jagosz Apr 21 '17 at 16:26

2 Answers2

1

Add the following:

.filter-name.selected {
flex: 0;
}
Neil K
  • 1,318
  • 1
  • 14
  • 23
0

You can add a flex-basis of 0% to the selected items:

.filter-name.selected {
  flex-basis: 0%;
}

Unfortunately, this will force some items to line wrap before it is necessary.

The better answer might be to put the blue box inside the .filter-name element, as a new sub-element:

<div class="filter-name"><span class="selected-item">Beskidy Zachodnie</span></div>

Then apply the bg color, padding, and border radius to that element. You may also want to set it to display: inline-block.

keithjgrant
  • 12,421
  • 6
  • 54
  • 88
  • Actually, no... this will force line wrapping where it is not necessary. Hmm. – keithjgrant Apr 21 '17 at 15:01
  • This was worth a try, but the span doesn't have all its corners rounded, and in addition, the background on the span obscures the upper part of the second line. For what it's worth, display: inline-block causes the span to behave just like its parent: stretch all the way to the right. – Adam Jagosz Apr 21 '17 at 16:10