I have the following simple layout (with the exception that the textarea becomes a Code Mirror at runtime):
<div class="columns">
<div class="column is-paddingless" style="background: indigo;">
<textarea id="code-editor"></textarea>
</div>
<div class="column">
</div>
</div>
The problem is - the first column does not fill the vertical space of the page (below the tabs) - rather it just wraps the height of the textarea. For instance:
Is there a way to make the column fill the page?
Flexbox should work for you! For your reference I love this guide: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Setting up your .columns like this should do the trick:
.columns {
display: flex;
flex-direction: row; // this is default
align-items: stretch; // this will stretch the children vertically
}
Unsure how you have .column styled (ie height: 100%) but let me know if this does NOT work and I can troubleshoot further.
Give a class or id or just write inline style and do
min-height : XXvh;
Where xx is how VH you need.
According to MOzila devaloper
vh
Equal to 1% of the height of the viewport's initial containing block.
Related
I am trying to use an implicit CSS grid to generate a layout for the following basic HTML structure:
<div class='row'>
<textarea></textarea>
<div></div>
</div>
where the .row div is a CSS grid with an auto-flow set to column for automatically placing elements as columns:
.row {
display: grid;
grid-auto-flow: column;
}
I would expect, as with most elements, that the CSS grid would provide equal space to both the textarea and the div elements along the row. But instead, the layout looks like this:
The textarea takes up more space along the row than expected. When you try to resize the textarea, I see the following:
What seems to be happening here is the grid is adding additional space to the right of the textarea equal to the width of the div on the right. What I can't figure out is why this is happening, and why the elements don't initially have an equal width. What am I missing here?
I've created a simple JSFiddle for testing this behavior here.
To make them the same size you need to ask the grid to do that
grid-auto-columns:1fr;
You can stop the user resizing the textarea with resize:none
If you want to get this to work whilst letting the user resize, I couldn't find a css solution
I had an idea but I couldn't get it to work.
The gist was
have a set of [invisible] divs as a first row
have a function that can be called on an element of a grid to see if its offsetWidth is lesser to one of the hidden divs of the same column
if it is, manipulate the css from auto to setting the width explicitly to the textarea's for that column, then with some mix of repeat(x, 1fr) (pre-textarea columns) & repeat(auto-fill, 1fr) (post-textarea columns)
then attach this function to the resize (or mouseup) of the textarea
Alternatively, consider flex.
It will have the opposite problem; it wont force an element to be 1fr (and apply that unwanted padding), but I dont think you can ask it to be 1/<number in row> in size [in css only] either.
why the elements don't initially have an equal width. What am I missing here?
textarea has a width initially defined by cols which has a default value equal to 20
cols
The visible width of the text control, in average character widths. If it is specified, it must be a positive integer. If it is not specified, the default value is 20.
This width play a role in defining the initial width of the textarea. You can set a small value to make sure it behave almost the same as div.
.row {
display: grid;
grid-auto-flow: column;
}
.row > div {
border: 1px dotted;
}
<div class='row'>
<textarea cols=1></textarea>
<div></div>
</div>
You can still notice a small difference since the textarea is not having an initial width exactly equal to 0 and it also has some padding so its column will logically be a little bigger.
To avoid this and to also fix the resize issue better explicitely define the grid like below where you set the initial width of the textarea to be half the width of grid.
I don't know your real use case but I will consider the fact that your grid is full page width (I will also consider the default body margin)
.row {
display: grid;
grid-template-columns:auto 1fr;
}
.row > div {
border: 1px dotted;
}
textarea {
width:calc(50vw - 16px);
box-sizing:border-box;
}
<div class='row'>
<textarea ></textarea>
<div></div>
</div>
I have a centered div that contains a header, input, and button in a row. I would like to make the input field expand so that the total width of the contents of the div take up the entire width allotted to the div. Is there some CSS way to specify something like width: 100%-other_elems?
Is there some CSS way to specify something like width: 100%-other_elems?
Yes using flex-box. Flexbox part of the browser's layout engine to create dynamic and flexible boxes or divs. See the example below and try resizing. Refer to CSS trick's flexbox tutorial for a complete rundown of flexbox. It's a fantastic reference that I use it all the time.
CSS rundown:
display: flex on .some-container declares that any element with the class some-container will use flexbox.
flex: 1 on .expand declares that in the parent flexbox (i.e. some-container) this element should grow.
.some-container { display: flex; }
.expand { flex: 1; }
<div class="some-container">
<h1>some header</h1>
<input class="expand" type="text">
<button>some button</button>
</div>
i'm working on a layout and I can't figure out how to get these columns to be equal height, specifically the green areas when the text wraps. Can you help?
My html template, with more .category-containers inside...
<div class="flex-container">
<div class="category-container">
<a href="#" class="img-gallery-col medium-internal-page-static-image" style="background-image: url('http://placehold.it/800/800');">
</a>
<h4 class="text-center">Salads & Sides</h4>
</div>
</div>
My css for the flex-container is...
.flex-container {
width: 100%;
display: flex;
flex-wrap: wrap;
align-items: flex-start;
}
Here's a coden link if that helps http://codepen.io/johnsonjpj/pen/evopaV?editors=1100
EDIT: I have updated the pen and added a height to the category-container and also made it display: flex. Then I added flex-grow to the h4. How can I get it vertically center inside that green area?
You have no heights defined anywhere in your code. Therefore, there is no reason for your text blocks to have equal height. Their height is defined by the content, which is a default setting (height: auto).
You need to define a height somewhere in your layout, whether high up on the body element or on a container element closer to the text. You can then establish equal heights and use flex properties for vertical and horizontal alignment.
As you resize the page, there's points which all of the text boxes are on one line, and points where they're all on two lines (resize browser to wide/narrow).
Since you have this issue in a middle ground of sorts, I would recommend using CSS #media queries to change the height property of .category-container h4 to predetermined values which you know will look okay.
As far as I've been able to gather, if working with IE10 / IE11 I should be able to use the standardized flex terms.
I have a container div and 2 child divs.
The 2 child divs are not larger than 400px, so there should always be enough room for the justify-content: space-between.
I want the first child to be all the way at the top and the second child to be all the way at the bottom.
This works in Chrome and Firefox but not in IE, and I have no idea why.
Any comments and feedback are welcome.
<div style="display: flex; flex-direction: column; justify-content: space-between; min-height: 400px; background-color: lightyellow;">
<div style="background-color: red;">
<h2>Title (variable height)</h2>
<p>Summary (variable height)</p>
</div>
<div style="background-color: orange;">
<img src="http://avatarbox.net/avatars/img32/tv_test_card_avatar_picture_61484.jpg" />
</div>
</div>
https://jsfiddle.net/akxn68vm/
IE 10 & 11 have a number of issues with rendering flexbox properly.
Here's one: A flex container doesn't respect the min-height property in these browsers.
A simple solution is to make your flex container also a flex item.
Just add this to your code (no other changes necessary):
body {
display: flex;
flex-direction: column;
}
revised fiddle
More info: https://github.com/philipwalton/flexbugs#flexbug-3
According to this bug IE11 doesn't render the items correctly when using min-height in flexbox.
It seems like the problem was solved in Edge, but IE10-11 will not work.
This is a bug in IE10/11. You can find the information at https://github.com/philipwalton/flexbugs#flexbug-3
To fix this bug in IE10/11, add a wrapper element around the flex container that is itself a flex container. In your example, you can add display flex to body tag. And add width 100% style in the container div
When using css flexbox the three main browsers appear to behave entirely differently in certain areas.
In this case I am trying to create a grid of images:
<div class="container">
<div class="photo"></div>
<div class="photo"></div>
<div class="photo"></div>
<div class="photo"></div>
<div class="photo"></div>
<div class="photo"></div>
</div>
.container {
display:inline-flex;
flex-flow : column wrap;
align-content : flex-start;
height : 100%;
}
In this example I need a container, itself containing several div elements set up to flow from top to bottom and wrapping when they reach the bottom. Ultimately providing me with columns of photos.
However I need the container to expand horizontally to accommodate the wrapped elements:
Here is a quick jsFiddle to demonstrate.
The behaviour is as follows:
IE 11 - Correct, the container stretches horizontally to wrap each column of wrapped elements
Firefox - The container only wraps the first column of elements, with the rest overflow out.
Chrome - The container always stretches to fill the width of its parent, whatever that may be.
In this instance I would like to achieve the behaviour of IE11 in the other two browsers. Therefore my question is, how can I make a flexbox container expand horizontally to match its column wrap contents.
Thanks in advance.
It's curious that most browsers haven't implemented column flex containers correctly, but the support for writing modes is reasonably good.
Therefore, you can use a row flex container with a vertical writing mode. This will swap the block direction with the inline direction, and thus the flex items will flow vertically. Then you only need to restore the horizontal writing mode inside the flex items.
.container {
display: inline-flex;
writing-mode: vertical-lr;
flex-wrap: wrap;
align-content: flex-start;
height: 350px;
background: blue;
}
.photo {
writing-mode: horizontal-tb;
width: 150px;
height: 100px;
background: red;
margin: 2px;
}
<div class="container">
<div class="photo">1</div>
<div class="photo">2</div>
<div class="photo">3</div>
<div class="photo">4</div>
<div class="photo">5</div>
<div class="photo">6</div>
<div class="photo">7</div>
<div class="photo">8</div>
<div class="photo">9</div>
</div>
This approach may have its own bugs in edge cases, especially if you mix advanced layout techniques like floats and nested flexboxs. But for most cases it seems to work properly.
The spec says that what you're doing should work, but it's implemented incorrectly in every major browser besides Internet Explorer / Edge, making multi-line inline-flex column layouts useless at present for most developers. Here's a Chromium bug report providing an example that is effectively identical to yours, and noting that it renders incorrectly in Chrome, Safari, and Firefox.
The argument from spec is more complicated than I'm able to understand, but the key point is that Flexible Box Layout Module Level 1 spec defines the intrinsic cross-size of a flex container (that is, the intrinsic height of a flex-direction: row flex container or the intrinsic width of a flex-direction: column flex container) in the section Flex Container Intrinsic Cross Size. There, it is stated:
For a multi-line flex container, the min-content/max-content cross size is the sum of the flex line cross sizes
That is, the intrinsic width of a flex-direction: column flex container should be the sum of the widths of its columns, as you'd expect. (There is more complexity than this, and I don't understand it all, but I believe the above to be broadly true.) However, Chrome, Firefox, and Safari all calculate this width incorrectly; setting width: min-content or width: max-content on a column wrap flex box in Chrome, you can clearly see that the width is set to the width of the widest single element.
A silly Chrome-specific workaround exists, but is probably best avoided. Until the bug is fixed, this part of the Flexbox model simply doesn't work as designed and there's no clean solution available.
It seems this issue cannot be solved only with CSS, so I propose you a JQuery solution
container width = position of the last child - position of the container + width of the last child (including margin)
Code :
$(document).ready(function() {
$('.container').each(function( index ) {
var lastChild = $(this).children().last();
var newWidth = lastChild.position().left - $(this).position().left + lastChild.outerWidth(true);
$(this).width(newWidth);
})
});
Demo :
http://jsfiddle.net/qzea320L/
You have a column layout distribution with a fixed height container.
When you set the flex-direction to column you define the Vertical axis as the main axis.
In flexbox that means it will fill up the available height and then create a new column.
In this JSBIN I use javascript to change the container's height and, because of that, you will see the child items move.
PS: you shouldn't rely on IE behavior since their flex support is recent.
Another possible approach:
.container {
column-count: 2; /*or whatever */
}
.container > div {
display: inline-block;
}
https://developer.mozilla.org/en-US/docs/Web/CSS/column-count
You may also need to adjust margin-top of .container > div:first-child if they don't align to the top.