I'm having trouble trying to get a desired page layout to work by using HTML5/CSS3 only (without needing JavaScript).
The basic concepts are...
A page with a header and body (static).
The body has several "sections" which each have a header and body (static).
The sections flow from left-to-right (you scroll the page body horizontally to see the sections if they overflow).
The sections have a fluid height and width (height adjusts to the size of the page body, width adjusts based on the contents or a min of 300px).
The fields within the section body flow from top-to-bottom. When there is overflow, the fields overflowing should move to a new column and the section body should expand dynamically. The should not be broken apart if they overflow to a new column (the label and input should be moved together).
NOTE: I'm testing in IE11 currently but ultimately the solution should be functional in the latest Chrome/FF/IE/Safari versions.
I can't seem to get the section body to expand when the fields overflow into new columns while still retaining the column behavior.
HTML:
<div class="container">
<div class="header">Header</div>
<div class="body">
<div class="section">
<div class="sectionheader">Section 1</div>
<div class="sectionbody">
<div class="field">
<label>Field 1</label>
<input type="text" />
</div>
<!-- NOTE: repeat field element to create 5 or more fields... -->
</div>
</div>
<!-- NOTE: repeat section element to create more sections... -->
</div>
</div>
CSS:
* {
box-sizing: border-box;
-moz-box-sizing: border-box;
}
html, body, .container {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
background-color: gray;
overflow: hidden;
}
.header {
height: 150px;
background-color: red;
}
.body {
position: absolute;
top: 150px;
bottom: 0;
left: 0;
right: 0;
white-space: nowrap;
vertical-align: top;
padding: 40px;
overflow-x: auto;
overflow-y: hidden;
}
.section {
min-height: 200px;
height: 100%;
border: 2px solid red;
margin-right: 40px;
display: inline-block;
min-width: 300px;
position: relative;
vertical-align: top;
}
.sectionheader {
height: 40px;
color: white;
font-size: 20pt;
padding-left: 5px;
}
.sectionbody {
white-space: normal;
border: 2px solid blue;
padding-top: 10px;
color: white;
height: calc(100% - 40px);
column-count: auto;
-webkit-column-count: auto;
column-width: 320px;
-webkit-column-width: 320px;
column-fill: auto;
-webkit-column-fill: auto;
}
.field {
margin: 0 10px 10px 10px;
width: 300px;
display: inline-block;
}
.field label {
font-size: 12px;
line-height: 20px;
display: block;
}
.field input {
width: 100%;
font-size: 16px;
line-height: 20px;
height: 40px;
padding-left: 5px;
}
Here is the fiddle: http://jsfiddle.net/t7kQ4/7/
(drag the handle to adjust the height of the result pane to trigger the field overflow)
Does this help: http://jsfiddle.net/t7kQ4/10/
You need to remove the calc you are performing and allow it to be auto.
section {
height:auto;
}
.sectionbody {
height:auto;
}
Related
I have a textarea inside a div, and I wish for the text area height to match the height of the div container.
Currently, the width fits perfectly, however the textbox (which begins empty) only fills about 20% of the div height.
And when an ajax call grabs some text and populates the textarea, the textarea height remains at about 20% of the div and provides a scroll bar.
How can I alter my CSS to ensure that the textarea height always matches the height of its div container?
#answerBox {
width: 100%;
height: 100%;
box-sizing: border-box;
margin: 5px auto;
padding: 5px;
font-size: 10px;
text-align: left;
position: relative;
}
#answerBoxDiv {
width: 90%;
min-height: 50%;
margin: 5px auto;
border: 4px solid #00bfb6;
padding: 5px;
font-size: 10px;
text-align: left;
position: relative;
}
<div id="answerBoxDiv">
<textarea id="answerBox"></textarea>
</div>
You need to explicitly set a height of the parent container (whether that is in px or rem etc) - that way the height: 100% of the textarea will fill to the container.
The expand on text content cannot be done with simple css - you need js to determine the heaight of the content and adjust the parent container accordingly.
The only way tyou can keep height: 100% on the parent container is its ancestor has a height set (eg 100vh) - that way the browser can determine the height of each DOM element and size the text area accrodingly.
UPDATE - I have added a js function to automatiucally increae the height of the parent container on the input. (the textarea autoincreases in height since it is 100% of the parentThis will need massaging - but when you type into the textarea the height will auto expand.
function setHeight(element) {
const container = document.getElementById("answerBoxDiv");
const height = element.scrollHeight;
if(height > 100) {
container.style.height = (element.scrollHeight)+"px";
}
}
#answerBoxDiv {
width: 90%;
height: 100px; **// this is needed - but can be in px / rem / vh or other but NOT % unless its parent has its height set.**
margin: 5px auto;
border: 4px solid #00bfb6;
padding: 5px;
font-size: 10px;
text-align: left;
position: relative;
}
#answerBox {
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 5px;
font-size: 10px;
text-align: left;
position: relative;
resize: vertical;
overflow: hidden
}
<div id="answerBoxDiv">
<textarea id="answerBox" oninput="setHeight(this)"></textarea>
</div>
You can use the CSS height: 100%; property on the textarea element to make it fill the entire height of its parent container, the #answerBoxDiv. Additionally, you can remove the min-height property from the #answerBoxDiv to make sure the container's height is always equal to the height of its content.
Here's the updated CSS:
#answerBox {
width: 100%;
height: 100%;
box-sizing: border-box;
margin: 0;/*keep it zero*/
padding: 5px;
font-size: 10px;
text-align: left;
position: relative;
}
#answerBoxDiv {
width: 90%;
margin: 5px auto;
border: 4px solid #00bfb6;
padding: 0px;/*keep it zero*/
font-size: 10px;
text-align: left;
position: relative;
}
And the updated HTML:
<div id="answerBoxDiv">
<textarea id="answerBox"></textarea>
</div>
Percentage height does not work with a min-height parent, you would either need to give your parent a height or you could use flex:
html,
body {
height: 100%;
margin: 0;
}
#answerBox {
flex-grow:1;
width: 100%;
box-sizing: border-box;
margin: 5px auto;
padding: 5px;
font-size: 10px;
text-align: left;
position: relative;
}
#answerBoxDiv {
width: 90%;
min-height: 50%;
margin: 5px auto;
border: 4px solid #00bfb6;
padding: 5px;
font-size: 10px;
text-align: left;
position: relative;
display: flex;
flex-direction: column;
}
<div id="answerBoxDiv">
<textarea id="answerBox"></textarea>
</div>
You can try this
#answerBox {
height: 100%;
resize: none;
}
try keeping the min-height of the textarea as 100% or nearby or try using
object-fit: contain(or cover) on your text area
Give specific height for #answerBoxDiv parent div. So you will get appropriate height for this div.
<div class="parent-div" style="height: 100%;">
<div id="answerBoxDiv">
<textarea id="answerBox"></textarea>
</div>
</div>
#answerBox {
width: 100%;
height: 100%;
box-sizing: border-box;
margin: 0;
padding: 5px;
font-size: 10px;
text-align: left;
resize: none;
border: none;
}
#answerBoxDiv {
width: 90%;
min-height: 50%;
margin: 5px auto;
border: 4px solid #00bfb6;
padding: 0;
position: relative;
}
Why does block with text shift to the bottom? I know how to fix this issue (need to add "overflow: hidden" to the box), but I don't understand why it shift to the bottom, text inside the box is short, margins in browser-inspector are same as margins of example without text.
Example of the problem
HTML:
<div class="with-text">
<div class="box1">
SIMPLE TEXT
</div>
<div class="box2">
</div>
</div>
<div class="without-text">
<div class="box1">
</div>
<div class="box2">
</div>
</div>
CSS:
html, body {
font-size: 10px;
margin: 0;
height: 100%;
}
.box1 {
display: inline-block;
margin: 5px;
width: 50px;
height: 50px;
background: blue;
/* Fix the problem */
/* overflow: hidden; */
color: white;
}
.box2 {
display: inline-block;
margin: 5px;
width: 50px;
height: 50px;
background: red;
}
.with-text:before {
display: block;
content: "with-text";
text-transform: uppercase;
margin: 1rem;
}
.with-text {
box-sizing: border-box;
height: 50%;
border: 1px solid;
}
.without-text:before {
display: block;
content: "without text";
text-transform: uppercase;
margin: 1rem;
}
.without-text {
box-sizing: border-box;
height: 50%;
border: 2px solid black;
}
The problem is that by default vertical alignment of inline elements – baseline,
The text inside element affects it and pushes div to the bottom.
Use vertical-align: top to solve issue.
You can try to add vertical-align:
.box1 {
display: inline-block;
margin: 5px;
width: 50px;
height: 50px;
background: blue;
/* overflow: hidden; */
color: white;
vertical-align:top;
}
At the top level of my website layout are 4 div tags.
The first one is a full width header section, with css:
#header {
margin-top: 0px;
height: 70px;
border: 4px double rgb(255,255,255);
border-radius: 20px;
background: rgb(88,150,183) no-repeat fixed left top;
padding: 0px;
}
At the bottom is a full width footer:
#footer {
clear: both;
margin: 0px;
color:#cdcdcd;
padding: 10px;
text-align: center;
border: 4px double rgb(88,150,183);
border-radius: 20px;
}
On the left is my main menu section:
#categories {
float:left;
width:150px;
border: 4px double rgb(88,150,183);
border-radius: 20px;
}
All of those 3 elements work fine. They're in the right place and that doesn't change whatever screen resolution the user has on their monitor, or whether they view it on not maximum screen size.
My problem is with the main element of the page - where all the interesting stuff is. It's directly to the right of the menu div - or rather, it should be. My css is:
#main {
float:right;
min-height: 440px;
width: 80%;
margin-bottom: 20px;
padding:20px;
border: 4px double rgb(88,150,183);
border-radius: 20px;
}
width 80% works OK for most of my users, but for those with less resolution, the main element shifts below the menu, which is ghastly.
What I would ideally like is for the width set in the css #main to be something like (100% - 170px), thus leaving a nice margin between the menu and the main bit at all times and never pushing it below the menu. However, css standards don't fulfil that desire yet!
Could someone suggest how I amend my css to give me a nice clean page that's clean for all my users? Or do I need to go back to setting out my page using tables?
Using CSS3 flex
* { box-sizing: border-box; margin: 0; }
#parent{
display: flex;
}
#aside{
width: 170px; /* You, be fixed to 170 */
background: #1CEA6E;
padding: 24px;
}
#main{
flex: 1; /* You... fill the remaining space */
background: #C0FFEE;
padding: 24px;
}
<div id="parent">
<div id="aside">Aside</div>
<div id="main">Main</div>
</div>
Using CSS3 calc
width: calc(100% - 170px);
Example:
* { box-sizing: border-box; margin: 0; }
#aside {
background: #1CEA6E;
width: 170px;
float: left;
padding: 24px;
}
#main {
background: #C0FFEE;
width: calc(100% - 170px);
float: left;
padding: 24px;
}
<div id="aside">Aside</div>
<div id="main">Main</div>
Using float: left; and overflow
* { box-sizing: border-box; margin: 0; }
#aside{
width: 170px; /* You, be fixed to 170 */
float: left; /* and floated to the left */
padding: 24px;
background: #1CEA6E;
}
#main {
background: #C0FFEE;
padding: 24px;
overflow: auto; /* don't collapse spaces */
/* or you could use a .clearfix class (Google for it) */
}
<div id="aside">Aside</div>
<div id="main">Main</div>
Using style display: table;
* { box-sizing: border-box; margin: 0; }
#parent{
display: table;
border-collapse: collapse;
width: 100%;
}
#parent > div {
display: table-cell;
}
#aside{
width: 170px; /* You, be fixed to 170 */
background: #1CEA6E;
padding: 24px;
}
#main{
background: #C0FFEE;
padding: 24px;
}
<div id="parent">
<div id="aside">Aside</div>
<div id="main">Main</div>
</div>
Is this what you are looking for? You don't need any css3
Dont need any css3
.wrapper {
width: 800px;
height: 800px;
background-color: blue;
}
.content {
width: auto;
height: 100%;
background-color: yellow;
}
.menu {
width: 170px;
height: 100%;
float: left;
background-color: red;
}
<div class="wrapper">
<div class="menu">Menu</div>
<div class="content">
Aside
</div>
</div>
You can use 'calc' function supported by all modern browsers and IE9+, or switch to flexbox (supported by IE11+)
See this pen: https://codepen.io/neutrico/pen/MyXmxa
width: calc(100% - 170px);
Keep in mind that all borders matter unless you set 'box-sizing' to 'border-box' (or just remove these borders and apply them on child elements).
I am trying to make a file hierarchy in html/css and I can't get these labels or the divs they are in to expand to full width. They only expand to the width of the visible area but I want the width of what they are in. Here is the fiddle to see what I am talking about. The grey area needs to all line up on the right.
a = 3;
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
div.hierarchy {
position: relative;
overflow: auto;
border-right: 1px solid grey;
width: 150px;
left: 0;
top: 0;
bottom: 0;
height: 100%;
}
div.hierarchy label {
display: block;
min-width: 100%;
background: #eee;
white-space: nowrap;
}
div.directory {
padding-left: 20px;
width: 100%;
}
div.directory label {
border: 1px solid grey;
width: 100%;
cursor: pointer;
}
<div class="hierarchy">
<label>Hierarchy</label>
<div class="directory">
<label>src</label>
<div class="directory">
<div class="file"><label>test.txt</label></div>
<div class="file"><label>readme.txt</label></div>
<div class="file"><label>a really long filename.txt</label></div>
</div>
</div>
</div>
You need to change your div.directory CSS class as follows:
div.directory {
display:inline-block;
padding-left: 20px;
}
I made the following changes:
1) Added display:inline-block;
2) Removed the width:100%; rule.
Here is an example:
http://jsfiddle.net/nnd7jyj1/
(As a side note, it's generally bad practice in CSS to apply both a width and either a padding or margin rule to the same element. The reason for this is that some browsers interpret the width to include the padding/margin and some don't, which leads to inconsistent results)
Simply add display:inline-block; to div.directory
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
div.hierarchy {
position: relative;
overflow: auto;
border-right: 1px solid grey;
width: 150px;
left: 0;
top: 0;
bottom: 0;
height: 100%;
}
div.hierarchy label {
display: block;
min-width: 100%;
background: #eee;
white-space: nowrap;
}
div.directory {
padding-left: 20px;
/* width: 100%; */
/* added */
display: inline-block;
}
div.directory label {
border: 1px solid grey;
width: 100%;
cursor: pointer;
}
<div class="hierarchy">
<label>Hierarchy</label>
<div class="directory">
<label>src</label>
<div class="directory">
<div class="file">
<label>test.txt</label>
</div>
<div class="file">
<label>readme.txt</label>
</div>
<div class="file">
<label>a really long filename.txt</label>
</div>
</div>
</div>
</div>
Before you roll your eyes and move on, I know how to solve this problem by using a fixed height and absolution positioning with top: and bottom:, but I want to solve it without using fixed heights. I want to learn more about CSS so I'm trying to solve this a different way.
I have set up a typical navbar running across the top, and then a scrolling content div below.
However! How do I fit the bottom scrolling div container to the remaining space without using absolute coordinates? I can't do position: absolute, because then I'd need to know the height of the navbar to set "top:". And I can't do "bottom: 0" because I'd have to specify a height.
Here's the JS filddle:
http://jsfiddle.net/8dugffz4/1/
The class of interest is ".result". I currently have the height fixed, which I don't want.
Thanks, y'all.
PT
CSS:
* {
font-family: Helvetica, Sans;
border: 0px;
margin: 0px;
padding: 0px;
}
.navBar {
width: auto;
overflow: auto;
border-bottom: 1px solid #bbb;
}
.pageBar {
float: right;
}
.pager {
cursor: pointer;
float: left;
border: 1px solid #bbb;
width: 2em;
height: 2em;
line-height: 2em;
text-align: center;
margin: 5px;
margin-left: 0px;
background: #eee;
color: #bbb;
}
.pager:hover {
background: #777;
border: 1px solid black;
color: white;
}
.fliph {
-ms-transform:scale(-1,1); /* IE 9 */
-moz-transform:scale(-1,1); /* Firefox */
-webkit-transform:scale(-1,1); /* Safari and Chrome */
-o-transform:scale(-1,1); /* Opera */
}
.results {
background: gray;
width: 100%;
height: 200px;
overflow: scroll;
}
.line {
height: 10em;
line-height: 10em;
border: 1px solid red;
}
HTML:
<body>
<div class='navBar'>
<div class='pageBar'>
<div class='pager'>◁</div>
<div class='pager'>1</div>
<div class='pager fliph'>◁</div>
</div>
</div>
<div class='results'>
<div class='line'>Line1</div>
<div class='line'>Line2</div>
<div class='line'>Line3</div>
<div class='line'>Line4</div>
</div>
</body>
Here's a solution that uses display: table and can actually achieve fluid heights:
http://jsfiddle.net/8dugffz4/8/
And a minimalistic snippet in case you want to see specifically what I did:
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
#table {
display: table;
height: 100%;
width: 100%;
}
#table > div {
display: table-row;
}
#navbar {
height: 45px;
opacity: .5;
}
#navbar > div {
height: 100%;
background: black;
}
#results {
height: 100%;
}
#results > div {
height: 100%;
overflow: auto;
background: green;
}
<div id="table">
<div id="navbar">
<div></div>
</div>
<div id="results">
<div></div>
</div>
</div>
If you're just looking for an alternative to the position: absolute method, you could use the height: 100% method:
html, body { height: 100%; }
body { box-sizing: border-box; padding-top: 45px; }
.navBar { height: 45px; margin-top: -45px; }
.results { height: 100%; }
Like so: http://jsfiddle.net/8dugffz4/7/