box-orient in both direction? - html

What I am trying to do here is to make the <div>s (9 in my demo) to arrange like δΊ• (a 3x3 grid). My approach is to use the flexible box layout to make them spread evenly across the whole area.
<div id="container">
<div>1</div>
...
<div>9</div>
</div>
#container {
display: -webkit-box;
-webkit-box-align: stretch;
-webkit-box-orient: horizontal;
width: 300px;
height: 300px;
}
#container > div {
-webkit-box-flex: 1;
border: 1px solid black;
height: 50px;
}
However, this will make them line up in a single axis. I can change the orientation to vertical or horizontal, but not both. What is a better (and working) way to achieve this with only CSS? The float: left trick won't work here because the size of the container will vary.

You're actually looking at the wrong specification. The 2009 specification is being phased out in favor of the CR draft from Sept. 2012. To make a 3x3 grid with flexbox, you need to enable wrapping. The property from the 2009 draft for that was called box-lines, but the last remaining browser that follows that spec (Firefox) never implemented it.
http://jsfiddle.net/aUSWE/1/ (prefixes not included)
#container {
display: flex;
flex-flow: row wrap;
width: 300px;
height: 300px;
border: 1px solid black;
resize: both;
overflow:auto;
}
#container > div {
flex: 1 1 33%;
border: 1px solid black;
box-sizing: border-box;
}

