I have a data table that needs to scroll vertically. It seems that if your display value is table, you cannot set a height or max-height, and so overflow-y:scroll does nothing.
(Codepen with table)
.fake-table {
display: table;
max-height: 300px;
overflow-y: scroll;
}
Also, if you remove the display:table from the parent but keep the display:table-row and table-cell, the width of the rows will not be 100%;
I tried instead doing this with flexbox (Codepen with flexbox). But of course, then I don't have nice columns that are left-justified.
.fake-table > * {
display: flex;
justify-content: space-around;
}
Browser support is all modern browsers (IE10 +) including mobile safari and android browser.
It seems that if your display value is table, you cannot set a height or max-height
Effectively, the spec says (max-height):
In CSS 2.1, the effect of 'min-height' and 'max-height' on tables,
inline tables, table cells, table rows, and row groups is undefined.
And you can use the height property, but it will be treated as a minimum height, and thus won't produce overflow (Table height algorithms):
The height of a table is given by the 'height' property for the
'table' or 'inline-table' element. A value of 'auto' means that the
height is the sum of the row heights plus any cell spacing or borders.
Any other value is treated as a minimum height.
Also, if you remove the display:table from the parent but keep the display:table-row and table-cell, the width of the rows will not be 100%
In this case, since there is no tabular container, an anonymous one is generated (Anonymous table objects):
Document languages other than HTML may not contain all the elements in
the CSS 2.1 table model. In these cases, the "missing" elements must
be assumed in order for the table model to work. Any table element
will automatically generate necessary anonymous table objects around
itself
But that anonymous table won't necessarily be as wide as .fake-table.
I tried instead doing this with flexbox
Flexbox is a bad choice because it has no grid notion.
Maybe CSS Grid would be better, but it's currently experimental and only IE10 supports it (an older version of the spec, tough).
Basically, you have two options:
Fixed column width approach
If you predefine the width of the columns, the result will be a grid, even if you don't use tabular/grid displays.
Non-tabular to wrapper
You can wrap your table inside a dummy (non-tabular) element, and set overflow and max-height to that element.
Wrap your .fake-table in a div?
CodePen
Also, it is 100% acceptable to use actual <table>'s for displaying tabular data... actually it's preferred. Its using tables for layout when things get hairy.
This addition worked for me:
table {
width: 100%;
}
.example-container {
height: 400px;
max-width: 100%;
overflow: auto;
}
Just set a container for your table, make it scrollable and fix its size, and limit its width, to prevent horizontal scroll.
I would like to give credit to Hardik Savani, who wrote the solution & explanation here.
Related
We have a series of div components that are supposed to flex in IE11 as per the same behavior in Chrome. Within the following fiddle, you will find checkbox elements that make up a 'column' structure, as well as checkbox elements that are expected to fill the width of the entire parent.
On the second row where the full-width checkbox elements begin, that element is expected to wrap to the next line, because the .grid__item-flex element within it exceeds that width available to it in .grid__row a couple of levels up. However, on IE11, that width ceases to be respected, and thus .grid__item-flex continues to overflow off the width of the parent element.
Potential solutions that failed include enforcing a width on .grid__item-flex; where we give it 100% width, but the nested checkbox elements above will lose its column structure. Also, max-width: 100% as a property seems to be ignored when we apply it to .grid__item-flex.
Is there a CSS solution where we can force .grid__item-flex to respect its container width without breaking the nested columns above it, and ensure that the last checkbox element (below it) stays on the same line?
The JSFiddle that replicates my problem can be found here. The example works as expected on Chrome. Update Nov. 2018, JSFiddle no longer supports IE so this example is invalid unless we sandbox it elsewhere.
To summarize, there's two cases where flexboxes has to work simultaneously:
1) n number of div in a row that wraps to the next line if row width exceeds parent's width
We can achieve this using flex-wrap: wrap, but only when element has correct width
2) div that wraps to the next line if it's own content exceeds parent's width
Things I've tried:
Expanding out the shorthand flex: 1 into its full properties flex-grow flex-shrink flex-basis as "IE10 and IE11 default values for flex are 0 0 auto rather than 0 1 auto, as per the draft spec, as of September 2013"
Using a JS Polyfill for IE Flexbox, however the project is no longer being maintained (and did not work as a fix)
Using a PostCSS plugin for Webpack that attempts a global fix using flex: 1 1 0%
Applying width: 100% on the div that overflows its parent causes the nested columns above to turn into one long column, thus although it partially fixes the overflow issue, it defeats the purpose of having flexbox in the first place (since we want as many divs as possible to flex into a row).
If you need a solution which doesn't involve declaring width, I was able to get this working with a couple of flex specifications:
See example: https://jsfiddle.net/0ykq19um/
.grid__item-flex {
flex: 0 1 auto;
}
To be explicit with IE,
.grid__item-flex:only-child {
flex: 1 1 auto;
}
To allow full-width, and
.grid__row-overflow {
flex: 1 1;
}
For a new class on the .grid__row.grid__row-md.parent which surrounds the (potentially) overflowing row.
I'm trying to add a flexbox element to the content area of a two column layout. The layout has a fixed width sidebar and fluid content. It uses float: left and negative margins to achieve this.
The goal is for the flex container to be 100% width of the parent. Flex items should be displayed in rows, with excess items wrapping to the next row.
The straight-forward approach works fine in Firefox and Chrome:
.flex-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: stretch;
}
.flex-item {
flex: 1 0 100px;
padding: 10px;
border: 1px solid gray;
}
...
<div class="flex-container">
<div class="flex-item">Item</div>
<!-- more items here -->
<div class="flex-item">Item</div>
</div>
Full example (works in FF and Chrome, but not IE 11):
http://jsfiddle.net/btc9chw0/3/
The problem
In Internet Explorer 11, all items are displayed on a single row. They never wrap to the next row, even when there are lots of items. This causes the page to become much wider than the browser window.
After lots of experimentation, it appears that this is somehow related to the fact that the flex container is inside a float: left element. Removing the float allows items to wrap correctly, but breaks other parts of the layout. The content area can have other content in addition to the flexbox, and some of that content needs to use float: left and clear: both. Without a floating parent element, a clear: both would push everything below the sidebar. Giving .flex-container a fixed width also fixes the problem, but in this case we want it be 100% width.
Firefox screenshot:
IE 11 screenshot:
The question
Is there are way to make flex items wrap to the next row in IE 11 when the parent of the flexbox container has "float: left"?
Disclaimer: Please disregard, for the moment, the fact that this layout uses both floats and flexbox instead of just one or the other. In this case, flexbox is a nice-to-have enhancement for one part of the page, while the general layout must be more robust.
The underlying issue here actually has to do with the auto measurement of a container in a shrink-to-fit context. By making .content have a min-width of 100% you've left the max-width to auto so the browser needs to measure the content to know its max-width to shrink down around it.
In IE, complete layout will be done to get the exact result with no limitations if none were set (as is the case here, we actually have infinite space since we can scroll and you have limited the width anywhere within its ancestor tree). Webkit and Gecko had made some changes in the past to avoid having to actually do layout and do an approximation, even though the actual measurement results were incorrect since they didn't know how big other (shrink-to-fit containers were) they decided the perf benefits were worth the tradeoff. With Gecko, Webkit and Blink (due to forking from webkit) all using this same behavior we changed our implementation to match this in Microsoft Edge and so we render the same as Firefox, Chrome, Safari. To get the same result in IE11 you'll need to provide a maximum width constraint when in a shrink-to-fit context (floats, abspos, table cell, etc).
Ultimately I prefer the IE behavior because it actually makes sense and is consistent. If there is enough space to lay out the content, the layout shouldn't change (as is the case here). Here is a simpler example showing why this approximation can cause issues, there is still enough room in the viewport to render the same result in each case but because they can't determine the actual dimensions of the floated blocks you get different results in Chrome/Firefox/Safari/Edge; while in IE they produce the same consistent result.
Sorry for the long reply, but I wanted to provide the context for why IE seems incorrect here.
Let me know if you need any further clarification.
This is in addition to my recent question:
Is it possible to use pseudo-elements to make containing elements wrap around an absolutely-positioned element (like a clearfix)?
JSFiddle: http://jsfiddle.net/derekmx271/T7A7M/
I'm trying to use pseudo-elements to "clearfix" absolutely positioned images. I have gotten as far as getting the same image to display behind the slides, but cannot seem to apply widths to the inserted image. Am I crazy, or can you NOT apply widths to pseudo elements whose content is content: url(img/image.jpg)? I tried different variations of display:block, etc. to no avail...
#slider ul:after {
content: url(http://www.cs7tutorials.com/img/slide1.jpg);
display: block;
position:relative;
width:70px;
}
I need to set the width of the pseudo-element image to 100% and the max-width to 800px, so that it has the same dimensions as my slides.
You're not crazy: it is indeed not possible to change the dimensions of an image that is inserted using content, whether it's inserted with url(), image(), image-set(), element(), or a CSS gradient. The image is always rendered as is. This is known as replaced content, or a replaced element (except we're not talking about elements here).
However, since replaced elements can be resized using width and height as described in section 10 of the CSS2.1 spec, this raises the question of why the properties don't seem to apply here. The answer to this, it would seem, is that the properties do apply, but to the pseudo-element box instead — you can see this by giving your pseudo-element a background color. Rather than replacing the pseudo-element box itself, the image is rendered as a child of the pseudo-element box, and therefore cannot be styled at all (as it would require another pseudo-element which doesn't exist).
And that lends itself to another question: why doesn't it replace the pseudo-element box altogether? Unfortunately, CSS2.1 does not specify this behavior at all, so the implementation that was agreed on is to render the content as a child of the pseudo-element box instead:
CSS2.1 doesn't really clearly define the processing model of 'content' on ::before and ::after, but the informative examples in CSS 2.1, the fact that 'content' specifies a list of things, and the desire for consistency has led to UA behavior being the following: the 'content' property specifies a list of things that become children of the ::before or ::after box.
-Boris
Hopefully this will be further addressed in CSS Generated Content level 3, on which rewriting work has just begun.
In the meantime, if you want to be able to resize the :after pseudo-element and the image that's generated, you will need to apply it as a background image instead and — assuming browser support isn't an issue — use background-size along with width and height to scale it (based on the understanding that those properties apply to the pseudo-element box instead).
You can set either width or height, but not both, by using display: flex and setting flex-direction to the opposite axis of the dimension you wish to set.
For example:
.setWidth::before {
content: url("myImg.png")
display: flex;
flex-direction: column;
width: 200px;
}
.setHeight::before {
content: url("myImg.png")
display: flex;
flex-direction: row;
height: 200px;
}
Demonstration here.
Have a look at the demo using background-image: http://jsfiddle.net/T7A7M/12/
I'm using this free html template to create a page that displays some information about a web application. Please see this JsFiddle for reference: http://jsfiddle.net/wx3Gz/1/
The problem are the tables in the three columns in the main content.
I'd like to set the tables to the same width as the column (274px) each, and the content should be automatically arranged within.
For the first table I'd like to have the 2nd column to be as wide as the content requires, the first column then should take up the rest of the available width and overflow with ellipsis.
Anything I already tried (setting display: block on the table, using tabley-layout: fixed) resulted in either a table with all the columns having the same (wrong) width or in the most cases in content overflowing the column.
The perfect solution would format all tables in the three group-elements to a max width and allow to set a css class on the columns (the th elements, that is) that should show ellipsis where the column gets to wide). An almost perfect solution would require that css class on every cell.
I need this to work in Firefox and IE7/8. Ideally also IE9 and Chrome.
Try setting a max-width on the table cells rather than on the table directly:
td {
max-width: 200px;
}
td div, td {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
Here's a modified version of your code. I'm not on Windows, so I can't check in IE.
I like to get my table behave like a block element. I cannot set it to width:100% because it does have some padding, this is going to result 100% + the paddings PX.
Check out: http://jsfiddle.net/LScqQ
Finally the table does what I want, can you see the box-shadow? But the table children don't like it that way^^
I guess the TH inside the THEAD are the problem.
They do not get the aspected ratio of 66% to 33%.
Help wanted...
Your table should be display: table. If you're worried about the sizing, use box-sizing: content-box.
The reason is that display: table creates the table layout mechanism the rows and columns need to be laid out; in certain conditions if the required elements aren't there, they will be implicitly created, but it can cause problems. (You can test that out by making a table layout with divs and setting them to display: table, table-row, table-cell, which are the default user agent styles for table, tr, and td elements. If you play around with unsetting the styles on the divs in different combinations, you'll see that sometimes the browser implicitly makes the table layout incorrectly.)
So, always leave the display: table-* styles intact if you want an actual table layout. Sort out your width issues using the appropriate styles for that. If you describe better what you want, maybe you can get a better answer.
Finally I found the answer by myself.
Put your table inside a wrapper container and write a CSS rule similar to this:
//HTML
<div class="wrapper-table">
<table>...</table>
</div>
//CSS
.wrapper-table > table
{
width: 100%;
}
Now the table will no longer overflow your layout and fits perfectly like most elements do.