inline flex container width not growing - html

Consider the following layout:
<div class="div">
<span class="span1">test</span>
<span class="span2">test test test test test</span>
</div>
and the css:
.div{
display:inline-flex;
background-color:lightgray;
}
.span1{
flex:0 0 100px;
}
.span2{
white-space:nowrap;
}
Why isn't the div stretched wide enough to cover the two spans? This happens in FF and Chrome. In IE 11/Edge it works (as I would expect it to work)
Here's the fiddle https://jsfiddle.net/p18h0jxt/
PS: It works everywhere if I used the following style:
.span1{
flex:0 0 auto;
width:100px;
}
Thanks.

From this SO answer:
Bug affecting all major browsers, except IE 11 & Edge:
Just as you said - apparently flex-basis is not respected in a nested flex container.
So your 100px flex-basis from flex: 0 0 100px; can't work properly (except ironically in IE 11 & Edge).
The workaround (also mentioned here) is to use width instead of flex-basis like so:
.div {
display: inline-flex;
background-color: lightgray;
}
.span1 {
width: 100px;
}
.span2 {
white-space: nowrap;
}
<div class="div">
<span class="span1">test</span>
<span class="span2">test test test test test</span>
</div>
You could use flex instead of inline-flex, but then your div will be rendered like a block element i.e. it will take up the full width that's available rather than being confined to your content.
I assume you are using inline-flex so that the background remains confined to the content.

The 100px you refer to in your current example refers to flex-basis not the element width.

Related

Merging width and flex properties for utility classes

On my site, I have a lot of utility classes that sets the width of elements. For almost all of the cases, the width property is perfect. The only issue is with flex box. For flex items, the width property does not set the width, and instead the flex property needs to be used. I tried combining the two into a single class like so:
.width-100 {
width: 100px !important;
flex: 0 0 100px !important;
}
Surprisingly enough, this worked on the few places I tried it. When an element is not using flexbox, its width gets set properly. When an element is using flexbox, the flex property makes sure it works as well. However, I am wondering if this is a good idea or not. Could there be possible bugs that I am simply not foreseeing right now?
You may fall into the case where you have min-width constraint and setting the width will make the flex item behave differently:
Here is a basic example:
.container {
display:flex;
margin:5px;
}
.container > img {
flex: 0 0 100px;
}
.container > span {
flex-grow:1;
background:red;
}
<div class="container">
<img src="https://i.picsum.photos/id/100/200/100.jpg">
<span></span>
</div>
<div class="container">
<img src="https://i.picsum.photos/id/100/200/100.jpg" style="width:100px">
<span></span>
</div>
In the first case the min-width constraint of the image will force it to have a width equal to 200px whereas in the second case you will have 100px. So it's wrong to assume that width isn't working in flexbox and you need flex-basis.Your code will indeed force the width to always be 100px but it's not the same as flex:0 0 100px when dealing with flex items:
By the way, your code can be simplified to only
.width-100 {
width: 100px !important;
flex-shrink: 0 !important;
}
This should produce the same output because flex-grow is by default 0 and flex-basis will consider the width you set.

CSS margin for Firefox

