Css for an element that allows break-word on child divs, but that can also expand to take the width of its children
I'm trying to determine whether it's possible to create css for an element that supports word-wrap:break-word
, but that also expands to take the width of its children when breaking is not possible.
<html>
<style>
.outer {
background-color:red;
word-wrap:break-word;
}
</style>
<div class="outer">
User generated content:
<a href="http://www.google.com">http://anannoyinglylongurlth开发者_C百科atcausesthepagetogrowtolongunlessIusewordwrapbreakwordasdfasfasdfasdfasdfasdfasdfsadfasdfadsf</a>
<table>
<tr>
<td>asdfasdfadsffdsasdfasdfsadfafsd</td>
<td>asdfasdfadsffdaasdfassdffaafasds</td>
</tr>
</table>
<img src="http://www.google.com/intl/en_com/images/srpr/logo3w.png"/>
</div>
</html>
In the above sample, the url breaks properly, but the table and img overflow the red outer div if the window becomes narraower than the table.
If I make the outer div display:inline-block or display:table, the red outer div correctly expands to include the content, but the url doesn't break if the window is narrower than the url.
I only need this to work in WebKit (on Android), and I'm trying to find a CSS only (no Javascript) solution if possible.
If I understood what you need correctly, all you need is overflow: auto
set on .outer
. Here's an example: http://jsfiddle.net/hgLbh/1/ (tested on safari & chrome).
Update:
After your scrolling related comment I've tried a few other solutions and I've found something that satisfies even that. I'll say in advance it's dirty, but if you can handle absolutely positioned content and you are willing to duplicate the generated markup I hope it will work (at least on my local safari it does).
The solution is to duplicate your content and wrap the new content in 2 other divs, so the HTML will look something like:
<div class="outer-fixed">
<div class="just-a-helper-wrapper">
... user generated content
</div>
</div>
<div class="outer">
... same user generated content
</div>
And for the CSS:
.outer,
.outer-fixed {
background-color:red;
word-wrap:break-word;
position: absolute;
left: 0;
right: 0;
}
.outer-fixed {
position: fixed;
right: 0;
}
.outer-fixed * {
visibility: hidden;
}
I'd like to point out that the just-a-helper-wrapper
is required only because outer-fixed *
doesn't select text nodes (ie. content that's not in another tag) - for example the string User generated content:
from your example would have still been visible. If you don't actually have that kind of content, you can remove it.
Here's the link: http://jsfiddle.net/hgLbh/2/
Assigning width: 100%;
and using table-layout: fixed;
forces the td cells to fit the table and will allow for text wrapping.
table {
width:100%;
table-layout:fixed
}
I don't know about mobile webkit but this worked in Chrome
http://jsfiddle.net/HerrSerker/duDTz/1/
.outer {
background-color:red;
word-wrap:break-word;
overflow:hidden;
}
.outer table {
width: 100%;
table-layout:fixed
}
.outer * {
max-width: 100%;
}
It seems to me that draevor has the answer, but I suspect that you don't want a scroll bar showing up in the middle of the screen on the div
. If that is so, and depending on your limitations, you might try this to make the div
the window:
CSS
html {height: 100%}
body {overflow: auto; height: 100%; margin: 0;}
.outer {
word-wrap: break-word;
background-color: red;
overflow: auto;
min-height: 100%;
}
Looking at the CSS spec, it's likely that what I'm trying to do is impossible, although I find the size calculations fairly difficult to decipher. Here are some important bits:
http://www.w3.org/TR/CSS21/visudet.html
The content width of a non-replaced inline element's boxes is that of the rendered content within them
So if I want the background of my containing box to grow to be the width of the children, it appears I need to make sure it's layout is calulated in an inline formatting context:
http://www.w3.org/TR/CSS21/visuren.html#normal-flow
When an inline box exceeds the width of a line box, it is split into several boxes and these boxes are distributed across several line boxes. If an inline box cannot be split (e.g., if the inline box contains a single character, or language specific word breaking rules disallow a break within the inline box, or if the inline box is affected by a white-space value of nowrap or pre), then the inline box overflows the line box.
Great. Hopefully the breaking rules also include emergency wrapping possibilities.
http://www.w3.org/TR/2010/WD-css3-text-20101005/#word-wrap
This property specifies whether the UA may break within a word to prevent overflow when an otherwise-unbreakable string is too long to fit within the line box.
Doesn't really help; let's look at the newer draft spec:
http://www.w3.org/TR/css3-text/#overflow-wrap
Break opportunities not part of ‘overflow-wrap: normal’ line breaking are not considered when calculating ‘min-content’ intrinsic sizes.
This isn't very clear, but if 'min-content' instrinsic sizes has something to do with the same calculations used to determine line-breaking possibilities, I might be out of luck.
I ended up just using Javascript to measure the content and decide whether to show it in block or inline context. Sigh.
var messages = document.body.getElementsByClassName('mail_uncollapsed');
// Show overflowing content by setting element display to inline-block. This
// prevents break-word from being applied to the element, so we only do this
// if the element would overflow anyway.
for (var i = 0; i < messages.length; ++i) {
var message = messages[i];
message.style.display = 'block';
var isOverflowing = message.clientWidth < message.scrollWidth;
if (isOverflowing) {
message.style.display = 'inline-block';
}
}
精彩评论