http://www.w3.org/TR/2011/WD-css3-flexbox-20110322/#flex-order
It seems to me like the w3 standard for flexbox explicitly requires them to be either horizontal (LR/RL) or vertical (TB/BT), so I don't believe you can explicitly call for a 3x3 grid. As noted in the comments, the simplest solution seems to be three vertical flexbox divs with 3 horizontal flexbox divs inside of them (or the inverse). Unnecessary divs, indeed, but what else is CSS about? :)
You might look into grid-layout (http://www.w3.org/TR/2011/WD-css3-grid-layout-20110407/ ) since that seems like it's the grid cousin of flexbox. (Of course, that would be if you're designing solely for IE 10... http://caniuse.com/css-grid )

Related

Vertically center a textbox in a right-aligned div

One of the solutions I learned is to set the display of the parent div element to table-cell and use the vertical-align property.
While this works, in my case I also need the parent div to float right, but it breaks the table-cell trick and the whole thing does not work now.
So my question is simple: Why exactly is this happening, and more importantly, how can I achieve the effect I want?
div {
/* float: right; uncomment this will make this not working */
display: table-cell;
vertical-align: middle;
height: 60px;
border: 1px solid red;
}
<div>
<input>
</div>
Corresponding JSFiddle
CSS3 provides flexbox. All you need is this:
body {
display: flex; /* create flex container */
justify-content: flex-end; /* align child to right edge */
}
div {
display: flex; /* create nested flex container */
align-items: center; /* center child vertically */
height: 60px;
border: 1px solid red;
}
<div>
<input>
</div>
Benefits of flexbox:
minimal code; very efficient
centering, both vertically and horizontally, is simple and easy
equal height columns are simple and easy
multiple options for aligning flex elements
it's responsive
unlike floats and tables, which offer limited layout capacity because they were never intended for building layouts, flexbox is a modern (CSS3) technique with a broad range of options.
To learn more about flexbox visit:
Methods for Aligning Flex Items
Using CSS flexible boxes ~ MDN
A Complete Guide to Flexbox ~ CSS-Tricks
What the Flexbox?! ~ YouTube video tutorial
Browser support:
Flexbox is supported by all major browsers, except IE 8 & 9. Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes. For a quick way to add all the prefixes you need, use Autoprefixer. More details in this answer.
Wrap everything with a div set to float:right.
updated your fiddle with few tweaks. hope this works for you.
Please check http://jsfiddle.net/53ALd/3780/
html :
<div >
<input class="form-control" id="txtWOFastNavigation">
</div>
css :
div {
float: right;
height: 160px;
border: 1px solid #000;
position: relative;
background: red;
width: 104px;
}
div .form-control{
width: 100px;
position: absolute;
top: 50%;
transform: translateY(-50%);
}

How does a flexbox expand to it's child on overflow?

I have a flexbox layout.
The html is as follows:
<div class="grid">
<div class="row">
<div class="column">Content</div>
<div class="column">Content2</div>
<div class="column">Content2</div>
</div>
<div class="row">
<div class="column">Content</div>
<div class="column">Content2</div>
<div class="column">Content2</div>
</div>
</div>
and the css:
.grid {
overflow: auto;
width: 500px;
height: 400px;
background-color: #eee;
display: flex;
flex-direction: column;
}
.row {
background-color: #ddd;
align-items: stretch;
display: flex;
border: 2px solid black;
}
.column {
flex: 1 0 20em;
padding: 0.2em;
border: 2px solid lightblue;
/*background-color: hsla(0, 100%, 80%, 50%);*/
}
(see https://jsfiddle.net/bz71qptu/1/)
In the previous code, the .box element does not expand to the width of its children. How do I make it do this?
Edit
I have added an example of what I am hoping to achieve visually to the jsfiddle
Edit 2
I needed to change the question slightly to fit my particular issue. The parent element is aligned with flex-direction: column which means that using min-width doesn't seem to work. The min-width solution would be perfect without this.
Edit 3
I'm very thankful to everyone for helping, but I'm not sure I've exactly captured the behaviour I wanted to in my example, and even with all the advice I've been given I can't seem to make it do what I want. Here is a much better jsfiddle, if you look at this I've put borders up to show where everything is. I've read through the answers to see if I can adapt them to my situation, but I can't quite see it. I apologise if this fiddle is already answered.
Revised Answer
Your revised question changes the flex-direction from row to column.
With this adjustment, the flex property applied to .box is no longer relevant for your purposes, as it now handles vertical sizing. In other words, with column the flex property controls height not width.
As I mentioned in the comments, however, adding overflow: auto to .box seems to work perfectly (tested in Chrome, FF and IE11).
DEMO
You mentioned in your comments that it breaks the layout engine. The layout broke for me, as well in jsFiddle. Just hit [RUN] it again.
Ever since jsFiddle launched their upgrade a few days/weeks(?) ago it's been causing some confusion, as it now caches code. You may need to clear jsFiddle cookies (go to chrome://settings/cookies in your browser) or run revised code again after loading.
Original Answser
Instead of content for the flex-basis value, try auto or 0.
The content value isn't supported yet.
In fact, maybe simply flex: 1 will work for you.
See here:
CSS-Tricks ~ Common Values for flex
W3C Flexbox Spec ~ Common Values for flex
class .box is a flexbox container and a flexed child of class
.container
display: flex makes it act as a flexbox container
flex: 1 0 auto defines how it behaves as a child (of .container)
class .element is a flexed child of class .box
display: flex makes .element act as a flexbox container and yields no effect in your fidde (only when .element has children)
flex: 1 0 auto defines how it behaves as a child (of .box)
As you have not defined any sizes but 1000em for class .element, overflow: auto for class .container and flex-shrink: 0 (in flex: 1 0 auto) for both class .box and .element all elements react on the defined 1000em and can only grow to 1000em.
Change both flex: 1 0 auto to flex: 1 (defaults to flex: 1 1 auto) and your question has been answered!
Tiny update: .element change to flex: 1; min-width: 1000em
Fiddle

Layout with two equal height columns and one column has two rows

I am developing a forum theme at the moment, and am trying to figure out how to do the last bits, the posts. Example of what I'd like to make:
So the key things to keep in mind here is how User Info and Post Content have different colors, as well as the Post Description in the grid is in the same column as the Post Content.
Using a simple div setup doesn't work, as I need the User Info height to control the height of Post Content and vice versa. Having a wrapper element with the background color of User Info would work, but only if the Post Content is taller than User Info.
I am really just looking for brainstorming here. What would be the best way to go about doing this?
I created a draft of what the final result should look like here:
It should be fine with the code you have provided altered slightly, but I have some questions.
1) You commented the description has a set height? Does it need to? Worst case scenario I just adjust this height in media queries.
2) I probably need to have some columns within Post description too. As you see in my draft there's a left container with the timestamp (let's call that desc-meta) of the post, and to the right there's a permalink with ID (let's call that desc-ID). There's also a set of post options (Edit, report etc.) between the two (let's call that desc-edit), but aligned to the right side of the description. From my brief understanding of flex I can't figure out how to always keep the desc-meta and desc-ID on the same row, while desc-meta can be moved down if needed on smaller screens.
This layout can be achieved with CSS flexbox.
For both columns to have equal height we can use the align-items property, which controls space distribution among flex items on the cross-axis.
The default value is stretch, which enables items to extend the full length of the container.
.container-outer { align-items: stretch; }
We can also use the flex-grow property to control how free space is distributed among flex items in the main-axis.
.post-content { flex-grow: 1; }
The code below renders this (with borders only for demo purposes):
.container-outer {
display: flex;
align-items: stretch; /* tells boxes to stretch vertically (default value) */
width: 75%;
min-height: 250px;
border: 5px solid mistyrose;
}
.user-info {
display: flex; /* nested flexbox, to enable flex properties */
flex-direction: column;
justify-content: center;
align-items: center;
width: 25%;
border: 3px solid red;
font-family: verdana;
font-weight: bold;
font-size: 2em;
color: red;
box-sizing: border-box;
overflow: auto;
}
.container-inner {
display: flex; /* nested flexbox */
flex-direction: column;
width: 100%;
border: 3px dashed black;
overflow: auto;
}
.post-description {
display: flex; /* nested flexbox */
justify-content: center;
align-items: center;
height: 50px; /* fixed height */
border: 3px solid green;
font-family: verdana;
font-weight: bold;
font-size: 1.5em;
color: green;
box-sizing: border-box;
overflow: auto;
}
.post-content {
display: flex; /* nested flexbox */
justify-content: center;
align-items: center;
flex-grow: 1; /* box takes all available space (stretch, basically) */
border: 3px solid blue;
font-family: verdana;
font-weight: bold;
font-size: 2em;
color: blue;
box-sizing: border-box;
overflow: auto;
}
<article class="container-outer">
<section class="user-info">USER<br>INFO</section>
<div class="container-inner">
<section class="post-description">POST DESCRIPTION</section>
<section class="post-content">POST CONTENT</section>
</div><!-- end .container-inner -->
</article><!-- end .container-outer -->
jsFiddle
Regardless of how much or how little content is placed in USER INFO or POST CONTENT, both columns will remain equal height.
The container is given a minimum height (min-height: 250px;) to ensure it doesn't get too small if there is no content in either box.
flex-grow is only applied to POST CONTENT because USER INFO already expands full height by inheriting height from the container, and POST DESCRIPTION has a fixed height, so it won't expand.
Browser support: Flexbox is supported by all major browsers, except IE < 10. Some recent browser versions, such as Safari 8 and IE10, require vendor prefixes. For a quick way to add prefixes use Autoprefixer. More details in this answer.
My initial thoughts would be to do something like this:
<div class="one">
</div>
<div class="container">
<div class="two">
</div>
<div class="three">
</div>
</div>
And then give the left div a display of inline-block and the right container of inline-block, and the inner divs remain block.
.one {
display: inline-block;
}
.container {
display: inline-block;
}
I would use display: table with the corresponding rows/cells. See this http://jsfiddle.net/ycsmo9vg/ it should be easy extend this for your needs
notice how in the second cell, I have 2 divs, 1 has class row and the second div is plain (no class needed). This is up to you. Since a div is a block level element it will automatically take a row. Though I'd say keep it consistent and have a class of row wherever you have a row