i have written a CSS margin for spacing between checkboxes. It works fine on chrome but not on Firefox.
here is CSS
.vehicle-types {
float:left;
width:100%;
margin: 6px 0;
.check-vehicle {
float:left;
width:100%;
.checkbox-btn {
width: auto;
display: inline-block;
margin-right: 20px;
float:left;
input {
float:left;
width:0 !important;
}
label {
margin:0 !important;
float:left;
}
}
}
}
is there any Firefox browser specific CSS?
(screenshots below)
Thanks in advance.
Chrome
Firefox
Okay, So I was writing this answer before you pushed your edited post. I am still to go through the code but as an alternate you can try this and see if it works or not
update: You have only shared css which is still very difficult to comprehend
An ideal solution to have everything on the same line would be to do.
.parent-div {
display: flex;
flex-direction: row;
justify-content: space-between
}
.child-div {
align-items: center;
display: flex;
flex-direction: row;
}
.create-box {
height: 30px;
width: 30px;
border: 1px solid black;
}
p {
margin-left: 5px;
}
<div class="parent-div">
<div class="child-div">
<span class="create-box"> </span>
<p> checkBox 1 </p>
</div>
<div class="child-div">
<span class="create-box"> </span>
<p> checkBox 1 </p>
</div>
<div class="child-div">
<span class="create-box"> </span>
<p> checkBox 1 </p>
</div>
</div>
In the above code I have used flex
flex-direction says that wether you want your divs to be stacked in row or columns i.e consider this somewhat equivalent to bootstrap class row . (if you have used bootstrap previously)
justify-content: space-between: space-between gives equal space between each square, but not between it and the container.
Note: You could have also used space-around
Space-around puts an equal cushion of space on either side of the square — which means the space between the outermost squares and the container is half as much as the space between two squares (each square contributing a non-overlapping equal amount of margin, thus doubling the space).
align-items: center; just align everything inside a div to centre across x-y axis
I found this article very useful when learning about flexboxes (might help you as well)
Look, the Firefox version adds that margin to the first child as well..
To avoid that, use:
.checkbox-btn:not(:first-child) {
...
margin-right: 20px;
...
}
I had this kind of problem also but with IE, for the next time you can use this code
it will only show on firefox, you can edit what you want and it will only show on firefox
#-moz-document url-prefix() {
//just write the code here
}
I know its not a problem from your code but if that was the case you could go to:
https://caniuse.com/
and check if it is your code

How to get div to collapse to content horizontally

I've been trying all day to get a container to display its content in the form of columns and expand towards the side instead of down when the number of children div's increases. I've tried everything from -vendor-box-orient layout to inline-block, nothing seems to be working. Here is the use case.
<div class="container">
<div class="row">
<div class="item">
</div>
<div class="item">
</div>
</div>
</div>
The .container is supposed to be overflow-x:scroll while .row is supposed to exceed .container if it has enough children to do so, instead of leaving overflow visible. So, how can I get .row to collapse to the width of its collective children as it would work if it was vertical?
Use case: JSfiddle
Looking at your fiddle demo, I found this answer by ThirtyDot (fiddle here) and adapted to do the same thing for right-flowing content to be right-fitted. I'm not entirely I got the scroll feature right, but let me know. This should work with elements other than UL and LI as well, but I haven't modified the markup to check yet.
Of course, this uses the weird and wonderful display: table- properties. Doing that, it was bound not to be supported by some legacy browser. See When Can I Use? for details on support.
I tested the following:
Firefox 13 - Works
Chrome Latest - Works
Opera 11.67 - Works
IE 8 - Works
IE 9 - Works
IE 7 - Does NOT Work
Safari - Untested
So if IE7 support is critical, this won't work for that browser at least. But unless I've misunderstood something, it works great in all the others.
Markup
<div>
<div class="super-scroller">
<ul class="horizontal-fit">
<li class="outer-block"><span class="inner-block"></span></li>
</ul>
</div>
</div>
CSS
.super-scroller {
border: 1px solid green;
overflow-x: scroll;
padding: 5px;
margin: 10px auto;
width: 90%;
}
.horizontal-fit {
display: table;
border: 1px solid blue;
}
.horizontal-fit .outer-block {
display: table-cell;
}
.horizontal-fit .inner-block {
display: block;
border: 1px solid red;
text-align: center;
margin: 5px;
width: 100px;
height: 100px;
}
http://jsfiddle.net/suJ3d/2/
Interactive demo:
http://jsfiddle.net/userdude/suJ3d/5/embedded/result/
Here's a working example. The red div's move inside the blue div.
The key was
overflow-x:scroll;
white-space: nowrap;
on the outer div and
display:inline-block;
on the inner div
http://jsfiddle.net/WTw2P/2/

CSS: Vertically align div when no fixed size of the div is known

