From what I've seen in other answers, CSS viewport units can't be used in calc() statements yet. What I would like to achieve is the following statement:
height: calc(100vh - 75vw)
Is there some workaround way I can achieve this using purely CSS even though the viewport units can't be used in the calc() statement? Or just CSS and HTML? I know I can do it dynamically using javascript, but I'd prefer CSS.
Before I answer this, I'd like to point out that Chrome and IE 10+ actually supports calc with viewport units.
FIDDLE (In IE10+)
Solution (for other browsers): box-sizing
1) Start of by setting your height as 100vh.
2) With box-sizing set to border-box - add a padding-top of 75vw. This means that the padding will be part f the inner height.
3) Just offset the extra padding-top with a negative margin-top
FIDDLE
div
{
/*height: calc(100vh - 75vw);*/
height: 100vh;
margin-top: -75vw;
padding-top: 75vw;
-moz-box-sizing: border-box;
box-sizing: border-box;
background: pink;
}
As a workaround you can use the fact percent vertical padding and margin are computed from the container width. It's quite a ugly solution and I don't know if you'll be able to use it but well, it works: http://jsfiddle.net/bFWT9/
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div>It works!</div>
</body>
</html>
html, body, div {
height: 100%;
}
body {
margin: 0;
}
div {
box-sizing: border-box;
margin-top: -75%;
padding-top: 75%;
background: #d35400;
color: #fff;
}
<div>It's working fine.....</div>
div
{
height: calc(100vh - 8vw);
background: #000;
overflow:visible;
color: red;
}
Check here this css code right now support All browser without Opera
just check this
Live
see Live preview by jsfiddle
See Live preview by codepen.io
Doing this with a CSS Grid is pretty easy. The trick is to set the grid's height to 100vw, then assign one of the rows to 75vw, and the remaining one (optional) to 1fr. This gives you, from what I assume is what you're after, a ratio-locked resizing container.
Example here: https://codesandbox.io/s/21r4z95p7j
You can even utilize the bottom gutter space if you so choose, simply by adding another "item".
Edit: StackOverflow's built-in code runner has some side effects. Pop over to the codesandbox link and you'll see the ratio in action.
body {
margin: 0;
padding: 0;
background-color: #334;
color: #eee;
}
.main {
min-height: 100vh;
min-width: 100vw;
display: grid;
grid-template-columns: 100%;
grid-template-rows: 75vw 1fr;
}
.item {
background-color: #558;
padding: 2px;
margin: 1px;
}
.item.dead {
background-color: transparent;
}
<html>
<head>
<title>Parcel Sandbox</title>
<meta charset="UTF-8" />
<link rel="stylesheet" href="src/index.css" />
</head>
<body>
<div id="app">
<div class="main">
<div class="item">Item 1</div>
<!-- <div class="item dead">Item 2 (dead area)</div> -->
</div>
</div>
</body>
</html>
Related
This question already has answers here:
Why does this CSS margin-top style not work?
(14 answers)
CSS margin terror; Margin adds space outside parent element [duplicate]
(7 answers)
Closed 1 year ago.
I don't understand why there is a scroll in the body and a space after the block .example. According to my logic, I make the margin-bottom 100px and then subtract these 100px from the block height max-height: calc(100% - 100px);
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
html,
body {
height: 100%;
}
.example {
padding: 20px;
width: 60%;
margin: 100px auto 0;
max-height: calc(100% - 100px);
border: 1px solid black;
overflow-y: scroll;
}
p{
padding: 100vh 0;
}
</style>
</head>
<body>
<div class="example">
<div class="text">
<p>Lorem</p>
<p>Lorem</p>
</div>
</div>
</body>
</html>
You're running into wildly inherited margins problem derived from the popular collapsed margins - issue (which is better known for when two elements with vertical margins, the two colliding margins collapse into one) - not your exact case but same in nature.
Read more on w3.org Collapsing Margins
Since you used html, body {height: 100%} and the tall .example element has margin-top 100% - the body element moved, collapsed 100px down! It basically "wildly" inherited (at least visually) those 100px margin.
An element with vertical margin can cause unwanted results with ancestors flow. One common way to fix this is to smartly avoid vertical margin, or to add overflow: auto to the ancestor that's being affected by that problem html, body in your specific case.
html, body {
height: 100%; /* Why would you want this? */
overflow: auto; /* FIX for wild margins */
}
The other solution (I'm sure there are many others) is to not use html, body {height: 100%}
Rather min-height (if really needed) on html and body and vh (viewport height) unit on the .example element
html, body {
/* min-height: 100%; /* use min-height, but not needed */
}
.example {
/* .... other styles */
margin: 100px auto 0;
height: calc(100vh - 100px); /* 100vh minus 100px margin-top */
}
Long story short - Be careful when using margin. I personally use it only when working with flexbox, or in the horizontal space (often when using inline-block elements) otherwise I always use wrappers with padding to create desired spacings which are perfectly controlled thanks to box-sizing: border-box (no need to calculate anything) - or when really necessary- I treat them with special care.
Get rid of the padding on the p elements:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
html,
body {
height: 100%;
}
.example {
padding: 20px;
width: 60%;
margin: 100px auto 0;
max-height: calc(100% - 100px);
border: 1px solid black;
overflow-y: scroll;
}
</style>
</head>
<body>
<div class="example">
<div class="text">
<p>Lorem</p>
<p>Lorem</p>
</div>
</div>
</body>
</html>
Right answer its a Collapsing margins xD. To solve the problem, you can add one of the following to the body:
border
padding
overflow
I have three divs: outer, inner, deeper, where each one is the parent of the next.
"Deeper" has its height set to a fixed value, whereas "inner" is set to auto.
I'd expect that "inner" height is the same as "deeper" height, but turns out that it is limited by "outer" height whenever "outer" display is set to flex.
However when "outer" display is set to "block" it works as expected.
Why does this happen?
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.outer {
height: 400px;
overflow-y: auto;
border: 1px solid gray;
display: flex;
}
.inner {
margin: 50px 0;
background-clip: content-box;
height: auto;
}
.deeper {
height: 600px;
width: 200px;
background-color: red;
}
<div class="outer">
<div class="inner">
<div class="deeper"></div>
</div>
</div>
here I posted another code to show my previous conclusion better. in this code you can change the "display:flex" to "display:block" to see the effect in inspect window.
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
padding: 0;
}
.outer {
height: 400px;
border: 1px solid gray;
display: flex;
/* the above "display:flex" makes the children of this tag to have the fixed height. */
}
.inner {
height: auto; /* the height defined here does not affect, you can inspect the tag to see that the height is "400px". */
background-color: #242;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex-box</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="outer">
<div class="inner">
</div>
</div>
</body>
</html>
I think what you would expect is wrong. see the code below:
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
padding: 0;
}
.outer {
height: 400px;
/* overflow-y: auto;*/
border: 1px solid gray;
display: block;
}
.inner {
/* margin: 50px 0;*/
/* background-clip: content-box;*/
height: 500px;
background-color: #242;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex-box</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="outer">
<div class="inner">
<!-- <div class="deeper"></div>-->
</div>
</div>
</body>
</html>
this is a very simple example. in this case I commented the "deeper" div. and also I commented the "overflow" and "background-clip" properties, because I think that they are not related to the question about "height".
what I want to say is that in this case we have the ".outer" div with "display:block" and a fixed "height". in that div we have another div with "height:500px" that is taller from his parent. you may see only this 500px div. but if you "inspect" you will notice that the height of ".outer" div is 400px. so we can conclude that
if we have a tag with "display:block" and a "fixed height", the height of this tag is not changed according to its child.
so in the case of "your question", we have the ".inner" div and its child is the ".deeper" div. ".inner" div has "display:block" and has a fixed height because:
"align-items" property, which has an initial value of "stretch" makes the children of a div with "display:flex" (that is the ".inner" div) to have the height of their parent (means the ".inner" has "400px" height)
so according to our conclusion height of ".inner" is not changed with the height of ".deeper".
This is basically what I want to achieve:
I want the total page to be 100% height, but when I put the sidebar and body at 100%, the page adds the 40px from the navbar, so I get a scrollbar even when there shouldn't be one.
I got it fixed by using tables, but I'm sure there must be an easier way
<body>
<div class="container-fluid">
<div class="navbar"></div>
<div class="sidebar"></div>
<div class="body"></div>
</div>
</body>
and css what I've got so far:
body, html, .container-fluid, .sidebar, .body {
height: 100%;
min-height: 100%;
}
.navbar {
height: 40px;
position: relative;
}
You'll have to subtract the height of the navbar from the 100%. There are several solutions, many of which will include JavaScript but you won't need that.
1: box-sizing
Give the navbar an absolute position. Then you have the issue of the content of the other elements disappearing below it.
Then comes the next trick: add a top-padding the size of the navbar.
And the last trick: add box-sizing: border-box; to the .sidebar and .body. For better browser support you also need -moz- and -webkit- prefixes like so: -moz-box-sizing:
Example: Fiddle to box-sizing
2: Actually subtract.
use .body, .sidebar{ height: calc(100% - 40px);
Browser support is very minimal for this from what I know less than for box-sizing, so I would recommend the first solution.
Calc explained on css-tricks
3: Flexbox(added anno 2015)
You should now probably go with using calc when you know the height but an awesome replacement for using tables is flexbox. This is really my saviour for complex designs in responsive websites. By using one of the best features - flex-shrink: 0 - on the header you can force other elements into adjusting themselves to fill the rest of the container.
An old answer is probably not the best place to write down an extensive guide on flexbox so, again, a great link to css-tricks
Probably because it is adding the default margin from the navbar. Try this:
.navbar {
height: 40px;
position: relative;
margin: 0;
padding: 0;
}
Also, try changing the min to max height:
max-height: 100% !important;
I change a litle your code by adding a container around your side bar and body class:
Here is the RESULT
Css:
body, html, .container-fluid, .sidebar, .body {
height: 100%;
min-height: 100%;
}
#container{
width:100%;
height:100%;
}
.sidebar{
background-color: green;
width:10%;
float:left;
height:100%;
}
.body{
background-color: orange;
float:left;
width:90%;
height:100%;
}
.navbar {
height: 40px;
position: relative;
background-color: yellow;
width:100%;
}
HTML
<div class="container-fluid">
<div class="navbar">
navbar
</div>
<div id="container">
<div class="sidebar">
sidebar
</div>
<div class="body">
body
</div>
</div>
</div>
</body>
Sorry, if my problem is a little bit too specific, but I have not found the answer anywhere else. On my website, there is a header that is supposed to take up the whole width of the screen, but it does not. There is always a blank space between the top, and the sides. I have tried display: block; min-width: 100%, just width: 100% and many more variations but I just can't find out how to get rid of it. Anybody have ideas? Thanks!
FULL CODE
/* GLOBAL */
body {
/*background-color: #1abc9c;
display: block;
min-width: 100%;*/
}
#content {} header {
display: block;
min-width: 100%;
height: 100px;
background-color: #34495e;
border-top: 5px solid #1abc9c;
}
<!DOCTYPE html>
<html>
<head>
<title>Example Website</title>
</head>
<body>
<div id="content">
<header>
<img src="REPLACE.png" />
</header>
</div>
</body>
</html>
By default, the browser adds some margin to body element. Thus to fix it, add margin:0; to your body CSS.
body {
margin:0;
}
JSfiddle demo
I've got a slight issue with the below code in IE.
The design is perfect in Chrome and Firefox but IE renders the textarea size very small. I want it as it looks in Firefox or Chrome.
It might be a duplicate of
Consistently sizing a <textarea> under IE, FF, Safari/Chrome
OR
Firefox / IE textarea sizing quirk - workarounds?
but there are no proper solutions mentioned. So I started this.
I'm sure that jQuery can sort it out but I want only CSS in my page, Is there any proper CSS solution to it??
I'm not able to log into jsFiddle, so, no jsFiddle guys.. :(
<!DOCROOT html>
<html>
<head>
<meta charset="utf-8" />
<title>Code Compressor</title>
<link href="styles.css" rel="stylesheet" type="text/css" />
<style type="text/css">
.container {
width: 100%;
overflow: hidden;
}
.column {
width: 48%;
margin: 1%;
float: left;
}
textarea {
min-width: 100%;
max-width: 100%;
min-height: 80%;
max-height: 80%;
overflow: auto;
}
.center {
clear: both;
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<div class="column">
<div>Input Source:</div>
<textarea id="sourceCode" name="sourceCode" ></textarea>
</div>
<div class="column">
<div>Compressed Output:</div>
<textarea id="outputCode" name="outputCode" ></textarea>
</div>
<div class="center">
<input type="button" id="compressButton" name="compressButton"
value="Compress" onClick="compress" />
</div>
</div>
</body>
</html>
If the height is not behaving as expected, so try to set a height for .column. Your textarea is inside of a column and its height is a percentage of his father, but, how high is your father?
Updated
You told that the .center layer is overlapped by the columns if you set a height to the textarea, right? Then we must to set the columns relative to each other and we have to explain to HTML that our .center should to be after our columns. To do this, follow the code:
.column {
width: 48%;
height: 500px; /* for example */
position: relative; /* add this to trasnform your columns
relative to each other */
margin: 1%;
float: left;
}
textarea {
min-width: 100%;
max-width: 100%;
width: 90%;
height: 90%;
min-height: 80%;
max-height: 80%;
overflow: auto;
}
.center {
width: 100%; /* to specify that your "center" must
to occupy 100% of the width on the screen. */
position: relative; /* to transform the position to relative */
float: left; /* to accompany the columns' floating */
clear: both;
text-align: center;
}
Percentage comprehension
Just to make things look better for you: to work with percentage, we need an initial point. This means that for something to have 80% of the height of something else, we need to know the height of something else.
In other words, to .something have 80% of height, we need to know the height of his father, and if his father have 90% of height, the father of his father must to have a specified height. At some point, we need a defined height.
JavaScript alternative
As I said, I have worked too much with percentage measures and no success to found a solution with pure CSS 2.1. Thereat, I created this mini-plugin in JavaScript + jQuery. No work-a-rounds:
function calculateResponsiveHeight(couple) {
for (var value in couple) {
$(value)
.css("height",
$(couple[value].wrapper).height() -
couple[value].spacing + "px");
}
}
Usage:
calculateResponsiveHeight({
".content": {
spacing: 135, // how much you want to spacing your layer?
wrapper: window // who is the reference point?
}
});
try this
#outputCode{
width:100%;
height:100%;
}
You haven't declared a height, add in a "height: 80%", you have just said what the max can be and the min can be - it doesn't intrinsically know what it should be in between.