Why word-break doesn't work here? - css

http://codepen.io/rick-li/pen/oshCb
<div class="wrapper">
<div class="left"></div>
<span>lfjaslkjasldjfaljdfaldflasjflasjdfldasfsdafafasdfsdafadsfazxcvzvzxv</span>
</div>
.wrapper{
width: 400px;
height: 300px;
border: solid 1px;
}
.wrapper .left{
float: left;
width: 200px;
height: 200px;
border: solid 1px;
background-color: #111111
}
.wrapper span{
word-wrap: break-word;
}
you will notice the text dropped to the bottom,
if there're spaces exist in the text, it will wrap correct and lies on the wright, so I wonder why the word-wrap: break-word or word-wrap: break-all doesn't work?

You could also use, word-wrap: break-word;
.wrapper .right{
display: block;
width:200px;
}
.wrapper .right{
word-wrap:break-word;
}

.right should not be inline. Also, assign some width to it.
.wrapper .right{
display: block;
width: 200px;
}
.wrapper .right{
word-break: break-all;
}
DEMO here.

NoobEditor in reference to your answer did you mean to say "word-wrap only works when there are no spaces rather than when there are spaces in the word? The reason why word-wrap is not working in the code above is due to wrong placement of closing div.
<div class="wrapper">
<div class="left"></div> <!-- here is your problem -->
<span>lfjaslkjasldjfaljdfaldflasjflasjdfldasfsdafafasdfsdafadsfazxcvzvzxv</span>
</div>
If you close div tag in the right place, word-wrap will work:
<div class="wrapper">
<div class="left">
<span>lfjaslkjasldjfaljdfaldflasjflasjdfldasfsdafafasdfsdafadsfazxcvzvzxv</span>
</div> <!-- close statement here -->
</div> <!-- close statement here -->
See it here

You can do this a couple of ways, you can change the display from inline so that you can set a max-width, allowing it to know when it should break the word:
http://codepen.io/anon/pen/ibvKq
.wrapper .right{
display: inline-block;
max-width: 290px;
word-wrap: break-word;
}
Alternatively, if you want to keep the inline, you need to couple the word-wrap: break-word; with white-space: pre; but this does mean it will preserve line-breaks and spaces. Personally, I'd use the first one over this one.
http://codepen.io/anon/pen/cfhwI
.wrapper .right{
display: inline;
white-space: pre;
word-wrap: break-word;
}

Related

Break text by word, break anyways if no space