How do I align a <div> which contains an image (or flash) vertically with CSS. Height and width are dynamic.
This is a pure CSS2 solution for horizontally and vertically centering without known sizes of either container nor child. No hacks are involved. I discovered it for this answer and I also demonstrated it in this answer.
The solution is based on vertical-align: middle in conjunction with line-height: 0, which parent has a fixed line-height.
The HTML:
<span id="center">
<span id="wrap">
<img src="http://lorempixum.com/300/250/abstract" alt="" />
</span>
</span>
And the CSS:
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
overflow: hidden;
}
#center {
position: relative;
display: block;
top: 50%;
margin-top: -1000px;
height: 2000px;
text-align: center;
line-height: 2000px;
}
#wrap {
line-height: 0;
}
#wrap img {
vertical-align: middle;
}
Tested on Win7 in IE8, IE9, Opera 11.51, Safari 5.0.5, FF 6.0, Chrome 13.0.
The only caveat is IE7, for which the two innermost elements have to declared at one line, as demonstrated in this fiddle:
<span id="center">
<span id="wrap"><img src="http://lorempixum.com/300/250/abstract" alt="" /></span>
</span>
Note that the span's are also required for IE7. In every other browser, the span's may be div's.
You can do this by using inline-blocks, one with height: 100% (and same heights for HTML and BODY) and vertical-align: middle.
Example 1: http://jsfiddle.net/kizu/TQX9b/ (a lot of content, so it's full width)
Example 2: http://jsfiddle.net/kizu/TQX9b/2/ (an image with any size)
In this example I use spans, so It would work in IE without hacks, if you'd like to use divs, don't forget to add in Conditional Comments for IE .helper, .content { display: inline; zoom: 1; }, so inline-blocks would work for block elements.
In addition to the other answers here, the CSS3 flexible box model will, amongst other things, allow you to achieve this.
You only need a single container element. Everything inside it will be laid out according to the flexible box model rules.
<div class="container">
<img src="/logo.png"/>
</div>
The CSS is pretty simple, actually:
.container {
display: box;
box-orient: horizontal;
box-pack: center;
box-align: center;
}
I've omitted vendor-prefixed rules for brevity.
Here's a demo in which the img is always in the centre of the page: http://jsfiddle.net/zn8bm/
Note that Flexbox is a fledgling specification, and is only currently implemented in Safari, Chrome and Firefox 4+.
I would recommend this solution by Bruno: http://www.brunildo.org/test/img_center.html
However, I ran into a problem w/ his solution w/r/t webkit. It appears that webkit was rendering a small space at the top of the div if the empty span was allowed to be there. So, for my solution I only add the empty span if I detect the browser to be IE (If someone figures out how to get rid of the space, let me know!) So, my solution ends up being:
HTML:
<div class="outerdiv">
<img src="..." />
</div>
CSS:
.outerdiv {
display: table-cell;
width: 200px;
height: 150px;
text-align: center;
vertical-align: middle;
}
.ie_vertical_align * {
vertical-align: middle;
}
.ie_vertical_align span {
display: inline-block;
height: 150px;
width: 0;
}
And if I detect the browser to be IE I add an empty span element before the img tag and a css style so it looks like:
<div class="outerdiv ie_vertical_align">
<span></span>
<img src="..." />
</div>
Here's a JSFiddle with this code.
Dušan Janovský, Czech web developer, has published a cross-browser solution for this some time ago. Read http://www.jakpsatweb.cz/css/css-vertical-center-solution.html
If you don't care about IE7 and below, you don't have to use multiple nested divs. If you have a div that you want to align vertically, that div is within some container (even if the container is your <body>). Therefore, you can specify display: table-cell and vertical-align: middle on the container, and then your div will be vertically centered.
However, if you do care about IE7 and below, you will need an additional container to make it work (yes, via a hack).
Take a look at this fiddle. It displays correctly in IE6-9 and other major browsers. #container2 is present solely for IE7 and below, so if you don't care about them, you can remove it as well as the IE-specific conditional styles.
Set the image as background of the div and align it center
try the 50% padding trick:
<html>
<body style="width:50%; height: 50%;">
<div style="display:block; display:inline-block; layout-grid:line;
text-align:center; vertical-align:bottom;
padding: 50% 0 50% 0">test</div>
</body>
</html>
This is possible if you know the height of the image or flash object to be centered. You don't need to know the container's height/width, but you do need to know the contained height/width.
It's possible using float, clear and negative margins. Example: www.laurenackley.com homepage.
html
<div id='container'><!-- container can be BODY -->
<div id='vertical-center'> </div>
<div id='contained-with-known-height'>
<p>stuff</p>
</div>
</div>
css
#vertical-center{
height:50%;
width:1px;
float:left;
margin-bottom:-50px;/** 1/2 of inner div's known height **/
}
#contained-with-known-height{
height:100px;
clear:left;
margin:0 auto;/** horizontal center **/
width:700px;
text-align:left;
}
#container{/** or body **/
text-align:center;
/** width and height unknown **/
}
If you don't know the inner elements width/height. You are out of luck with <div>. BUT -- table cells (<td>) do support vertical-align:middle; If you can't get it done with the div stuff above, go with a table inside the container, and put the div you are centering inside a td with vertical-align middle.

