CSS square with dynamic height - css

I need to make a div square. The height of the div is dynamically changing and I want the width to be equal to the height. I have seen a lot of solutions to set the height to be equal to the width (with padding-bottom on pseudo-elements), but I need it the other way arround. Is this possible with pure CSS?

No .... well, there is this trick, where one use a hidden image
div {
display: inline-block;
height: 170px;
background: red;
}
div img {
visibility: hidden;
height: 100%;
}
<div>
<img src="http://placehold.it/50">
</div>
Updated
And here is a script version, that also keep it within the width
Stack snippet
(function (d,t) {
window.addEventListener("resize", throttler, false);
window.addEventListener("load", throttler(), false); /* run once on load to init */
function throttler() {
if ( !t ) {
t = setTimeout(function() {
t = null;
keepSquared(d.querySelector('.container'),
d.querySelector('.squared'));
}, 66);
}
}
function keepSquared(co,el) {
var s = window.getComputedStyle(co, null);
var m = Math.min(
parseFloat(s.getPropertyValue("width")),
parseFloat(s.getPropertyValue("height")));
el.style.cssText =
'width: ' + m + 'px; height: ' + m + 'px;';
}
})(document,null);
html, body {
height: 100%;
margin: 0;
}
.container {
position: relative;
width: 50%;
height: 50%;
top: 50px;
left: 50px;
border: 1px solid black;
box-sizing: border-box;
}
.squared {
background-color: red;
}
<div class="container">
<div class="squared">
</div>
</div>
Note: Since resize events can fire at a high rate, the throttler is used to reduced the rate so the handler doesn't execute expensive operations such as DOM modifications too often.

Related

::-webkit-scrollbar is it possible to make the scrollbar-thumb grow instead moving?

I would like my scroll to work like this when the user scrolls. e.g to start to fill up instead of moving.
Is it possible to make the scroll-thumb grow or to style the scrollbar-track-piece different before and after the thumb?
Here is a small example how to implement this loader
window.addEventListener("scroll", (e) => {
var html = document.documentElement;
let step = 100 / (html.scrollHeight - window.innerHeight);
let loader = document.getElementById("scrollprogress");
loader.style.width = (step * html.scrollTop) + "%";
})
#scrollprogress {
height: 5px;
position: fixed;
left: 0;
top: 0;
background: orange;
}
.backgr {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 5px;
background: lightgrey;
z-index: -1;
}
.box {
height: 3000px;
}
<div id="scrollprogress"></div>
<div class="backgr"></div>
<div class="box"></div>
You can approximate this using negative box shadow:
body::-webkit-scrollbar {
width: 1em;
}
body::-webkit-scrollbar-thumb {
background-color: orange;
box-shadow:-1000vmax -1000vmax 0px 1000vmax orange;
}
body {
width:300vw;
height:300vh;
background:linear-gradient(60deg,red,blue,orange);
margin:0;
}
html {
background:#fff;
}

Why does html child element disappears when rotating element in Webkit?

I am trying to rotate a container div in html so that all of it's child elements rotate with it.
document.addEventListener('DOMContentLoaded', function() {
var img = document.createElement('img');
var ctx = document.getElementById('canvas').getContext('2d');
var n = 73; // -58
var elContainer = document.getElementById('container');
var elDegrees = document.getElementById('degrees');
var setAngle = function(n) {
elContainer.style.transform = ''.concat('rotate(', n, 'deg)');
elDegrees.innerHTML = n;
}; // /setAngle()
document.getElementById('btnUp').addEventListener('mousedown', function() {
n++;
setAngle(n);
});
document.getElementById('btnDown').addEventListener('mousedown', function() {
n--;
setAngle(n);
});
img.onload = function() {
ctx.drawImage(img, 0, 0, 640, 360);
};
img.src = 'https://blog.codepen.io/wp-content/uploads/2012/06/Made-For-Codepen.png';
setAngle(n);
});
* {
box-sizing: border-box;
overflow: hidden;
}
#root {
position: relative;
width: 250px;
height: 150px;
}
#container {
position: absolute;
top: 0;
left: 0;
overflow: hidden;
width: 250px;
height: 150px;
transform-origin: center center 0px;
transform: rotate(90deg);
transform-style: preserve-3d;
background-color: #000000;
}
#child {
background-color: #00ff00;
position: absolute;
box-sizing: border-box;
overflow: hidden;
top: 60px;
left: 60px;
padding: 10px;
z-index: 2;
}
#canvas {
display: block;
width: 250px;
height: 150px;
position: absolute;
box-sizing: border-box;
overflow: hidden;
top: 0;
left: 0;
z-index: 1;
}
<div id="root">
<div id="container">
<div id="child">
TEXT ELEMENT
</div>
<canvas id="canvas" style="" width="640" height="360"></canvas>
</div>
</div>
<button id="btnDown">-1 degree</button>
<button id="btnUp">+1 degree</button>
<span id="degrees"></span> degrees
<p>
In Chrome or Safari, if the container is rotated greater than 73 degrees or less than -58 degrees, to absolute positioned child div with text disappears. Why?
</p>
For some reason when the container div is rotated past 73 degrees or -58 degrees in Chrome or Safari, the child div element disappears behind the canvas element. This happens with both canvas elements and video elements. This problem does not happen in Firefox.
Have you tried putting the same webkit rotation on the child too? And possibly floating the child might help. Not 100% sure. Or, you may need to specify which browsers you are using within the webkit.

