So I'm trying to build a pure CSS responsive square (well actually I'm trying to build a circle but that's easy once I've got the square.)
In other words:
I want a div that has a height that is a percentage of the body and a width that is equal to that (or vice versa).
The div also needs to have another div inside it which can contain content and overflow: auto.
Lastly, the div can never exceed the height (or width) of the body or viewport.
So far, I have got some solutions working partially (i.e. in portrait but not landscape) using a 1px transparent .gif as an img to fill out a wrapper div. Not ideal semantics but I don't see how this can be done without it.
<div class="wrap">
<img src="http://www.neurillion.com/p/35/static/media/images/1x1t.gif" />
<main>
<div class="content">
<h2>Title</h2>
<p> Lorem... etc. </p>
</div>
</main>
</div>
Here are my CSS solutions and what is wrong with them:
This works except it exceeds the height of the body in landscape (max-height in any of the elements does not solve this):
.wrap {
background: blue;
margin: 10% auto;
width: 70%;
position:relative;
text-align:center;
}
.wrap img {
border: 1px solid black;
height: auto;
width: 100%;
}
main {
background: red;
display: block;
border-radius:50%;
height: 100%;
width: 100%;
position: absolute;
top:0
}
main div {
background: green;
overflow: auto;
display:inline-block;
height:70%;
width: 70%;
margin-top:15%;
}
Codepen
Next I added a landscape media query to swap around the height and width values. Same problem.
#media(orientation:landscape) {
.wrap {
margin: auto 10%;
height: 70%;
width: auto;
}
}
Codepen
At this point I started looking into .wrap's parent elements , namely the body and html. (Resource on the difference between them.) I added height and max-height: 100% to both of them, but no joy. I've also tried adding another div container as I thought it might be easier to control the height, but that doesn't seem to be doing much either.
And now I'm pretty much out of options. I'm fairly sure the solution is something to do with the html and body elements and the way they are so eager to expand vertically but I'm not really sure how else to stop them doing so.
Any help much appreciated.
You can use vw, vh and vmin to scale the square:
Demo: http://jsfiddle.net/r9VQs/
CSS (changed part only):
.wrap {
background: blue;
margin: 0 auto;
max-width: 90vh;
max-height: 90vh;
position:relative;
text-align:center;
}
You can also use vmin (which gives better results but is less well supported) and forego the image:
Demo: http://jsfiddle.net/r9VQs/2/
CSS:
.wrap {
background: blue;
margin: 0 auto;
width: 90vmin;
height: 90vmin;
position:relative;
text-align:center;
}
vh, vw and vmin are units equivalent to 1% of their respective viewport dimensions (vh is viewport-height, vw is viewport-width and vmin is whichever has a smaller value).
Please see http://caniuse.com/#feat=viewport-units for browser support.
Related
Currently I'm trying to fix a div class to always be 80% of the screen size if that's possible? I don't want the div to resize when I change the size of my browser, would I be better using media queries?
.main{
width: 80%;
min-width: 80%;
margin-left: auto;
margin-right: auto;
background-color: #ffffff;
overflow: hidden;
}
You write
I don't want the div to resize when I change the size of my browser
Well, then use a fixed width in pixels:
.main{
width: 600px; /* or whatever value you wish */
margin-left: auto;
margin-right: auto;
background-color: #ffffff;
overflow: hidden;
}
If you always want your div to be 80% of screen size. use viewport units. vw in your case which means viewport width.
This way your div will always be 80vw out of 100vw which is the full viewport size.
See below
.main {
height:100px;
width:80vw;
background:red;
}
<div class="main"> </div>
In the following fiddle:
http://jsfiddle.net/6qF7Q/1/
I have a yellow content area that has a min-height set to 100% - it's the background div to all pages and should take up at least 100% of the available height. If there's overflow, it expands vertically.
Then, within that yellow container, I have another child div (red) that I would like to take up as much vertical space as its parent. It seems I can't set height because the parent element only has min-height, and setting min-height on the red element doesn't work either.
So right now, the yellow is behaving as I'd like, but the red is not expanding. How can this be achieved with CSS only?
CSS:
.browser {
background-color: blue;
height: 600px;
width: 200px;
position: relative;
}
.innercontent {
min-height: 100%;
background-color: red;
width: 100%;
color: white;
padding: 2px;
}
.content {
background-color: yellow;
width: 100%;
min-height: calc(100% - 30px);
}
.footer {
position: absolute;
bottom: 0px;
left: 0px;
width: 100%;
background-color: orange;
height: 20px;
}
HTML:
<div class="browser">
<div class="content">
<div class="innercontent">
This is the problem - I need this to take up 100% of the remaining yellow space, without setting the parent element's 'height' - only min-height is specified in the parent because I need to make sure that it takes up 100% of the height at least, but allow it to extend vertically if there's any overflow.
</div>
should not see any yellow
</div>
<div class="footer"></div>
</div>
Take a look at this
I added this
*{
box-sizing: border-box;
}
html, body {
/* Make the body to be as tall as browser window */
height: 100%;
}
and changed some attributes u can see at fiddle
If thats what you want you should read this article
http://css-tricks.com/a-couple-of-use-cases-for-calc/
I made that based in this use-cases
I think this might solve your issue?
I have changed the innercontent to position: absolute
http://jsfiddle.net/6qF7Q/7/
If you have text in the yellow section it will always show.
Also, you're going to have to do a bit of fiddling to get your footer positioned correctly since you are going to have an overflowing absolute element. I think a full body position: relative wrapper will solve it.
P.S I don't see why you would need a .content AND a .innercontent if you don't want the .content to show?
This works much better and doesn't give you footer grief: http://jsfiddle.net/6qF7Q/9/
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;
}
The code is here:
<div class="entry-page-image">
<div class="featured-image-container">
<?php the_post_thumbnail('large'); ?>
</div>
</div><!-- .entry-page-image -->
Effected by this css:
.entry-page-image { position: fixed; display: inline-block; top: 0; margin: 0 0 30px 30px; margin-left: 260px; float:left; width: 100%; }
.featured-image-container { height: 100%; width: auto; }
.featured-image-container img { height: 100%; width: auto; }
However in Firefox the browser takes the standard 1024px high image, and wont scale it down to be 100% of the browser window height. I'm aware this is quite a common problem, but I can't seem to rephrase my code to the right effect.
Anyone fancy shifting it about for me?
The issue here is that height:100%; on .featured-image-container sizes the height relative to the height of its container.
In this case, the height of the container is equal to the height of the content in the container (the natural height of the image).
If you manually set the height on html,body to 100% then you'll find that the height of your div is now as you'd expect.
Example: http://jsfiddle.net/EyLHG/
html,body{
height:100%;
}
.container{
width:auto;
height:100%;
border:1px solid red;
}
img{
min-height:100%;
}
Update
Also, setting the width of the image to auto will cause the width to be the default width of the image rather than of the container. Setting the width to be 100% will fix this scaling issue:
Example: http://jsfiddle.net/EyLHG/2/
just saw your website, I think there is image still in below the browser as well, I think you might need to add position:relative; to .entry-page-image
This is my CSS code;
#wrap {
width:50em;
max-width: 94%;
margin: 0 auto;
background-color:#fff;
}
#head {
width:50em;
height:10em;
max-width: 100%;
margin: 0 auto;
text-align:center;
position: relative;
}
#css-table {
display: table;
margin: 1em auto;
position: relative;
width:50em;
max-width: 100%;
}
#css-table .col {
display: table-cell;
width: 20em;
padding: 0px;
margin: 0 auto;
}
#css-table .col:nth-child(even) {
background: #fff;
}
#css-table .col:nth-child(odd) {
background: #fff;
border-right: 4px double #b5b5b5;
}
And my HTML code;
<div id="cont">
<div id="css-table">
<div class="col">123</div>
<div class="col">123</div>
</div>
</div>
When I scale the Firefox window, the table scales fine even down to 300px width viewport...just like I want to. But in Chrome, the table looks normal only when the viewport is wider than 50em. If I narrow the Chrome window, the table bleeds out on the right side of the wrap.
Is there a reason why is Chrome doing this?
Technically Chrome is following the rules because max-width should only apply to block elements.
From MSDN docs:
The min-width/max-width attributes apply to floating and absolutely
positioned block and inline-block elements, as well as some intrinsic
controls. They do not apply to non-replaced inline elements, such as
table rows and row/column groups. (A "replaced" element has intrinsic
dimensions, such as an img or textArea.)
The table (or in your case display:table) should technically not work or be supported. FF apparently obeys it fine, but you'll probably need to come up with another solution, either removing the display:table or the max-width.
max-width property
MSDN Doc
The solution I found was using table-layout: fixed and width: 100%
Create a div and give it a styling to display block and a max width. You may use traditional <table> and give it a styling of 100% width.
I was able to use a mixin(SASS) to fix the issue.
#mixin clearfix {
&::after{
content: "";
display: table;
clear: both;
}
}