I have a DIV measuring 400px wide, containing two DIVs side-by-side, each with width of 400px and height of 600px. The width of both DIVs is fixed, however the height can vary. I'd like to hide the second DIV and show the first completely, with no scrolling inside the DIV.
My solution, I thought, was to hide the overflow-x. This seems to also hide the y overflow too.
Here's my code:
#schools-sub-nav {
}
#schools-container {
width: 400px; /* Set the width of the visible portion of content here */
background-color: fuchsia;
position: relative;
overflow-x: hidden;
}
#schools-list {
width: 400px; /* Set the width of the visible portion of content here */
height: 600px; /* Delete the height, let the content define the height */
background-color: purple;
position: absolute;
top: 0;
left: 0;
}
#boards-list {
width: 400px; /* Set the width of the visible portion of content here */
height: 600px; /* Delete the height, let the content define the height */
background-color: green;
position: absolute;
top: 0;
left: 400px;
}
<div id="schools-sub-nav"> Schools List // Boards List </div>
<div id="schools-container">
<div id="schools-list"> One </div>
<div id="boards-list"> Two </div>
</div>
I expect #schools-list to be visible, but for some reason overflow-x: hidden in #schools-container hides it.
The way you made the two divs (with an absolute position) void the overflow rule!
You need to change the position type (to normal/not absolute) and I suggest using floats, finally, the container div that you want to apply the overflow, needs to have a way to fit it, like placing a div at the end with clear: both (in the case of using floats).
EDIT: I just tried it and you can hide the second div by following the upper suggestion and adding another surrounding div inside with a very large width and change the overflow-x to overflow for the main container div.
Like this:
<div id="schools-container">
<div id="schools-container-inside">
<div id="schools-list"> One </div>
<div id="boards-list"> Two </div>
</div>
</div>
And then the CSS (I commented the original not used CSS and added the new div class at the end):
#schools-container {
width: 400px; /* Set the width of the visible portion of content here */
background-color: fuchsia;
position: relative;
/*overflow-x: hidden;*/
overflow: hidden;
}
#schools-list {
width: 400px; /* Set the width of the visible portion of content here */
height: 600px; /* Delete the height, let the content define the height */
background-color: purple;
/*
position: absolute;
top: 0;
left: 0;
*/
float: left;
}
#boards-list {
width: 400px; /* Set the width of the visible portion of content here */
height: 600px; /* Delete the height, let the content define the height */
background-color: green;
/*
position: absolute;
top: 0;
left: 400px;
*/
float: left;
}
#schools-container-inside {
width: 10000px;
overflow: hidden;
}
JsFiddle here: http://jsfiddle.net/MbMAc/
I think you need this
#schools-container {
width: 400px; /* Set the width of the visible portion of content here */
background-color: fuchsia;
position: relative;
overflow-x: hidden;
overflow-y:auto;
height:600px;
}
You need to define height of main div as well.
Related
I have a case where the fixed element is 'positioned' - in a way - relative to the parent container and not the browser window...
.container {
position: relative;
width: 640px;
margin: 0 auto;
}
.options {
position: fixed;
bottom: 0;
width: 100%;
}
.options button {
float: left;
box-sizing: border-box;
width: 25%;
}
<div class="container">
<div class="options">
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
</div>
</div>
The div containing the buttons is fixed, and the bottom offset is set to 0. However, the div is offset a certain distance, and starts at the same horizontal distance as the parent container. Now once I set the left offset value to '0' the element positions itself as expected, starting from the edge of the viewport. So I understand that this isn't actually positioned in relation to the parent container. But why is there an offset initially? I'm guessing the default 'auto' setting computes that left value to something other than zero. But how is this value computed?
Also, another point of confusion arose with how the width value is computed, when the value is 100% vs inherit. I looked up and realized that the difference between the two is that while 'width: 100%' sets the width to 100% of the computed value of the parent element, 'width: inherit' takes up the CSS value of the parent literally and applies that to the element. So in the case of the sample I shared above, while the former will set the width of the div containing the buttons to literally 100% of its own parent's computed width, the latter will set to width to '640px', which is the parent's CSS value. The issue I have is, in the first case, where the width is set in percentages, the element is wider than expected. The computed width appears to be computed from the viewport width i.e. 100% of the viewport, and not the parent element, which is what I expected.
If 'width: inherit' acquires the width of 640px from the parent element, then why is the width inherited from the viewport if width is set to 100%, and not the computed value of the parent. Why is it that in one case, the preceding container is considered as the parent from which the value is inherited, and in the other case the viewport is the parent from which the value is computed?
But why is there an offset initially?
That's the case with position values other than static and sticky (fixed, absolute) they keep their parent offsets.
Demo:
*,
*:after,
*:before {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body * {
padding: 10px;
border: 1px solid;
}
body {
text-align: center;
}
[container] {
position: relative;
width: 120px;
margin: 50px;
padding: 30px;
display: inline-block;
}
[absolute] {
position: absolute;
}
[fixed] {
position: fixed;
}
<div container>
<div absolute>absolute</div>
</div>
<br/>
<div container>
<div fixed>fixed</div>
</div>
As you can see even with position applied, the elements don't suddenly jump around to where they're expected to be. You can try adding left:0 add see how they move.
Width: inherit or 100%; ?
Like i said before:
percentage is relative to the containing block, that changes according to css rules, inherit keyword is relative to the parent element defined in the markup and that never changes with css
Much more accurate MDN explanation
Percentage values that are applied to the width, height, padding, margin, and offset properties of an absolutely positioned element (i.e., which has its position set to absolute or fixed) are computed from the element's containing block.
Demo
[container] {
background: orange;
position: relative;
width: 300px;
height: 100px;
transform: translate(0)
}
[fixed] {
background: red;
position: fixed;
width: 100%;
left: 0;
}
<div container>
<div fixed>fixed</div>
</div>
In this example width:100% is behaving as it should because we changed the congaing block of the fixed element using transform: translate(0)
There's many ways to change the containing block of an element i suggest you read up the MDN article on that.
body have a padding per default. You can add padding: 0 to make your fixed element go as far to the left as possible, or add left: 0 to your fixed .options element.
You shouldn't use fixed width (640px), because you should code with responsiveness in mind.
You shouldn't use float in layout, because it mess up the box size of the object. Only use it on images if you want the text to "float" around the image.
html, body { /* ADDED */
margin: 0;
padding: 0;
}
.container {
position: relative;
width: 100%; /* CHANGED */
margin: 0 auto;
/* ADDED */
min-width: 640px;
}
.options {
position: fixed;
bottom: 0;
width: 100%;
/*left: 0; if you don't want to change the padding for the body */
/* ADDED */
display: flex;
}
.options button {
/*float: left;*/
box-sizing: border-box;
/* width: 25%; */
/* ADDED */
flex: 1 1 auto; /* grow / shrink / auto-adjust in width */
}
<div class="container">
<div class="options">
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
</div>
</div>
This question already has answers here:
Setting Element Width Based on Height Via CSS
(10 answers)
Closed 3 years ago.
I saw solution for height depending on width: css height same as width. Or here: https://stackoverflow.com/a/6615994/2256981.
But my question is opposite.
My element:
<body>
<div id="square"></div>
</body>
Style for it:
body, html {
margin: 0;
height: 100%;
min-height: 300px;
position: relative;
}
div#square { /* My square. */
height: 75%; /* It's height depends on ancestor's height. */
width: 75vh; /* If supported, preliminarily sets it's width. */
position: absolute; /* Centers it. */
left: 50%; top: 50%; transform: translate(-50%, -50%);
background-color: darkorange; /* Makes it visible. */
}
Script, that keeps it square:
window.onload = window.onresize = function (event) {
var mySquare = document.getElementById("square");
mySquare.style.width = mySquare.offsetHeight + 'px';
};
Complete code here: http://jsfiddle.net/je1h/hxkgfr9g/
The question is to make the same thing in pure CSS. No scripting.
There are two techiques I am aware of to keep the aspect ratio of an element according to it's height :
When height is relative to the viewport :
You can use vh units :
div {
width: 75vh;
height: 75vh;
background:darkorange;
}
<div></div>
For a height based on the height of a parent element :
You can use a dummy image that has the aspect ratio you want. Example with a 1:1 aspect ratio you can use a 1*1 transparent .png image or as commented by #vlgalik a 1*1 base64 encoded gif :
html,body{
height:100%;
margin:0;
padding:0;
}
#wrap{
height:75%;
}
#el{
display:inline-block;
height:100%;
background:darkorange;
}
#el img{
display:block;
height:100%;
width:auto;
}
<div id="wrap">
<div id="el">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
</div>
</div>
Note that this last demo doesn't update on window resize. But the aspect ratio is kept on page load
UPDATE :
As reported in the comments setting display:inline-flex: on #el seems to solve the updating on window resize problem.
Edit: Missed that you wanted to set the width depending of the height, this does the opposite :(
To support all ratios you can use padding-bottom. Percentages in padding-bottom are always relative to the width of the element:
/* the wrapper has a width */
.wrapper {
position: relative;
width: 25%;
margin-bottom: 10px;
}
/* these elements set the height (using padding-bottom) */
.square {
padding-bottom: 100%;
position: relative;
}
.widescreen {
padding-bottom: 56.25%; /* 9/16 = 0.5625 */
}
/*
* This is the content.
* Needs position:absolute to not add to the width of the parent
*/
.content {
/* fill parent */
position: absolute;
top: 0; bottom: 0;
left: 0; right: 0;
/* visual */
padding: 10px;
background: orange;
color: white;
}
<div class="wrapper">
<div class="square">
<div class="content">square</div>
</div>
</div>
<div class="wrapper">
<div class="widescreen">
<div class="content">16:9 ratio</div>
</div>
</div>
The only downside is, that you need a bunch of wrapper elements.
Height was not respected on this fiddle
I want the image to have a height and width of 80% relative to its parent, vertically and horizontally aligned. For some reason, it does not work.
HTML:
<div id="menu_header_new_orig">
<img id="menu_logo_orig" src="https://imagizer.imageshack.us/v2/849x565q90/833/uua2.jpg" />
</div>
CSS:
#menu_header_new_orig {
margin-top: 2.5%;
height:40%;
width:100%;
overflow: hidden;
position: relative;
border: 1px solid green;
text-align: center;
}
#menu_logo_orig {
width: 80%;
height: 80%;
position: relative;
}
I have figured it out here, but just in case somebody have better solution.
If I understand you correct :
The parent #menu_header_new_orig own parent must also have a height (obviously 100%)
html, body {
height: 100%;
}
set display to inline, 10% top to get vertical alignment
#menu_logo_orig {
top: 10%;
display: inline;
position: relative;
width: 80%;
height: 80%;
}
Is that what you were heading for? [not really sure] - try to set #menu_header_new_orig height to other things than 40% to get it in another perspective.
forked fiddle -> http://jsfiddle.net/Dmc7j/
I saw that there were some posts on the subject but none of them answers my question specifically
http://jsfiddle.net/27van/ shows how to center text horizontally.
I want to center it vertically in the parent div, without using the top which sets a fixed number of pixels (while I need it to be dynamic)
Any clues?
.parent_div {
position: relative;
text-align: center;
}
.child_div {
position: absolute;
width: 100%;
top: 70px;
}
<div class="parent_div">
<img src=...></img>
<div class="child_div">
<h1>Some Title</h1>
</div>
</div>
Because you have given the child element a width of 100% so i am guessing you are looking to center align it vertically ... in that case you need to know the height of your .child-div if it has a fixed height then you can use something like this:
.parent_div {
position: relative;
}
.child-div {
position: absolute;
height: 100px; /* for example */
top: 50%;
margin-top: -50px /* height divided by 2 */
}
and if the height is unknown then you can use the same method but calculate height & margin via jQuery. And just in case you wanted to align it horizontally you can use the same method but with these changes ... in this case you need fixed width.
.child-div {
position: absolute;
width: 100px; /* for example */
left: 50%;
margin-left: -50px /* width divided by 2 */
}
Your updated fiddle
I want to have a site that is 100% of the height of the browser at all times, with the width scaling with an aspect ratio when the height is changed.
I can achieve this using the new vh unit: http://jsbin.com/AmAZaDA/3 (resize browser height)
<body>
<div></div>
</body>
html, body {
height: 100%;
width: 100%;
margin: 0;
}
div {
height: 100%;
width: 130vh;
margin: 0 auto;
background: #f0f;
}
However, I worry about fallback for IE8 and Safari, as it this unit is not supported there.
Are there any other CSS only methods of achieving this effect?
I have a solution that works also with IE8 (using Pure CSS 2.1), but not perfectly.
because I need the browser to recalculate things when he get resized, and apparently it doesn't do that unless he has to (and I cant find a way to make him think he has to), so you will have to refresh the page after resizing.
as far as I know, the only element that can scale reserving his ratio is an <img>, so we will use the <img> to our advantage.
SO, we are going to use an image with the ratio that we want (using the services of placehold.it), lets say we want a 13X10 ratio (like in your example), so we'll use <img src="http://placehold.it/13x10" />.
that image will have a fixed height of 100% the body, and now the width of the image scales with respect to the ratio. so the width of the image is 130% height of the body.
that image is enclosed within a div, and that div has inline-block display, so he takes exactly the size of his content. witch is the size you want.
we remove the image from the display by using visibility: hidden; (not display:none; because we need the image to take the space), and we create another absolute div, that will hold the actual content, that will be right above the image (100% width and 100% height of the common container).
That works perfectly when you first initiate the page, but when you resize the page, the browser doesn't always measure the right width and height again, so you'll need to refresh to make that happened.
Here is the complete HTML:
<div class="Scalable">
<img class="Scaler" src="http://placehold.it/13x10" />
<div class="Content"></div>
</div>
and this simple CSS:
html, body, .Content
{
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body
{
text-align: center;
}
.Scalable
{
position: relative;
display: inline-block;
height: 100%;
}
.Scaler
{
width: auto;
height: 100%;
margin-bottom: -5px;
visibility: hidden;
}
.Content
{
position: absolute;
top: 0;
background-color: black;
}
Here's a Fiddle (don't forget to refresh after resizing)
I recommend you to copy this code to your local machine and try it there rather then within the fiddle.
In this similar SO question a CSS technique was found and explained on this blog entry that allows an element to adjust its height depending on its width. Here is a repost of the code:
HTML:
<div id="container">
<div id="dummy"></div>
<div id="element">
some text
</div>
</div>
CSS:
#container {
display: inline-block;
position: relative;
width: 50%;
}
#dummy {
margin-top: 75%; /* 4:3 aspect ratio */
}
#element {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: silver /* show me! */
}
Demo Here
If this is sufficient for you, I'd recommend this technique. However, I'm unaware if the technique can be adapted to handle scenarios where you must have an element adjust its width depending on its height.
You can do it with the help of padding on a parent item, because relative padding (even height-wise) is based on the width of the element.
CSS:
.imageContainer {
position: relative;
width: 25%;
padding-bottom: 25%;
float: left;
height: 0;
}
img {
width: 100%;
height: 100%;
position: absolute;
left: 0;
}