Extremely simple flexbox layout, with overflow: hidden -- vertical mis-alignment in Firefox

I'm trying to put two flex items side by side, baseline-aligned (simple enough!), but with some small constraints: (1) overflow: hidden on both; (2) some padding-top on the second flex item. Here's the HTML:
<div class="outer">
<div class="inner one">Hello</div>
<div class="inner two">Hello</div>
</div>
...and the CSS:
.outer {
display: flex;
align-items: baseline;
}
.inner {
width: 30px;
overflow: hidden;
}
.one {
background: red;
}
.two {
background: yellow;
padding-top: 40px;
}
While Chrome (v43) gets the layout right (or at least what one could expect), Firefox (v38) breaks it completely: open this fiddle in Firefox and you'll see.
Any workaround for correct vertical alignment? It's so simple I can't believe both major browsers don't offer the same result.
The workaround for this is fairly simple.
.outer {
display: flex;
align-items: flex-end;
}
Note using flex-end for an align property, and not baseline. Baseline is a complicated thing in flexbox as far as i can see. If you want to achieve proper results with baseline you should maybe fancy up that example of yours with some more typography.
About the overflow problem and why it acts like that im not really sure about. Still i hope you can workaround your issue like that.
I advise you on reading this great, so called "Complete Guide to Flexbox".
Greetings!

How to make children auto fit parent's width only with CSS?

I have a server-side component that generates a fluid layout "toolbar" using DIV without fixed width, generating many A inside it.
Then I need customize that layout to make all A tags auto fit to the parent width. But the number of children is variable and the parent's width isn't known (it auto fits itself to the window).
I made some tests with this Fiddle: http://jsfiddle.net/ErickPetru/6nSEj/1/
But I can't find a way to make it dynamic (uncomment the last A tag to see how it ins't working, lol).
I can't change the server-side sources to gerenate HTML with fixed width. And I really would like to solve it only with CSS if there is any way, even that with JavaScript I could achieve that result.
How can I make all the children auto-fit itself to the parent's width independently of the number of children?
You can use display: table-cell:
See: http://jsfiddle.net/6nSEj/12/ (or with 5 children)
This won't work in IE7 because that browser simply doesn't support display: table and friends.
div.parent {
..
width: 100%;
display: table;
table-layout: fixed;
}
div.parent a {
..
display: table-cell;
}
This is already a pretty old question. Although the answers given attended well at the time, nowadays the Flexible Box Layout offers the same result with much more simplicity, with good support in all modern browsers. I strongly recommend it!
/* Important parts */
.parent {
display: flex;
}
.parent a {
flex: 1;
}
/* Decoration */
.parent {
padding: 8px;
border: 1px solid #ccc;
background: #ededed;
}
.parent a {
line-height: 26px;
text-align: center;
text-decoration: none;
border: 1px solid #ccc;
background: #dbdbdb;
color: #111;
}
<div class="parent">
Some
Other
Any
</div>
<br>
<div class="parent">
Some
Other
Any
One More
Last
</div>
For now many use jQuery as a solution to this problem. All you need is one line. This is from your fiddle.
$("div.parent a").css("width", (($("div.parent").width() / $("div.parent a").length ) -2) + "px");