Using the following HTML and CSS3 rules, I'm trying to make sure that the following criteria are adhered to:
I have all of the criteria working except for item 1 where the children are exceeding their parent's width. Question: How to keep children within their parent?
- li items cannot exceed their parent width i.e. 400px
- img, label, and currency content must be centred vertically within their span
- currency should not wrap and should always be displayed in full
- currency should always be displayed as close as possible to the label span.
- the label text should be clamped at 2 lines with ellipsis displayed where it exceeds 2 lines.
Note: Only needs to work in Chrome and Safari webkit-based browsers.
It should look like:
However, it looks like this at the moment:
Any ideas?
********************* JS Fiddle example ************************
<ul>
<li>
<span class="img"></span>
<span class="label">Acclaim</span>
<span class="currency">(USD 50)</span>
</li>
<li>
<span class="img"></span>
<span class="label">Acclaim 1 11 111 1111 11111</span>
<span class="currency">(USD 50)</span>
</li>
<li>
<span class="img"></span>
<span class="label">Acclaim 1 11 111 1111 11111 2 22222 2222 22222 3 33 333 3333 33333 4 44 444 4444 44444 5 55 555 5555 55555 6 66 666 6666 66666</span>
<span class="currency">(USD 50)</span>
</li>
</ul>
ul {
width: 400px;
background-color: yellow;
padding: 0;
margin: 0;
}
li {
display: -webkit-box;
padding-right: 50px;
}
.label {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-pack: center;
-webkit-line-clamp: 2;
text-overflow: ellipsis;
overflow: hidden;
white-space: normal;
word-wrap: break-word;
line-height: 1.3em;
margin-right: 0.2em;
background-color: pink;
}
.currency {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-pack: center;
white-space: nowrap;
background-color: lightgreen;
}
.img {
display: block;
width: 40px;
height: 40px;
margin-right: 0.1em;
background-image:url('data:image/png;base64,iVBOR...);
}
The following will work, providing the price doesn't get wider:
http://jsfiddle.net/WDjZ3/4/
I simply converted the margin-right to pixels so I knew the space taken up by the content other than the label, then added a max-width for the remainder:
if the price or image are variable width, you will need js to read their widths, remove from 400px and add that value to max-width.
Here is an example using JavaScript to dynamically set the max-width: http://jsfiddle.net/WDjZ3/7/
I haven't checked all dimensions, so that should be added to make it fully accurate, otherwise the margins will make the price no longer fit.
I basically checked the width of the other elements:
I then removed this width from 400px, and set the maxWidth:
I’ve solved this to work without JavaScript. However, it only works in more modern browsers, including Chrome and Opera. It will not work in Safari. It will work in Firefox once it updates to the latest spec. I can probably get it to work in IE10, but I have to look into that more. The ellipsis only works in Chrome/Safari as it is vendor specific.
The demo is at http://jsfiddle.net/uLm92/1/
First of all we want to make the li as a flexbox container and set it to 400px, so the flex items will try to fit that size (more on that later):
Now the child items are flex items, the key to getting the label to fit is setting the image and the price to not flex. For the price, we know it wants to always be 40xp wide, so I set the following:
This says that the preferred with id 40px and never make it smaller.
Then we want to also tell the price to never shrink, and to also centre the anonymous box (the content):
Lastly, we want to also center the label text. As you need the ellipsis hack, I've used the old Flexbox syntax for WebKit. Without using old flexbox, the line-clamp property does not work:
.label {
}
As the other two items will never shrink, the .label element is the only one that can, so it reduces in size if there is no space left.