I am trying to break a text by word if possible, and if not - break anyways so the layout isn't dying. This works by default in google chrome and wraps properly, but it doesn't work in firefox.
.a {
width: 200px;
word-wrap: break-word;
display: inline-block;
white-space: normal;
word-break: break-word;
}
.a>div {
text-align: left;
display: inline-block;
}
<div class="a">
<div>
achrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachri
</div>
</div>
http://jsfiddle.net/prswjktc/12/
The problem can be solved by adding max-width: 100%; in the case in the fiddle but I am looking for alternative solutions. (I can't remove the inner div either).
Here we go :-)
Put your words (or terms) into <span>s.
set to
display: inline-block (so they get all the width they need)
max-width: 100%; overflow: hidden (so, yes, there's a chop-off, if column exceed)
overflow-wrap: break-word (so he breaks if there's a chop-off
legacy backup (think -moz-whatever): word-wrap: break-word
code:
span
display: inline-block
max-width: 100%
overflow-wrap: break-word
word-wrap: break-word
full Codepen
You can use the CSS3 property overflow-wrap, which may be what you're looking for. Read more at MDN, including about browser support, but the gist is that "In contrast to word-break, overflow-wrap will only create a break if an entire word cannot be placed on its own line without overflowing."
Note also that the width of 200px you have is not on the div that contains the long text but on the .a parent div, and that the div with the long text has display: inline-block, so currently its width will be determined by its content and it will spill out of the fixed-width .a parent div. To fix this, either give the inner div (.a > div) an explicit width (could be 200px, or 100%, or whatever your layout actually requires), or make the inner div display as a block by removing display: inline-block and/or setting display: block explicitly.
Here's a working snippet, in which I've left .a > div as an inline-block, and created another div .b where .b > div is a block:
.a {
width: 200px;
word-wrap: break-word;
display: inline-block;
white-space: normal;
word-break: break-word;
}
.a>div {
text-align: left;
width: 100%;
display: inline-block;
overflow-wrap: break-word;
}
.b {
width: 200px;
display: inline-block;
white-space: normal;
}
.b>div {
text-align: left;
display: block;
overflow-wrap: break-word;
}
<div class="a">
<div>
achrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachri
</div>
</div>
<div class="b">
<div>
achrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachri
</div>
</div>
Add word-break:break-all; to the child selector (.a > div)
https://jsfiddle.net/f4bdx7z9/1/
.a {
width: 200px;
word-wrap: break-word;
display:inline-block;
white-space:normal;
word-break:break-word;
}
.a > div {
text-align:left;
display:inline-block;
word-break:break-all;
}
<div class="a">
<div>
achrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachriachrichteinenachrichteinenachrichtchrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachrichteinenachri
</div>
</div>

in chrome, word-wrap: break-word breaks words even if there is no space

The following markup and CSS causes weird behaviour in Chrome:
#parent {
background: yellow;
height: 120px;
margin-bottom: 20px;
width: 100px;
word-wrap: break-word;
}
#box {
background: red;
float: left;
height: 100px;
width: 100%;
}
<div id="parent">
<div id="box"></div>
<div>OIL</div>
</div>
<div id="parent">
<div id="box"></div>
<div>OWL</div>
</div>
Fiddle: https://jsfiddle.net/7sq3ybxr/
The upper example (containing the word OIL), causes word breaks even though there is literally no room to the right. The lower one doesn't. I'm assuming it's got something to do with the character width. In other browsers, the word is always displayed below the box, as expected.
Does anybody know what causes this behaviour or have an idea for a workaround? The size, float and word-wrap properties must stay, however.
Edit: Oh, by the way, writing the markup like this seems to fix it, but it's not something I have control over (imagine user input via tinyMCE):
<div id="parent">
<div id="box"></div>
<div>
OIL
</div>
</div>
This appears to be a bug in Chrome.
In Chrome 50.0.2661.102 m the expected result was displayed
In Chrome 51.0.2704.103 m the undesired result is displayed
What can be done to avoid this issue?
I imagine that this bug will be fixed in time, but in the meantime you could use letter-spacing to increase the amount of space taken by the letters and force the expected behaviour.
.parent {
background: yellow;
height: 120px;
margin-bottom: 20px;
width: 100px;
word-wrap: break-word;
}
.box {
background: red;
float: left;
height: 100px;
width: 100%;
}
.word {
letter-spacing: 1.8px;
}
<div class="parent">
<div class="box"></div>
<div class="word">OIL</div>
</div>
<div class="parent">
<div class="box"></div>
<div class="word">OWL</div>
</div>
JS Fiddle
Floating elements in css causes errors like this. In previous versions of Internet explorer, we used to see problems like this all the time.
If I float one element, and want others stay intact, I usually use "clear:both" on the next element so that that element and the elements after that would not be effected.
#parent {
background: yellow;
height: 120px;
margin-bottom: 20px;
width: 100px;
word-wrap: break-word;
}
#box {
background: red;
height: 100px;
float:left;
width: 100%;
}
.box-2 {
clear:both;
}
<div id="parent">
<div id="box"></div>
<div class="box-2">OIL</div>
</div>
<div id="parent">
<div id="box"></div>
<div>
OIL
</div>
</div>
Floating elements are out-of-flow, so they overlap following blocks, unless they establish a block formatting context. That shouldn't be a problem, because line boxes are reduced, so the text should be pushed below the float in a full-width line box.
However, for some reason, this layout confuses Chrome. To fix this, you can establish a block formatting context with display: inline-block.
#parent {
background: yellow;
height: 120px;
margin-bottom: 20px;
width: 100px;
word-wrap: break-word;
}
#box {
background: red;
float: left;
height: 100px;
width: 100%;
}
#box + div {
display: inline-block;
}
<div id="parent">
<div id="box"></div>
<div>OIL</div>
</div>
<div id="parent">
<div id="box"></div>
<div>OWL</div>
</div>
Give a space character after the OIL or any unbreakable word. This might fix the error. Since word-wrap is breaking all the alphabets in the word.
#parent {
background: yellow;
height: 120px;
margin-bottom: 20px;
width: 100px;
word-wrap: break-word;
}
#box {
background: red;
float: left;
height: 100px;
width: 100%;
}
<div id="parent">
<div id="box"></div>
<div>OIL </div>
</div>
<div id="parent">
<div id="box"></div>
<div>OWL</div>
</div>

Text overflow hides text when it shouldn't in Safari

