What is an alternative to css subgrid? - css

I'm working on a page with a pretty simple layout - basically a data table, but using grid layout so that the columns will adjust nicely depending on content size. I want to make the rows sortable (using jQuery), so I need to find a way to wrap all the cells of a same row in a container.
display: subgrid;
I've tried using subgrid but it seems it's not much supported at the moment.. Obviously, just nesting a grid doesn't work as it won't sync the column sizes between different grids..
Any idea on how to achieve that?
Here is my pen so far: https://codepen.io/anon/pen/PEjqgx

Depending on the context, display: contents may be a viable workaround for display: subgrid.
From caniuse: (bold mine)
display: contents causes an element's children to appear as if they
were direct children of the element's parent, ignoring the element
itself. This can be useful when a wrapper element should be ignored
when using CSS grid or similar layout techniques.
The big win here is that we can keep our current markup - which groups together each row of data - while keeping components of each row synced together because they are part of just one CSS grid - the grid container.
Regarding browser support: display: contents is supported by Chrome, Firefox and iOS 11.4+.
So getting back to the OP's sample Codepen, we can make use of display: contents to implement the desired result by:
1) Moving the grid container properties to the globalWrapper div and
#globalWrapper {
display: grid;
grid-template-columns: 1fr 1fr max-content;
grid-gap: 3px;
}
2) setting the rowWrapper divs with display: contents
.rowWrapper {
display: contents;
}
Updated Codepen demo

Using display:contents to simulate css subgrid is a hack: hacks add complexity — making the code harder to maintain and prone to other errors — and sooner or later they will stop working.
Beware of using display:contentsas a substitute for subgrid: there are good reasons why it should be avoided. Instead use either another Grid in the container element or Flex.
[Adendum 11/1/2020] Firefox supports Subgrid since V71, no word yet from the other browsers. There is a good explanations about the feature in codrops, and you can see some examples here. And this is the link to see the current support in all of the browsers in can I use
[Adendum 06/06/2022] Apple announces subgrid support for Safari 16

Related

Is there a way to use the clearfix hack alongside flexbox?

I've been using flexbox for layouts, with CSS floats as a fallback for older browsers. On the whole this works well, since browsers that understand display: flex will ignore float on any flex items.
However, the one place that I've run into a problem with this approach is with clearfix. Clearfix is a widely-used hack that uses an invisible :after pseudo-element to make a container properly clear / contain any floated elements inside it. However, the problem is that this pseudo-element is treated as a flex item by browsers that support flexbox, which can lead to unexpected layout issues. For example, if you have two flex items and use justify-content: space-between, instead of being positioned at the start and end of the flex container, they will appear in the start and middle, with the invisible clearfix ::after pseudo-element taking the end position.
My question is: is there a way to use clearfix alongside a flexbox layout without causing these problems?
One way to handle this would be to consider alternative clearfix methods.
The ::after pseudo-element is one method but, as you noted, it becomes a flex item in a flex container. (See Box #81 in this answer for more details).
But there are various other ways to clear floats. For instance, you could use overflow: auto or overflow: hidden.
Check out some alternatives here:
What is a clearfix?
What methods of ‘clearfix’ can I use?
Clearing Floats: An Overview of Different clearfix Methods
Another way to solve your problem uses modernizr.com for feature detection.
From the website:
All web developers come up against differences between browsers and
devices. That’s largely due to different feature sets: the latest
versions of the popular browsers can do some awesome things which
older browsers can’t – but we still have to support the older ones.
Modernizr makes it easy to deliver tiered experiences: make use of the
latest and greatest features in browsers which support them, without
leaving less fortunate users high and dry.
Try this, it will deal with pseudo-elements in a flex container:
.clearfix::before,
.clearfix::after {
flex-basis: 0;
order: 1;
}
I'm not sure if this is the same issue you were having, but I was using a fairly complicated flex setup:
display: flex;
flex-wrap:wrap;
align-items: center;
I ran into a similar issue where I wanted to use clearfix to make sure I could split the content at a certain point, in my case it was to make some data break on specific screen sizes. I was absoutely stumped until I found a solution through trial and error that worked for me:
<div class="clearflex"></div>
.clearflex{
width:100%;
}
By adding an empty div with 100% width between flex content it seems to make that content break onto the new line exactly like clearfix did. You can also added a height to clearflex if you need some padding between the rows.
You can set flex-wrap to your flex container and width: 100% to after pseudo element so it will wrap and not mess with alignment.
One way to achieve that is to use overflow: hidden or overflow: auto on .clearfix & completely remove .clearfix::after.
.clearfix {
overflow: auto; /* or overflow: hidden; */
}
However, if you can't use overflow property on .clearfix for some reason, you can use margin-left: auto on the second div (considering your layout has only two column). That way the invisible ::after will be placed in between two layout divs.
.clearfix { ... }
.clearfix::after { .... }
.clearfix > div:last-of-type {
margin-left: auto;
/* for justify-content: space-between only.
* For other option, adjust accordingly */
}

Why bootstrap uses floating elements to construct Grid System? [duplicate]

I was tinkering with custom grid and wanted to see how other people have created their grid-systems. Since twitter's bootstrap seemed to be so popular i've looked at its code. Now i wonder why are they using floats? I would use display: inline-block; html elements have either display: inline; or display: block; i would try to avoid floats. But for some reason bootstrap creators decided to use floats. first i was thinking they used them to have backward compatibility since ie6 does not support display: inline-block; and ie7 supports it only on elements with display: inline; by default. But ie6 more or less out of the game and since they use micro clearfix hack which uses *zoom: 1; to target ie6+ IMO they could replicate the same display: inline-block; with *display: inline; *zoom: 1; So the final Question Why Floats Over Display Inline Block? Are there any issues they tried to solve i didn't mentioned above?
Inline blocks are white-space aware, have an auto width of the actual content and stacks in the order they have in HTML. Floats aren't but require a clearfix method and are based on block elements. These elements have auto width on the available space horizontally. Purely semantically, inline-blocks are less semantic since the white-space aware format and importance of order. But looking at it purely in a functional way, both just aren't made for a grid. And if it wasn't for pseudo CSS, we would have un-semantic HTML tag clearfixe's as well. So in my believes they are both not winners. But there is no alternative for the time being when flexbox will become mandatory in upcoming years.
With inline blocks:
<div>
<div style="display:inline-block; width:30%;">col1
</div><div style="display:inline-block; width:70%;">col2</div>
</div>
Tags must be glued together/appended, to dismiss any gutter. The container div is necessary to force the items being part of a separate row.
With floats:
<div class="clearfix">
<div style="float:left; width:30%;">col1</div>
<div style="float:left; width:70%;">col2</div>
</div>
Clearfix is necessary to force a "row" (dismiss any normal flow items issues or floats after the floats)
Whether use one or the other is a matter of your goal (and taste). I must say I like inline-blocks more than floats, as long as you know the both of the col widths or use relative sizing (%). I thinks it's more intuitive and predictable than floats with clearfix, a fix" for issues that aren't even issues if it was used by how it should be used. Only the white-space awareness of inline blocks force you to use some funky html, that's a downside.
Ironically, tables do exactly all this (and even col-heights and vertically alignement's) without any issues. Since inline-blocks have to be placed in order, there's an motive for discussing here.
If we are talking about responsive, table 'loses' of inline-blocks. Let say you have 4 cols on a desktop and you want 2 cols on a tablet and 1 on a mobile. With inline blocks, you 'just' give the cols other width dimensions and they hopefully wrap nice (be aware of margins as they collapse). With tables, you're bound to actual rows, which can be quite stubborn. Flexbox is needed for a long time and looks beautiful. You can adjust the layout flexible on certain circumstances.
Bootstrap can be handy to learn how they did something. Just read in 3.0 they are using relative grid sizing. Which gives an issue with nested grids and aligning.
---- --a- ---- ----
---b------
.... ..c.
Col a is a normal parent col. Col c is a child nested col of b. It's hard to align c with a with relative sizing since the gutter is variable to the container, unless you're using padding and border-box model. But that way you lose a lot of flexibility. When you want the col to have some background and padding, you're messing up the grid system, so you have to use container which you style, which would clutter the code. I haven't studied if they found a solution to this. I haven't yet. I went to fixed pixels, but that means in responsive design you can only have a few fixed width's and for everything around mobile use a relative grid.
I prefer grid systems that use display: inline-block; rather than float, such as Pure (formerly Yahoo YUI Grid), because they internationalise without extra styles; change the text direction to right-to-left and the layout automatically reverses; floats don't do this. Floats also introduce the need to clear and other cross browser oddities. Any inaccuracies that inline-block may have over float can be remedied, as demonstrated by Pure. As to the criticism that display: inline-block; is not meant to be used for layout, perhaps the use of display: table; should also be banned for cross-browser centring. I would also question whether the term Semantic Web really applies to CSS since the term is primarily concerned with HTML and using its elements and attributes to impart machine readable meaning; the whole point of CSS is to style semantic HTML as radically as one wants to, hence classic sites like CSS Zen Garden.
I say that as long as the technique is not exploiting a bug, is not obstructing content to users and devices and is sufficiently supported then it is acceptable. There is no reason that one can't use CSS in unorthodox, but supported, ways, just like Stu Nicholls' CSSPlay.
Interestingly, Flexible Box is also incorporated into Pure grids, a superior layout system compatible with modern browsers (≥IE10 and equivalent browsers).
In the term of semantic web, the display: inline-block should be used when we want to place a block level element like <img> within line(s) of text. We shouldn't use inline placement for making the pages main layout. The element with display: inline-block also takes effect from properties like font-size and line-height of parent element. This will decrease the accuracy of page layout.
You would better get in the habit of using float instead of inline-block when making the page main layout.

How to make IE 11 wrap flexbox items when the flex container is inside a floating element?

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.

How to resolve flexbox formatting differences bewtween Firefox and Chrome

I want to change the order of sidebar elements using a user style sheet (no access to change html or scripts).
I'm using Stylish CSS to add display: flex; to the container div and order: to the children to be moved and in FF it works perfectly but in Chrome the same CSS formats very differently.
I have reduced the problem to a single line
If I apply the style .sidebar { display:flex; flex-direction: column; } to website http://www.tripadvisor.co.uk/ShowForum-g1-i12105-TripAdvisor_Support.html I get the results I expect and want with Firefox (31.0):
but with Chrome (36.0) the formatting is totally different:
Why are the two browsers handling the same page so differently?
What needs to be done to get Chrome to format the same as Chrome?
Adding an explicit height: makes some difference in Chrome but each child div is still truncated and since I don't know the number or size of the child elements it is not a practical solution
I found that one of the classes specified on the Sidebar child elements had for some, non obvious, reason a height:100%; property that FF appears to ignore for both flexbox and normal column formatting but which Chrome was using when the formatting the column for flexbox.
Changing to height:auto; for both the container and child elements seems to have resolved my problems and I am able to reorder the children as needed

Flexible div positioning

I have several divs on a page that all have the same width but different heights. They are all in one div, the #note1PreviewDiv. They all share the class .note, which has the following css code (among other):
.note{
width: 160px;
padding: 10px;
margin: 10px;
background: #e3f0ff;
float: left;
}
I thought with float: left; they would all automatically align so that they are well aligned among each other.
Here's a preview of what it looks like:
Current state http://posti.sh/img/ist.png
And here's what the positioning should be like:
Desired state http://posti.sh/img/soll.png
I think you get the idea. Somehow it seems to me the height of the leftmost div pushes the other divs in the second row to the right - but that's only guessing.
Thanks for your help!
Charles
You're not going to be able to do this easily with CSS only.
CSS3 has a new feature called column layout, but browser support is not great. IE9 and below don't support it.
See http://designshack.net/articles/css/masonry/ and the last example for CSS3 solution.
Have a look at these js / jQuery options for easier implementation and browser support:
masonry
isotope
vanilla masonry which doesn't need jQuery.
wookmark
The kind of lay out you want is really difficult (not possible?) without going for a column based approach and adding additional block elements to represent each column. This obviously won't work with a flexible number of columns if you want a dynamic layout based on screen size.
That said, you could always use JavaScript to dynamically place elements into columns, and get it to match the screen size.
Is the height of the parent container given a fixed value? If it is, try setting the height of the parent container to auto, and the overlow propery to hidden.

Resources