Maintain aspect ratio and font size based on browser height and width?

The code below is attached to window.onresize = resize;. The baseWidth and baseHeight are read on load as a basis for the calculations. The main variable is defined just by setting it to the main html node. The font is set on a block element to cause all of the em based elements within it to resize in kind. When the width or height of the browser is changed then the ratio is recalculated. Please see demo to understand what I achieve with JS but would like to find a pure CSS solution: http://codepen.io/anon/pen/nLauF
I have been exploring options in CSS3 such as calc. Feel free to also suggest any improvements to the JS below also.
function resize() {
var height = 0,
width = 0;
if(window.innerWidth <= window.innerHeight) {
size = window.innerWidth / baseWidth;
height = baseHeight * size;
width = window.innerWidth;
} else {
size = window.innerHeight / baseHeight;
height = window.innerHeight;
width = baseWidth * size;
}
if(baseWidth * size > window.innerWidth) {
size = window.innerWidth / baseWidth;
height = baseHeight * size;
width = window.innerWidth;
}
main.style.height = height + "px";
main.style.width = width + "px";
main.style.fontSize = size * 16 + "px";
}
Thanks!
I wrote this code including font-size calculation with vmin units :
DEMO
CSS :
main {
width: 80vmin;
height: 60vmin;
background-color: #000;
position: absolute;
top:0; bottom:0;
left:0; right:0;
margin:auto;
}
h1 {
color: #fff;
font-size: 30px; /* general fallback */
font-size: 5vm; /* IE9 fallback */
font-size: 5vmin;
}
For browser support, you can check canIuse
I adapted a piece of CSS i wrote for a different project to solve your problem: JSFiddle DEMO
I achieved the aspect ration of 4-3 by using a .75 multiplier (i.e. the width of main is 50% and the height should be 75% of that so the padding-top is 37.5%). You can see how these are adjustable to lock in your ratio.
.main {
width: 50% !important;
height: 0;
display: block;
overflow: hidden;
line-height: 0;
position: relative;
padding: 37.5% 0 0 0;
background-color: #000;
margin: 0 auto;
}
.main-inner {
position: absolute;
display: block;
margin: auto;
top: 10px;
left: 10px;
bottom: 10px;
right: 10px;
}
.main-inner-relative {
position: relative;
padding: 10px;
}
p {
color: white;
padding: 0;
margin: 0;
}
This would require you to modify your HTML like so:
<div class="main">
<div class="main-inner">
<div class="main-inner-relative">
<p>hello</p>
</div>
</div>
</div>
reference 1 -- this reference is my original solution used to keep images locked into an aspect ratio responsively
reference 2

How to make Canvas take 100% of remaining space?

