Sometimes when a piece of data in one of my table cells is too long it stretches the cell and deforms the layout of the entire table. how can i prevent this?
You probably want table-layout:fixed and set width on the first cells of a row.
See http://www.w3.org/TR/CSS2/tables.html#fixed-table-layout for detailed explanation.
I just had the same problem and ended up solving it with this:
table { width: 1px; /* This ugly hack allows the table to be only as wide as necessary, breaking text on spaces to allow cells to be less wide. */ }
Apparently, setting the table width to something very small forces it to break text up and take less horizontal space. Words will not be broken though, so the table will end up being at least large enough for the largest word of each column.
Tried tested and true on:
Linux (Ubuntu 10.04)
Firefox 3.6.18
Chromium-browser 12.0.742.112 (90304) whatever all that means
Konqueror 4.5.3
SeaMonkey 2.0.11
Windows:
Internet Explorer 7
Firefox 4.0.1
If someone (I can't in my present situation) could test this on latest versions of IE, Firefox, Chrome, Safari and Opera and leave a comment or edit this answer, that would be awesome!
Assuming you don't have any non-breaking spaces or super-long text without a space in the cell, I've usually had the best luck by explicitly setting the width of said cell via CSS (seems to work better than doing something like "width='100'". If the data in the cell is just a really long string, there's not much you can do other than truncate it programatically, or wrap the data in a div with an explicit width and something like overflow: hidden / auto (auto if you want a horizontal scrollbar or something).
Set the width and height of the td tag using CSS. Then you need to deal with overflow.
td {
width: 40px;
height: 20px;
}
Use overflow: hidden to hide the overflow as such:
td, th {
overflow: hidden;
}
For this to work, your <td> or <th> tags needs to be assigned a width.
If you must absolutely have the table maintain it's layout even in the face of non-breaking spaces, then you'll need to use:
overflow: hidden;
However, I'd recommend against it. IMO, it's more important to have the data readable than the layout perfect.
Related
So I've been banging my head against a wall trying to figure this issue out with Chrome and how it has a hard time wrapping long URLs in a table cell. I have seen a lot of questions regarding word wrapping and some even had with long URLs but none of them worked for me. So essentially, I tried putting in the td
word-wrap:break-word;
but this doesn't wrap the long URL which is (changed here, doesn't go to anything):
https://differentName/api/?REQUEST=%3C%3Fxml%20version%3D%271.0%27%20%3F%3E%3Cnta%3E%3Capi%20version%3D%271.0%27%3E%woot%20function%3D%22login%22%3E%3Clogin%3E%3C!%5BCDATA%5Bjpublic%something.com%5D%5D%3E%3C%2Flogin%3E%3Cpassword%3E%3C!%5BCDATA%5Bnta46550%5D%5D%3E%3C%2F
I've tried adding a width property onto the td but I get nothing. I was also told that when using the word-wrap property to also include:
table-layout:fixed;
But I don't want my columns fixed in width. Also, I don't have the wrapping issue if I use the fixed property. I'm working off of the latest version of Chrome (as of this date). No issues with FF 26.0 or IE 11. Any help would be great.
I would just establish a class on the td that you are having the issue with.
In its current state, you are only breaking when spaces are present.
If you want to force breaks without spaces in Chrome as well, you can use the CSS word-break: break-all;
Does something like this work for you?
http://jsfiddle.net/qqsj8/2/
CSS:
td.break {
/* Be VERY careful with this, breaks normal words wh_erever */
word-break: break-all;
}
HTML:
<td class="break">Why do...</td>
Problem
I have a <select> where one of its <option>’s text values is very long. I want the <select> to resize so it is never wider than its parent, even if it has to cut off its displayed text. max-width: 100% should do that.
Before resize:
What I want after resize:
But if you load this jsFiddle example and resize the Result panel’s width to be smaller than that of the <select>, you can see that the select inside the <fieldset> fails to scale its width down.
What I’m actually seeing after resize:
However, the equivalent page with a <div> instead of a <fieldset> does scale properly. You can see that and test your changes more easily if you have a <fieldset> and a <div> next to each other on one page. And if you delete the surrounding <fieldset> tags, the resizing works. The <fieldset> tag is somehow causing horizontal resizing to break.
The <fieldset> acts is as if there is a CSS rule fieldset { min-width: min-content; }. (min-content means, roughly, the smallest width that doesn’t cause a child to overflow.) If I replace the <fieldset> with a <div> with min-width: min-content, it looks exactly the same. Yet there is no rule with min-content in my styles, in the browser default stylesheet, or visible in Firebug’s CSS Inspector. I tried to override every style visible on the <fieldset> in Firebug’s CSS Inspector and in Firefox’s default stylesheet forms.css, but that didn’t help. Specifically overriding min-width and width didn’t do anything either.
Code
HTML of the fieldset:
<fieldset>
<div class="wrapper">
<select id="section" name="section">
<option value="-1"></option>
<option value="1501" selected="selected">Sphinx of black quartz, judge my vow. The quick brown fox jumps over the lazy dog.</option>
<option value="1480">Subcontractor</option>
<option value="3181">Valley</option>
<option value="3180">Ventura</option>
<option value="3220">Very Newest Section</option>
<option value="1481">Visitor</option>
<option value="3200">N/A</option>
</select>
</div>
</fieldset>
My CSS that should be working but isn’t:
fieldset {
/* hide fieldset-specific visual features: */
margin: 0;
padding: 0;
border: none;
}
select {
max-width: 100%;
}
Resetting the width properties to the defaults does nothing:
fieldset {
width: auto;
min-width: 0;
max-width: none;
}
Further CSS in which I try and fail to fix the problem:
/* try lots of things to fix the width, with no success: */
fieldset {
display: block;
min-width: 0;
max-width: 100%;
width: 100%;
text-overflow: clip;
}
div.wrapper {
width: 100%;
}
select {
overflow: hidden;
}
More details
The problem also occurs in this more comprehensive, more complicated jsFiddle example, which is more similar to the web page I’m actually trying to fix. You can see from that that the <select> is not the problem – an inline-block div also fails to resize. Though this example is more complicated, I assume that the fix for the simple case above will also fix this more complicated case.
[Edit: see browser support details below.]
One curious thing about this problem is that if you set div.wrapper { width: 50%; }, the <fieldset> stops resizing itself at the point then the full-size <select> would have hit the edge of the viewport. The resizing happens as if the <select> has width: 100%, even though the <select> looks like it has width: 50%.
If you give the <select> itself width: 50%, that behavior does not occur; the width is simply correctly set.
I don’t understand the reason for that difference. But it may not be relevant.
I also found the very similar question HTML fieldset allows children to expand indefinitely. The asker couldn’t find a solution and guesses that there is no solution apart from removing the <fieldset>. But I’m wondering, if it really is impossible to make the <fieldset> display right, why is that? What in <fieldset>’s spec or default CSS (as of this question) causes this behavior? This special behavior is probably be documented somewhere, since multiple browsers work like this.
Background goal and requirements
The reason I’m trying to do this is as part of writing mobile styles for an existing page with a big form. The form has multiple sections, and one part of it is wrapped in a <fieldset>. On a smartphone (or if you make your browser window small), the part of the page with the <fieldset> is much wider than the rest of the form. Most of the form constrains its width just fine, but the section with the <fieldset> does not, forcing the user to zoom out or scroll right to see all of that section.
I’m wary of simply removing the <fieldset>, as it is generated on many pages in a big app, and I’m not sure what selectors in CSS or JavaScript might depend on it.
I can use JavaScript if I need to, and a JavaScript solution is better than nothing. But if JavaScript is the only way to do this, I’d be curious to hear an explanation for why this is not possible using only CSS and HTML.
Edit: browser support
On the site, I need to support Internet Explorer 8 and later (we just dropped support for IE7), the latest Firefox, and the latest Chrome. This particular page should also work on iOS and Android smartphones. Slightly degraded but still usable behavior is acceptable for Internet Explorer 8.
I retested my broken fieldset example on different browsers. It actually already works in these browsers:
Internet Explorer 8, 9, and 10
Chrome
Chrome for Android
It breaks in these browsers:
Firefox
Firefox for Android
Internet Explorer 7
Thus, the only browser I care about that the current code breaks in is Firefox (on both desktop and mobile). If the code were fixed so it worked in Firefox without breaking it in any other browsers, that would solve my problem.
The site HTML template uses Internet Explorer conditional comments to add classes such .ie8 and .oldie to the <html> element. You can use those classes in your CSS if you need to work around styling differences in IE. The classes added are the same as in this old version of HTML5 Boilerplate.
Update (25 Sept 2017)
The Firefox bug described below is fixed as of Firefox 53 and the link to this answer has finally been removed from Bootstrap's documentation.
Also, my sincere apologies to the Mozilla contributors who had to block removing support for -moz-document partly due to this answer.
The fix
In WebKit and Firefox 53+, you just set min-width: 0; on the fieldset to override the default value of min-content.¹
Still, Firefox is a bit… odd when it comes to fieldsets. To make this work in earlier versions, you must change the display property of the fieldset to one of the following values:
table-cell (recommended)
table-column
table-column-group
table-footer-group
table-header-group
table-row
table-row-group
Of these, I recommend table-cell. Both table-row and table-row-group prevent you from changing width, while table-column and table-column-group prevent you from changing height.
This will (somewhat reasonably) break rendering in IE. Since only Gecko needs this, you can justifiably use #-moz-document—one of Mozilla's proprietary CSS extensions—to hide it from other browsers:
#-moz-document url-prefix() {
fieldset {
display: table-cell;
}
}
(Here's a jsFiddle demo.)
That fixes things, but if you're anything like me your reaction was something like…
What.
There is a reason, but it's not pretty.
The default presentation of the fieldset element is absurd and essentially impossible to specify in CSS. Think about it: the fieldset's border disappears where it's overlapped by a legend element, but the background remains visible! There's no way to reproduce this with any other combination of elements.
To top it off, implementations are full of concessions to legacy behaviour. One such is that the minimum width of a fieldset is never less than the intrinsic width of its content. WebKit gives you a way to override this behaviour by specifying it in the default stylesheet, but Gecko² goes a step further and enforces it in the rendering engine.
However, internal table elements constitute a special frame type in Gecko. Dimensional constraints for elements with these display values set are calculated in a separate code path, entirely circumventing the enforced minimum width imposed on fieldsets.
Again—the bug for this has been fixed as of Firefox 53, so you do not need this hack if you are only targeting newer versions.
Is using #-moz-document safe?
For this one issue, yes. #-moz-document works as intended in all versions of Firefox up until 53, where this bug is fixed.
This is no accident. Due in part to this answer, the bug to limit #-moz-document to user/UA stylesheets was made dependent on the underlying fieldset bug being fixed first.
Beyond this, do not use #-moz-document to target Firefox in your CSS, other resources notwithstanding.³
¹ Value may be prefixed. According to one reader, this has no effect in Android 4.1.2 Stock Browser and possibly other old versions; I have not had time to verify this.
² All links to the Gecko source in this answer refer to the 5065fdc12408 changeset, committed 29ᵗʰ July 2013; you may wish to compare notes with the most recent revision from Mozilla Central.
³ See e.g. SO #953491: Targeting only Firefox with CSS and CSS Tricks: CSS hacks targeting Firefox for widely referenced articles on high-profile sites.
Safari on iOS issue with selected answer
I found the answer from Jordan Gray to be particularly helpful.
However it didn't seem to solve this issue on Safari iOS for me.
The issue for me is simply that the fieldset cannot have an auto width if the element within has a max-width as a % width.
Fix for issue
Simply setting the fieldset to have a 100% width of it's container seems to get around this issue.
Example
fieldset {
min-width: 0;
width: 100%;
}
Please refer to the below for working examples - if you remove the % width off the fieldset or replace it with auto, it will not continue to function.
JSFiddle | Codepen
I’ve struggled for many hours with this, and basically, the browser is applying computed styling that you need to override in your CSS. I forget the exact property that is being set on fieldset elements versus divs (perhaps min-width?).
My best advice would be to change your element to a div, copy the computed styles from your inspector, then change your element back to fieldset and compare the computed styles to find the culprit.
Hope that helps.
Update: Adding display: table-cell helps in non-Chrome browsers.
.fake-select { white-space:nowrap; } caused the fieldset to interpret the .fake-select element by its original width, rather than its forced width (even when the overflow is hidden).
Remove that rule, and change .fake-select's max-width:100% to just width:100% and everything fits. The caveat is that you see all of the content of the fake-select, but I don't think this is all that bad, and it fits horizontally now.
Update: with the current rules in the following fiddle (which contains only real selects), the fieldset's children are constrained to correct widths. Other than removing rules for .fake-select and fixing comments (from // comment to /* comment */, I've noted changes in the fiddle's CSS.
I understand your problem better now, and the fiddle reflects some progress. I set default rules for all <select>s, and reserve .xxlarge for those which you know will be wider than 480px (and this only works because you know the width of #viewport, and can manually add the class to those too wide. Just requires a little bit of testing)
Proof
I am working with a legacy html code which uses tables extensively for layout. For the page I'm making I unfortunately have to call one of these legacy systems which returns the output in table with multiple tr's.
I got it to align on the same line in both Firefox/Chrome by using
display: inline;
float: left;
But it still doesn't work in IE9 (I haven't tested with other versions of IE). Is there anything to force IE to display both <tr> elements on the same line?
I would try
display:inline-block;
Untested
You might also consider using javascript to manipulate the elements once the DOM is rendered.
EDIT
The other thing you might do is set a specific width on the trs. IE9 might be giving them a default 100%, so less than 50% each if there are two of them, etc.
I have an HTML table 360px wide, which works great. The challenge is that sometimes a url appears http://this/is/a/really-really-really-really-really/long/url in the text. This causes the table to expand horizontally and a scroll bar appears on the bottom.
I don't think overflow:hidden will work because half of the text would be hidden.
What is the best way to force breaking the line on slashes (/) and dashes (-) in CSS (hopefully)?
It should work with IE7+, Chrome, Firefox and Safari.
Working in Rails 3 and jQuery.
tl;dr; (edited Apr 2022)
Use <wbr> word-break-opportunity element before each /. See first link in further reading below.
Details (original from 2014)
While the css word-wrap: break-word; does work, its implementation is different across browsers.
If you have control of the content and want exact breakpoints, you can insert
a <wbr> word break (supported in all major browsers except IE8 CanIUse.com);
zero-width space (U+200B) - ugly in IE<=6
soft hyphen - though of course this adds a hyphen when breaking which is not always what is desired.
I have a large corporate user base who still have to use IE8, so when I hit this problem I used the C# someString.Replace("/", "/") in the server-side code.
Gotcha: If you insert a zero-width space in an email address, when a user copies and pastes into their email client, the space gets copied too and the email will fail with no way for a user to see why (the space is zero width ...)
References
Stack Overflow
http://www.quirksmode.org/oddsandends/wbr.html - with examples
Further Reading
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr#example
https://developer.mozilla.org/en-US/docs/Web/CSS/word-break
https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-wrap
https://kenneth.io/blog/2012/03/04/word-wrapping-hypernation-using-css/ (March 2012)
https://css-tricks.com/almanac/properties/w/word-break/ (Sep 2012)
https://css-tricks.com/almanac/properties/h/hyphenate/ (Sep 2011)
You can use word-wrap : break-word; like so:
div {
width : 50px;
border : 1px solid #000;
word-wrap : break-word;
}
<div>http://www.aaa.com/bbb/ccc/ddd/eee/fff/ggg</div>
I tested this in: I.E. 6/7/8, Firefox 7, Opera 11, Safari 5, Chrome 15
Here is a jsfiddle: https://jsfiddle.net/p4SxG/
If you don’t really care where the breaks happen, the simplest method is to add the style overflow-wrap: break-word;. This will allow long words to break without affecting the breaking of other words.
But if you want to break at specific characters, such as the slash character, you can’t do that with CSS, you have to do it in HTML. If you have access to the HTML code you can choose any of these solutions:
<wbr> word break opportunity tag
zero width space
​ zero width space
But you don’t always have access to the HTML code. Some web applications won’t allow you to enter code into certain fields; for example, WordPress will filter out any code you enter into a post title. In these situations you may be able to insert a zero-width-space character directly. One way to do this is to use Character Viewer (Mac) or Character Map (Windows), although of course they are a bit tricky to use when it comes to spaces because spaces are invisible. In the case of Character Viewer, when you search for arrow, lots of matches appear, but when you search for zero width space, it appears that no characters were found. But if you click where the blue square is in the second image below, you’ll discover that the character was found, it’s just invisible.
A snippet to demonstrate that these various methods all work:
h1 {
width: 15rem;
border: 1px solid black;
}
.b {
overflow-wrap: break-word;
}
A title which is too long
<h1>Seminars/Workshops</h1>
Breaking with CSS
<h1 class="b">Seminars/Workshops</h1>
Breaking with HTML: code-based solutions
<h1>Seminars<wbr>/<wbr>Workshops</h1>
<h1>Seminars/Workshops</h1>
<h1>Seminars​/​Workshops</h1>
Breaking with HTML: character-based solution
<h1>Seminars/Workshops</h1>
I recently noticed in several webpages, and some of my own, that when they are displayed in Internet Explorer 9, when its not on Quirks Mode, it renders a white line, about 1px, in the bottom of the page. It's like the html tag was with padding-bottom:1px and wrapped in another element with white background (but it's not, and it has no padding). It looks like the differences between IE9 standards and quirks mode shows when determining a wrapping element's width, but vertically. It also feels like the content of an element gets pushed 1px by a previous element, like their content, but, not margins or borders, were overlapping the next element dimensions.
I can't determine exactly what causes it. Sometimes, a page contains 2 tables and everything is fine. Then you need to add a third one, and the line shows up. Doesn't even need to be tables btw.
Sometimes, reseting css solves it. Setting the same line-height we have on body to links:
body {
line-height: 1
}
a, links, visited {
line-height: 1
}
fixes it, but not always. Only thing i can do, is check element by element, disabling/enabling their css rules till it's gone.
I noticed that when there are elements like tables, inputs, textareas, this issue is more likely to happen. 'resetting' their attributes, sometimes, solves it too.
I know it would be easier to provide a code as an example, but like i said, i coudn't determine a pattern for it. I can give you some examples of sites/urls i notice that error (you gotta look at the very bottom of the page and see the difference between IE and another browser, like Firefox):
casinosdelmundo.info, gatosabido.com.br, espanol.yahoo.com, en.wikipedia.org/wiki/Bruce_Beutler, ea.com/command-and-conquer-4, facebook.com (the ones with white, or almost white bg, change body background with f12, developer's tool, and you'll see). I found an example even here at stackoverflow (as today, the main page stackoverflow.com is showing that line too, but that can change since, sometimes the issue appears or disappears when new elements show up or are removed):
this question has the white-line:
Make link in table cell fill the entire row height
this one has not:
FireFox 3 line-height
Check this screenshot, if you still didn't see what im talking about:
the presence of this issue on very established (or not) sites makes me feel it's a IE9 bug and the only definitive fix for it is always use white background, so nobody will notice the white line (the line will still be there though). but thats obviously not the best option. I never found this white line in Chrome or Safari.
So, has anyone faced the same problem and got a better solution?
I'm not sure, cause there is no HTML here, but it is very resemble to standard browser behavior, when it displays inline content. It is due to the fact, that when text is displayed browser needs to leave some space at the bottom for letters and symbols such as: "," , "y" , "p" and so on, cause in that letters there is a part which protrudes to the bottom. You can better understand what I'm talking about when you look at this picture:
example of how inline content is displayed
so if you have some markup like
<body>
<div></div>
<textarea></textarea>
</body>
you'll get that extra space at the bottom. To get rid off it you have to use there either block element, or set to your inline-element a css style 'display: block'
I found a solution to the problem, if an idiotic one: set the toggle of your browser window's Maximize/Restore down to Maximize (= tooltip text; this indicates that the window is in a nonmaximal state). Make the browser window actually smaller than screen fit. Press F11 in this state and there is no white line at the bottom of your screen (Win7 x32 & x64). (BTW, FF dose not have this problem and is the best alternative.)
It happens when you use fractional font-sizes.
For example, stackoverflow uses h2 {font-size: 140%;} body { font-size:80%;}, which results in an total font-size of 112% for h2. Apply that to 16px default size, and you get 17.93px (including rounding errors, hooray!)
Try it yourself: getComputedStyle(document.querySelector('h2')).fontSize
Browsers have a hard time rendering fractional pixels, and thus may get confused and add a pixel at the bottom.
By the way, Firefox has some trouble too. The spacing between the footer lines is off by a pixel.
The fix is obvious: Use integer pixels to declare font-sizes.
Another way would be to apply a :after content to your body only for IE and Edge.
This way you will get rid of the extra white line.
We may require some jQuery too so that the content applies only when you are at the bottom of the page.
body{
position:relative;
width:100%;
}
body:after{
content: "";
display:block;
background-color: #000;
height: 1px;
bottom: 0px;
position: fixed;
width: 100%;
}
jQuery
//add a border to internet explorer
if (bowser.name == "Microsoft Edge" || bowser.name == "Internet Explorer") {
//console.log(" iam inside");
$(window).scroll(function () {
if ($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
$("body").addClass("end-border");
}
else {
$("body").removeClass("end-border");
}
});
}