I want to have various tags in a container and have them display ellipsis when the tag text is too big (i.e. when it would stretch beyond the width of the container). The problem I am facing is that in Safari, the ellipsis are displayed even though the tag has space to display the full content.
This is the code that shows what I'm trying to achieve:
.tag {
height: 30px;
background: #F67;
line-height: 30px;
display: block;
float: left;
max-width: calc(100% - 20px);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding: 0 5px;
margin: 5px 5px 0;
border-radius: 16px;
}
.content {
float: left;
max-width: calc(100% - 20px);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.icon {
float: right;
background: blue;
width: 20px;
text-align: center;
color: white;
text-decoration: none;
}
.container {
border: 2px solid blue;
width: 300px;
height: 400px;
padding: 10px;
}
<div class="container">
<div class="tag">
<span class="content">Some tag</span>
X
</div>
<div class="tag">
<span class="content">Some tag</span>
X
</div>
<span class="tag">
blahbsalkfnewijfnewifbwiefnbijfneifjnweifniwjenfewi
</span>
<div class="tag">
<span class="content">Some tags</span>
X
</div>
</div>
If you're running the snippet above in Safari(v8.0.8 is the one I am using) you can see the last tag shows ellipsis even though it still has space to stretch and display the full text. If you can't see what I am talking about here is a screenshot of the issue:
text-overflow problem on safari image
Small mention about the 'X' is that it is intended as an icon someone could click on and delete the tag, but that functionality is not the subject of this question.
I'm using this trick: adding a non-break space right after the text. You can add it directly into your html, like <div class="ellipsis">Test </div> or you can use the :after pseudo element. Here's the .ellipsis class that I'm using:
.ellipsis {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.ellipsis:after {
content: "\0000a0";
display: inline-block;
width: 0;
}
The use of :after has another advantage, it's hidden by setting width: 0;, so you won't notice a larger gap between this element and the thing next to it (another element or a border).
When you remove the following lines from your .content element it works fine by me.
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
example: http://codepen.io/WartClaes/pen/ZQxaKW?editors=1100
Edit: although when looking further I see that you don't always use the same HTML structure? Which results in the double text overflow declaration. Isn't it possible to always use the same structure?
You need to add a "width" for the text, down to the text-overflow:
width: 100%; /Or the size you need/
It works for me in the safari 13.

Empty span causes weird margin / padding

When I place a fixed size display-block <span> element inside a <div> it causes a weird margin or padding (I don't know) at the bottom of the <div>. When there is text inside the <span> element, everything is fine. What's the reason for this? How can I fix it? I tested on Firfox and Chrome.
Weird space http://picster.at/img/0/9/6/0968c75ddf29ad07cb71eee2cff472a9.png
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
<!--
.outer {
background: grey;
padding: 4px;
}
.inner {
display: inline-block;
background: cyan;
height: 40px;
width: 40px;
}
-->
</style>
</head>
<body>
<div class="outer">
<span class="inner">Foo</span>
</div>
<br>
<div class="outer">
<span class="inner"></span>
</div>
</body>
</html>
Update:
Floating would be an alternative to display-block elements. Perfectly valid, however I would like to understand what's wrong with display-block in this example. Also, it doesn't look like a white-space problem to me, as this would only affect margin to the left/right (correct me if I'm wrong).
It is because you are using inline-block;, this is the best example of how inline-block is different from floats
Demo
.outer {
background: grey;
padding: 4px;
overflow: hidden;
}
.inner {
float: left;
background: cyan;
height: 40px;
width: 40px;
}
inline-block leaves whitespace of 4px margin.
More Info
This hack works great for me.
Demo
.inner:after{
content: '\00a0';
}
inline-block is messing it up
If your intention of setting it as inline-block was to set a row of .inner's, set change the inner to block, and float left.
Then use a div with clear: both to fix the issue that normally the floating causes.
Here's your code modified:
<head>
<style type="text/css">
<!--
.outer {
background: grey;
padding: 4px;
}
.inner {
display: block;
background: cyan;
height: 40px;
width: 40px;
float: left;
margin-right: 4px;
}
.clear{
clear:both;
}
-->
</style>
</head>
<body>
<div class="outer">
<span class="inner">Foo</span>
<div class="clear"></div>
</div>
<br>
<div class="outer">
<span class="inner"></span>
<span class="inner"></span>
<div class="clear"></div>
</div>
</body>
</html>
It can be solved by setting the "line-height" of the outer element to 0. This solves pretty much every case.
Don't forget to make sure the inner element doesn't inherit that though, to do this you can just set it to "line-height:initial".
.outer {
background: grey;
padding: 4px;
line-height:0;
}
.inner {
display: inline-block;
background: cyan;
height: 40px;
width: 40px;
line-height:initial;
}

Dont wrap row of divs

How to create set of float:right divs one next to another and make them not wrap, no matter how much of them exists or how wide is any of them. If they together are wider than viewport, then x-scroll should appear.
Content inside those divs should wrap normally.
CSS only would be good.
Style the parent element with white-space: nowrap;, though this only works with display: inline (or display: inline-block;) elements. Given the following HTML:
<div id="parent">
<div class="child"></div>
<!-- there's quite a lot of these... -->
<div class="child"></div>
</div>
And the CSS:
#parent {
white-space: nowrap;
}
#parent .child {
display: inline-block;
/* there's some other CSS for aesthetics */
}
JS Fiddle demo.
Unfortunately I don't think there is a way of forcing float-ed elements to not wrap to a new line.
To preserve or, rather, force normal line-wrapping for descendant elements you'll have to explicitly over-ride the inheritance and set white-space: normal (as well as, possibly, define a width or max-width)
/* other CSS remains intact */
#parent .child {
display: inline-block;
/* irrelevant/aesthetic CSS */
white-space: normal;
max-width: 8em;
}
JS Fiddle demo.
Few elements: http://jsfiddle.net/thirtydot/A8duy/
Many elements: http://jsfiddle.net/thirtydot/A8duy/1/
HTML:
<div class="block-container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>​
CSS:
.block-container {
text-align: right;
white-space: nowrap;
float: left;
width: 100%;
margin-bottom: 1em;
border: 1px solid red;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.block-container > div {
width: 50px;
height: 50px;
vertical-align: top;
display: inline-block;
*display: inline;
zoom: 1;
text-align: left;
white-space: normal;
border: 1px solid blue;
}

Resources