How can I expand floated child div's height to parent's height?

I have the page structure as:
<div class="parent">
<div class="child-left floatLeft">
</div>
<div class="child-right floatLeft">
</div>
</div>
Now, the child-left DIV will have more content, so the parent DIV's height increases as per the child DIV.
But the problem is child-right height is not increasing. How can I make its height as equal to it's parent?
For the parent element, add the following properties:
.parent {
overflow: hidden;
position: relative;
width: 100%;
}
then for .child-right these:
.child-right {
background:green;
height: 100%;
width: 50%;
position: absolute;
right: 0;
top: 0;
}
Find more detailed results with CSS examples here and more information about equal height columns here.
A common solution to this problem uses absolute positioning or cropped floats, but these are tricky in that they require extensive tuning if your columns change in number+size, and that you need to make sure your "main" column is always the longest. Instead, I'd suggest you use one of three more robust solutions:
display: flex: by far the simplest & best solution and very flexible - but unsupported by IE9 and older.
table or display: table: very simple, very compatible (pretty much every browser ever), quite flexible.
display: inline-block; width:50% with a negative margin hack: quite simple, but column-bottom borders are a little tricky.
1. display:flex
This is really simple, and it's easy to adapt to more complex or more detailed layouts - but flexbox is only supported by IE10 or later (in addition to other modern browsers).
Example: http://output.jsbin.com/hetunujuma/1
Relevant html:
<div class="parent"><div>column 1</div><div>column 2</div></div>
Relevant css:
.parent { display: -ms-flex; display: -webkit-flex; display: flex; }
.parent>div { flex:1; }
Flexbox has support for a lot more options, but to simply have any number of columns the above suffices!
2.<table> or display: table
A simple & extremely compatible way to do this is to use a table - I'd recommend you try that first if you need old-IE support. You're dealing with columns; divs + floats simply aren't the best way to do that (not to mention the fact that multiple levels of nested divs just to hack around css limitations is hardly more "semantic" than just using a simple table). If you do not wish to use the table element, consider css display: table (unsupported by IE7 and older).
Example: http://jsfiddle.net/emn13/7FFp3/
Relevant html: (but consider using a plain <table> instead)
<div class="parent"><div>column 1</div><div>column 2</div></div>
Relevant css:
.parent { display: table; }
.parent > div {display: table-cell; width:50%; }
/*omit width:50% for auto-scaled column widths*/
This approach is far more robust than using overflow:hidden with floats. You can add pretty much any number of columns; you can have them auto-scale if you want; and you retain compatibility with ancient browsers. Unlike the float solution requires, you also don't need to know beforehand which column is longest; the height scales just fine.
KISS: don't use float hacks unless you specifically need to. If IE7 is an issue, I'd still pick a plain table with semantic columns over a hard-to-maintain, less flexible trick-CSS solution any day.
By the way, if you need your layout to be responsive (e.g. no columns on small mobile phones) you can use a #media query to fall back to plain block layout for small screen widths - this works whether you use <table> or any other display: table element.
3. display:inline block with a negative margin hack.
Another alternative is to use display:inline block.
Example: http://jsbin.com/ovuqes/2/edit
Relevant html: (the absence of spaces between the div tags is significant!)
<div class="parent"><div><div>column 1</div></div><div><div>column 2</div></div></div>
Relevant css:
.parent {
position: relative; width: 100%; white-space: nowrap; overflow: hidden;
}
.parent>div {
display:inline-block; width:50%; white-space:normal; vertical-align:top;
}
.parent>div>div {
padding-bottom: 32768px; margin-bottom: -32768px;
}
This is slightly tricky, and the negative margin means that the "true" bottom of the columns is obscured. This in turn means you can't position anything relative to the bottom of those columns because that's cut off by overflow: hidden. Note that in addition to inline-blocks, you can achieve a similar effect with floats.
TL;DR: use flexbox if you can ignore IE9 and older; otherwise try a (css) table. If neither of those options work for you, there are negative margin hacks, but these can cause weird display issues that are easy to miss during development, and there are layout limitations you need to be aware of.
For the parent:
display: flex;
For children:
align-items: stretch;
You should add some prefixes, check caniuse.
I found a lot of answers, but probably the best solution for me is
.parent {
overflow: hidden;
}
.parent .floatLeft {
# your other styles
float: left;
margin-bottom: -99999px;
padding-bottom: 99999px;
}
You can check other solutions here http://css-tricks.com/fluid-width-equal-height-columns/
Please set parent div to overflow: hidden
then in child divs you can set a large amount for padding-bottom. for example
padding-bottom: 5000px
then margin-bottom: -5000px
and then all child divs will be the height of the parent.
Of course this wont work if you are trying to put content in the parent div (outside of other divs that is)
.parent{
border: 1px solid black;
overflow: hidden;
height: auto;
}
.child{
float: left;
padding-bottom: 1500px;
margin-bottom: -1500px;
}
.child1{
background: red;
padding-right: 10px;
}
.child2{
background: green;
padding-left: 10px;
}
<div class="parent">
<div class="child1 child">
One line text in child1
</div>
<div class="child2 child">
Three line text in child2<br />
Three line text in child2<br />
Three line text in child2
</div>
</div>
Example: http://jsfiddle.net/Tareqdhk/DAFEC/
Does the parent have a height? If you set the parents height like so.
div.parent { height: 300px };
Then you can make the child stretch to the full height like this.
div.child-right { height: 100% };
EDIT
Here is how you would do it using JavaScript.
CSS table display is ideal for this:
.parent {
display: table;
width: 100%;
}
.parent > div {
display: table-cell;
}
.child-left {
background: powderblue;
}
.child-right {
background: papayawhip;
}
<div class="parent">
<div class="child-left">Short</div>
<div class="child-right">Tall<br>Tall</div>
</div>
Original answer (assumed any column could be taller):
You're trying to make the parent's height dependent on the children's height and children's height dependent on parent's height. Won't compute. CSS Faux columns is the best solution. There's more than one way of doing that. I'd rather not use JavaScript.
I used this for a comment section:
.parent {
display: flex;
float: left;
border-top:2px solid black;
width:635px;
margin:10px 0px 0px 0px;
padding:0px 20px 0px 20px;
background-color: rgba(255,255,255,0.5);
}
.child-left {
align-items: stretch;
float: left;
width:135px;
padding:10px 10px 10px 0px;
height:inherit;
border-right:2px solid black;
}
.child-right {
align-items: stretch;
float: left;
width:468px;
padding:10px;
}
<div class="parent">
<div class="child-left">Short</div>
<div class="child-right">Tall<br>Tall</div>
</div>
You could float the child-right to the right, but in this case I've calculated the widths of each div precisely.
I have recently done this on my website using jQuery. The code calculates the height of the tallest div and sets the other divs to the same height. Here's the technique:
http://www.broken-links.com/2009/01/20/very-quick-equal-height-columns-in-jquery/
I don't believe height:100% will work, so if you don't explicitly know the div heights I don't think there is a pure CSS solution.
If you are aware of bootstrap you can do it easily by using 'flex' property.All you need to do is pass below css properties to parent div
.homepageSection {
overflow: hidden;
height: auto;
display: flex;
flex-flow: row;
}
where .homepageSection is my parent div.
Now add child div in your html as
<div class="abc col-md-6">
<div class="abc col-md-6">
where abc is my child div.You can check equality of height in both child div irrespective of border just by giving border to child div
<div class="parent" style="height:500px;">
<div class="child-left floatLeft" style="height:100%">
</div>
<div class="child-right floatLeft" style="height:100%">
</div>
</div>
I used inline style just to give idea.
I can see that the accepted answer uses position: absolute; instead of float: left. In case you want to use float: left with the following structure,
<div class="parent">
<div class="child-left floatLeft"></div>
<div class="child-right floatLeft"></div>
</div>
Give position: auto; to the parent so that it will contain its children height.
.parent {
position: auto;
}
.floatLeft {
float: left
}
I learned of this neat trick in an internship interview. The original question is how do you ensure the height of each top component in three columns have the same height that shows all the content available. Basically create a child component that is invisible that renders the maximum possible height.
<div class="parent">
<div class="assert-height invisible">
<!-- content -->
</div>
<div class="shown">
<!-- content -->
</div>
</div>