简体   繁体   中英

Weird line-break on special character

The problem

I recently discovered an encoding problem in my backend for when calculating the initials of a user when the first letter is germanic letter (eg Ö and Ä ). Those letters couldn't be parsed and ended up being a question-mark.

But what I also discovered is a rather peculiar behavior (and the reason I seek advise) in my markup that simply makes no sense to me whatsoever.

I've replicated simplified example below:

 ul { padding: 0; display: flex; } li { list-style-type: none; font-family: 'Roboto', sans-serif; flex-direction: column; margin: 15px; width: 260px; min-height: 200px; padding: 30px 15px; text-align: center; background: white; border: 1px solid #E8E8E8; } .avatar { height: 35px; width: 35px; border: 2px solid #333; line-height: 35px; padding: 1px 2px; align-self: auto; margin: 10px auto 0; position: relative; } .avatar span { left: 50%; position: absolute; transform: translateX(-50%); } 
 <ul> <li> <div class="avatar"> <span>?N</span> </div> <h4>Örjan Norberg</h4> <span>orjan@example.com</span> </li> <li> <div class="avatar"> <span>II</span> </div> <h4>Isaac Ibarra</h4> <span>isaac@example.com</span> </li> <li> <div class="avatar"> <span>WW</span> </div> <h4>Wyatt Williams</h4> <span>wyatt@example.com</span> </li> </ul> 

You'll see that "Örjans" initials are ?N , but also that the "N" is being pushed down to the next line. This doesn't seem to be related to the avatar width because I tried with both long and short initials.

In fact, even if I put WWWWW or something else ( pic ) that overflows the avatar, there is no line-break which is as expected. I also tried other special characters, such as & and % , but those behave just as any other character or letter.


Question

What causes this behavior when using the question-mark specifically? Is it somehow related to the font ( Roboto ) or is it my css?

Also, (see pics below) how come this happens when the question-mark is followed by a letter, but not when the order is reversed (letter first) or when followed by another question-mark?

在此输入图像描述

What's going on here??


EDIT 1: Using OSX/Chrome.v59, though can replicate in Windows7/IE11

EDIT 2: Apparently the character also causes this behavior (thanks to @MrLister for finding this)

What you see happening is that the bounding client rectangle for the combination ?N is too wide to fit without overflow, and so the browser does whatever it should do when it sees overflow, based on default rules and CSS overrides. Part of the reason is that the translate and scale transforms do not reposition elements, they only draw them somewhere else, so your transform does not counteract your absolute positioning. Have a look at http://jsbin.com/gujafokiwe/edit?html,css,output and notice that as far as the DOM is concerned that span is still in its original position , we've only told CSS to draw it somewhere else.

When the browser sees ?N (and specifically: some browsers. Not all of them) it might see that it needs to break the line based on the bounding client rect dimensions. However, browsers are free to pick their rules for when and how to break text sequences (CSS does not specify which rules must be used, only that for unicode content outside of CJK it is advisable to use http://www.unicode.org/reports/tr14/tr14-37.html ) and while your example works fine in my Firefox, not breaking the text at all, my Chrome does see overflow, and does try to break up the sequence(s) as best as it knows how to.

Unfortunately, the only true answer on why it does that is in the code for the text render engine - that's either in Blink, or in Webkit, both of which are (mostly) open source and so unless you happen to get the eyes of the person or people who implemented it on this question, you're going to have to seek them out rather than hope they browser Stackoverflow and find your question: your best bet is to read through http://www.chromium.org/blink#participating and then post this question to their dev mailing list.

(Solutions for your problem are varied: remove the .avatar span rule and just text-align: center the parent div, or even better: use flexbox rules)

The ? in the first span is a word-break opportunity; after all, the N is the start of a word. This doesn't happen in the other spans, since those contain a whole word each only. So what you should do is apply white-space: nowrap to the span, so that it no longer wraps.

Edit: while this is not the explanation to what's actually happening - it doesn't happen with most other non-word characters, so "word boundary" is not the whole of the story; see comments - it still provides a practical workaround, so I'm leaving this up.

 ul { padding: 0; display: flex; } li { list-style-type: none; font-family: 'Roboto', sans-serif; flex-direction: column; margin: 15px; width: 260px; min-height: 200px; padding: 30px 15px; text-align: center; background: white; border: 1px solid #E8E8E8; } .avatar { height: 35px; width: 35px; border: 2px solid #333; line-height: 35px; padding: 1px 2px; align-self: auto; margin: 10px auto 0; position: relative; } .avatar span { left: 50%; position: absolute; transform: translateX(-50%); white-space:nowrap; } 
 <ul> <li> <div class="avatar"> <span>?N</span> </div> <h4>Örjan Norberg</h4> <span>orjan@example.com</span> </li> <li> <div class="avatar"> <span>II</span> </div> <h4>Isaac Ibarra</h4> <span>isaac@example.com</span> </li> <li> <div class="avatar"> <span>WW</span> </div> <h4>Wyatt Williams</h4> <span>wyatt@example.com</span> </li> </ul> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM