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
Related
I have a form where all of the elements use the CSS flex property to handle mobile devices. The flex direction is "row" by default, but I have one element on the page that needs to be forced to "column".
I can manually change, the flex-direction in FF developer tools and it works fine (see image below). However, when I try to modify my CSS file to make the same change, it doesn't take effect.
I tried the CSS below, but it didn't work.
#field_2_14 #content .page .gform_wrapper ul li {
flex-direction:column;
}
What am I doing wrong with my CSS file?
flex-direction requires display:flex.
Note that you can see a hint by pressing the i icon in the inspector
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
Can anyone explain this behavior in FF?
Fiddle: http://jsfiddle.net/4mrt8wq3/
<style>
.b { display: inline-block; }
#a { display: block; }
</style>
<div class="b">
<label>xxxxxxxxxx</label>
<input type="text" id="a"/>
</div>
<div class="b">
<label>xxxxxxxxxx</label>
<div> / </div>
</div>
Only in firefox, the first div is positioned one line lower than the second. It works correctly in Chrome and IE (at least IE11). It's as if the block element within the inline-block is wrapping below the second element for some reason.
Using overflow: hidden on the first div fixes the problem, but the second div is then positioned slightly oddly with about 4 or 5 pixels of margin above it. Placing overflow-hidden on both causes it to render correctly.
I am not looking for a solution to the problem, as I've already found one, but I'm at a loss of explaining the behavior... Can anyone explain WHY it's doing this?
Yes, interesting question. First we need understand that the default vertical alignment of inline-block elements is baseline, and the baseline of each such element is the baseline of the last line box in them.
In the second div with class "b", the inner div itself contains a line box to hold the '/' character. That then provides the baseline for the second div with class "b".
That baseline must align level with the baseline of the first div with class "b". The question becomes: where is the baseline of the last line box in that div?
By making the input element itself display:block, Firefox¹ takes the view that the input element is "replaced", it's contents are opaque to CSS, therefore no line box is ever created by the input element. So the last line of the first div with class "b" is the one containing the label, and that is aligned level with the line of the '/' character.
Chrome takes a different view. Chrome treats the input element as having an internal structure visible to CSS, so the innards of the element form a line box, whose baseline then becomes the baseline of the first div with class "b", and it is that which aligned level with the '/' character.
When you add `overflow:hidden', it affects the baseline of the inline-blocks such that their baselines cease to be the baseline of their last contained line box, and becomes the bottom margin edge of the element.
Which behaviour is correct is unclear. It depends on history and the somewhat adulterated notion of replaced elements. In the early days of browsers, the rendering of some elements was delegated to external systems, either the underlying operating system or a plug-in. In particular, this was true of the input element, where rendering was done by O/S calls. The O/S had no notion of CSS, so rules had to be defined to allow the effectively black boxes to interact with the rest of the page. Such elements were classified as "replaced" elements.
Note the way this is defined. There is no official list of elements that are replaced elements, an element is a replaced element if the browser chooses to delegate its rendering to a system outside the CSS world, so in theory you could have two browsers, one delegating the rendering of an element and one natively rendering it, and from the CSS rules get quite different interactions.
As browsers progressed, they stopped delegating their rendering of the input element and rendered it themselves, in the process making the renderings CSS aware. This causes a problem because extant web pages, which assume that the input elements will be rendered using the replaced elements' rules, can become unusable. If a browser allowed that to happen, it would lose market share. So for the most part, to avoid this, the browsers implement those elements' layouts to interact with the page as if they were replaced elements, even though in reality they are not.
How far they go in this respect is not well specified. The HTML5 spec does not recognise the form controls as replaced elements, and suggests that they be rendered as inline-block, which would make Chrome's behaviour correct, but there are many ways in which all the browsers including Chrome simply don't behave that way. From a backward compatibility perspective with old web content, the Firefox behaviour is more reliable.
Until the layout of form controls is specified much more tightly than is the case currently, it is impossible to conclusively say which behaviour is correct.
¹For me, IE11 behaves like Firefox. Opera 28 (blink engine like Chrome) behaves like Chrome. Opera 12 (presto engine) behaves like Firefox.
Your problem is that per spec setting overflow:hidden changes the baseline position of an inline-block. Firefox implements what the spec says. Chrome does not.
Solution:
<style>
.b { display: inline-block;
vertical-align: top; /*add this line */
}
#a { display: block; }
</style>
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.
I'm trying to create a site which uses laterally-stacked "blades" of content. The element containing them is moved laterally inside a div with overflow-x: hidden to create the desired sidescrolling effect. This seems to be working fine: The element containing the "blades" is set to display: table; width: 100%; table-layout: fixed and each blade is styled as follows: display: table-cell; width: 601px; border-right: 1px solid white; padding: 10px. Finally, the nav element has width 621px, with no horizontal padding or margins.
It all seems simple enough, but I'm getting a very odd cross-browser bug: Firefox and IE9 agree on how the page looks, but Chrome has a different opinion. I've figured out what Chrome is doing, but I haven't been able to figure out why it's doing it.
The doctype's set and everything else seems to be working fine. Except for background-colors, the rules above are all I've defined in the stylesheet, and there are no inline styles. Here are some screenshots which illustrate the problem behavior.
Here's the page in Firefox - as desired, the right edge of the navigation bar aligns with the right edge of the content box.
Same in IE9.
In Chrome, the padding is subtracted from the width, creating the overhang shown above. I never set border-box anywhere in the stylesheet, nor do I see it in the computed rules in Chrome - it just says that the width is 581px, whereas it's 601px in the other two browsers.
[Note: I saw that there were other posts on padding issues, but none where Firefox and IE9 agreed and Chrome did something different.]
Edit Here's a JSFiddle link: http://jsfiddle.net/aCeAw/
This is just a bug in Chrome. When it computes column widths for table-layout: fixed, it incorrectly ignores cell padding. See discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=652941 complete with spec quotes, and the almost-5-year-old WebKit bug report at https://bugs.webkit.org/show_bug.cgi?id=13339.
You may be able to work around this by using width styles on display: table-column elements, as discussed in the Mozilla bug report above. Alternately, you could add a first row with 0 height and no paddings, but the cell widths you want... I realize both of those mess with the actual site markup, which may not be an option in your case, of course.