Similar to how i want a div to take 100% height, 100% width, or both. i want a Canvas to take 100% width and 100% height:
(Link to JsFiddle for your perusal)
Markup:
<div id="canvasContainer">
<canvas id="myCanvas"></canvas>
</div>
CSS:
html {
width: 100%;
height: 100%;
}
body {
width: 100%;
height: 100%;
margin: 0;
}
#canvasContainer {
width: 100%;
height: 100%;
background-color: green;
}
#myCanvas {
width: 100%;
height: 100%;
}
Javascript:
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(canvas.width, canvas.height);
ctx.stroke();
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(canvas.width, 0);
ctx.lineTo(0, canvas.height);
ctx.stroke();
Which results in something not taking 100% of browser window:
It works fine if you delete the Canvas:
Downside of that is then i don't have a Canvas.
Sizing a canvas element
If you stretch the canvas using CSS you will stretch the poor canvas which has a default size of 300x150 pixels to the whole screen - imagine you had an image of that size and which you did the same to - will look pretty bad.
Canvas content can not be stretched using CSS (it acts as an image that way). You need to explicitly set the pixel size of the canvas.
This means you will need to get the size of the parent container and set it as a pixel value on the canvas:
First off, to get rid of scroll bars etc.adjust the CSS you have:
body, html {
width: 100%;
height: 100%;
margin: 0;
padding:0;
overflow:hidden;
}
Now modify this rule:
#myCanvas {
background-color: green;
position:fixed;
left:0;
top:0;
}
Now reduce your markup to this only (if you want the canvas covering the whole sceeen you don't need a container other than the window):
<canvas id="myCanvas"></canvas>
Now we can calculate size:
var canvas;
window.onload = window.onresize = function() {
canvas = document.getElementById('myCanvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
And that's it.
Working demo (resize the window to see).
you can position absolute with 0 everywere:
canvas {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
Then just look in which element it is positionned, add position: relative to handle the block it covers. In your case probably: #canvasContainer, but maybe body if it's just for a single full screen.
I have had a similar issue in the past. My solution for it was setting overflow: hidden on the html
Fiddle Here
It gets rid of that little bit at the bottom, which if you inspect the pages is just a little bit extra, and not actually the height of the body. If anyone has some insight into what that is I am all ears.
Modified some of the examples here to get mine to work.
JSFiddle: http://jsfiddle.net/FT3pP/1/
JS:
$( document ).ready( function () {
SizeBackground();
} );
function SizeBackground(){
var canvas = $( "canvas#background" )[0];
fitToContainer( canvas );
}
function fitToContainer( canvas ) {
canvas.width = canvas.parentElement.clientWidth;
canvas.height = canvas.parentElement.clientHeight;
}
CSS:
body, html {
margin: 0;
width: 100%;
height: 100%;
padding: 0; }
div .container {
width: 100%;
height: 100%; }
div#pallette {
position: absolute;
top: 1px;
bottom: 1px;
left: 1px;
right: 1px; }
canvas#background {
position: fixed;
left: 0;
top: 0;
background: black; }
HTML:
<body>
<div id="pallette">
<div class="container">
<canvas id="background"></canvas>
<canvas id="middleground"></canvas>
<canvas id="foreground"></canvas>
</div>
<div id="stats"></div>
<div id="chat"></div>
</div>
</body>
Only includes i had:
<!-- Styles Sheets -->
<link href="Scripts/App.min.css" rel="stylesheet" />
<!-- Javascript -->
<script src="Scripts/jquery-2.1.0.min.js"></script>
<script src="Scripts/jquery-ui-1.10.4.min.js"></script>
<script src="Scripts/app.js"></script>

Circular button that resizes with window size

I'd like to make a circular button (div works too) and put it in the centre with a diameter of 20% of the height of the window. This I can do, but the button will become oval if the window isn't exactly square (I'd like the width and height to be the same - a perfect circle).
.circle {
height: 20%;
width: 20%;
border-radius: 100%;
font-size: 20px;
color: #fff;
line-height: 100px;
text-align: center;
background: #000
}
Hardcoding a pixel value isn't much of an option as it wouldn't resize based on the window. Any ideas?
There are two ways to achive this; with and without JavaScript.
The JavaScript method
Here's a simple demo: little link.
HTML:
<div class = "circle"></div>
CSS:
html, body {
height: 100%;
}
.circle {
border-radius: 1000px;
background-color: rgb(0, 162, 232);
}
JavaScript (uses jQuery, but it isn't necessary):
function upd() {
var h = $("body").height();
$(".circle").height(h / 5);
$(".circle").width(h / 5);
}
upd();
window.onresize = upd;
The non-JavaScript (CSS) method
For a CSS-only solution, you need to use the fact that all padding values are calculated relative to the element parent's width, not height (reference). Little demo: little link.
HTML:
<div class = "wrapper">
<div class = "main">
</div>
</div>
CSS:
html, body {
height: 100%;
width: 100%;
}
.wrapper {
width: 20%;
display: inline-block;
position: relative;
}
.wrapper:after {
padding-top: 100%; /*1:1 ratio*/
display: block;
content: '';
}
.main {
position: absolute;
top: 0; bottom: 0; right: 0; left: 0; /*fill parent*/
border-radius: 1000px;
background-color: rgb(0, 162, 232);
/*I wanted it to look good :)*/
font-family: 'Arial', Helvetica, Sans-Serif;
color: white;
}
There is a way to achieve a perfect circle without using any JS, it lies in the specifications definition for padding percentage. When the padding is applied as a percentage it is applied as a percentage of the objects width, which means if you set width and height to 0, and give the object a padding of 20% you'll end up with a circle occupying 20% of the available width. You'll need to get creative to get things inside the circle though.
<style>
html, body {
width:80%;
}
.square
{
width:0%;
height:0%;
padding:20%;
position:relative;
left:25%;/*Position central*/
border-radius:100%;
margin:auto;/*Position central*/
border:1px solid #000000;
}
</style>
The easiest fix is to add min-height and min-width property to that circle with same value.
.circle {
min-width: 100px;
min-height: 100px;
}

Resources