I have a container with two elements absolutely positioned. While rotating the container on hover, why the top elements always remains on top even when the container is rotated by 180deg. why don't we see the bottom element then?
body {
perspective: 1000px;
}
.container {
margin: 20px 0 0 20px;
position: relative;
height: 400px;
width: 250px;
transition: all 3s;
}
.container:hover {
transform: rotateY(180deg);
}
.item {
position: absolute;
height: 100%;
width: 100%;
}
.item-1 {
height: 120%;
background: orange;
/* z-index: -1; */
}
.item-2 {
background: cyan;
/* z-index: 1; */
}
<div class="container">
<div class=" item item-1"></div>
<div class=" item item-2">Hover Over Me!</div>
</div>
code: https://jsfiddle.net/rj5b9dhc/
I have the solution, but I'm curious why above code doesn't work
solution code: https://jsfiddle.net/512p9x3r/1/
Because of backface-visibility: hidden; in item-2 css in solution code.
Check this: w3schools
Updated:
When .item (two items) height is 100%, .item-2 have no height in it css and covering 100% of container and .item-1 height is 120% (it's mean that it height is 20% more than .item-2) and covering 20% of container.
Cause of that .item-1 is before .item-2, .item-1 will be showing on .item-2.
as the Reference explained:
This property is useful when an element is rotated. It lets you choose
if the user should see the back face or not.
When container has rotated, .item-2 will be hidden.
Related
This question already has answers here:
one div gets bigger while the other gets smaller
(3 answers)
Make flex item expand on hover, shrinking its siblings
(2 answers)
Closed 2 years ago.
I'm very new to coding and I just want to do something basic in CSS. I have a landing page which is split into two down the middle. On the left side, is a yellow div. On the right side, a grey div.
When I hover over a div, it increases its width (ltr for the left div and rtl right div).
On the same hover event I want the OTHER div to decrease its width. So there's no overlap between the two.
With the code I have the left side div works. The hover event also works. When I hover over the left side. The width goes up to 51% and the right side div's width becomes 49%.
However, the right side equivalent doesn't work. When I hover over the right side. The right side div increases its width but the left side div does not decrease dwn to 49%. The right side just overlaps the left.
Any ideas? I found some answers about parent/child relationships and played around but with no success.
Apologies for my poorly written code. I am only starting out and would appreciate some advice.
#leftside {
/*this is the orange half*/
height: 100%;
width: 50%;
position: absolute;
left: 0;
top: 0;
opacity: 0.5;
background-image: linear-gradient(rgba(255, 255, 0, 1), rgba(255, 165, 0, 1));
transition: all 1s;
}
#leftside:hover {
opacity: 1.0;
width: 51%;
}
#leftside:hover+#rightside {
width: 49%
}
#rightside {
/*this is the grey half*/
height: 100%;
width: 50%;
position: absolute;
right: 0;
top: 0;
opacity: 0.5;
background-image: linear-gradient(rgba(255, 255, 255, 0), rgba(160, 160, 160, 1));
transition: all 1s;
}
#rightside:hover {
opacity: 1.0;
width: 51%;
}
#rightside:hover+#leftside {
width: 49%
}
<div id="leftside">
<a class="leftsidehome" href="page1.html"></a>
</div>
<div id="rightside">
<a class="rightsidehome" href="page2.html"></a>
</div>
The problem with your code is #rightside:hover+#leftside because CSS cannot look back. Below a possible solution using flexbox.
.container {
display: flex;
width: 100%;
}
#leftside,
#rightside {
flex-grow: 1; /* Allow each flex item to grow */
flex-shrink: 1; /* Allow each flex item to shrink */
width: 50%;
height: 100px; /* Used only to make them visible */
transition: width 1s; /* Animate the change of width */
}
#leftside {
background: yellow;
}
#rightside {
background: grey;
}
#leftside:hover {
width: 51%;
}
#rightside:hover {
width: 51%;
}
<div class="container">
<div id="leftside">
<a class="leftsidehome" href="page1.html"></a>
</div>
<div id="rightside">
<a class="rightsidehome" href="page2.html"></a>
</div>
</div>
I am having issues coming up with a way to make a child have transitionable width while making the parent change instantaneously.
Using the following example:
.parent {
height: 100px;
width: 25%;
background-color: blue;
}
.child {
width: 100%;
transition: width 1s;
background-color: red;
height: 50px;
}
.parent:hover {
width: 50%;
}
<div class="parent">
<div class="child">
</div>
</div>
When .parent is hovered, its width should increase, and then the child should take 1s to catch up to the parents width.
Is there any way to achieve this? I don't want the parent to transition as it will cause a lot of jumping around as the parent grows instead of moving everything at once.
You can't use transition, since the child's width value doesn't actually change - it was 100% before and 100% after.
In this case you can use an animation that will start from 50% if the new width, and proceed to the 100%. If the hover ends, the child width will go back to the parent's width immediately.
.parent {
height: 100px;
width: 25%;
background-color: blue;
}
.child {
width: 100%;
background-color: red;
height: 50px;
}
.parent:hover {
width: 50%;
}
.parent:hover .child {
animation: 1s both grow;
}
#keyframes grow {
from { width: 50%; }
to { width: 100%; }
}
<div class="parent">
<div class="child">
</div>
</div>
So keep in mind that div elements are block elements. They will fill the full-width of their parent unless you style them otherwise.
This makes using percentages problematic without adding a keyframes animation. Though there is nothing wrong with defining an animation.
But if you give exact widths with other types of css units, you can achieve the affect by also changing the width of the child when the parent is hovered.
Below I changed the parent width to 25vw and assigned the same width to the child. Then, when the parent is hovered, change the child width to 100% will cause it to transition.
In the original case, you were only changing the parents width, and the child's width never transitioned because in both states of the parent, its value was 100%.
.parent {
height: 100px;
width: 25vw;
background-color: blue;
}
.child {
width: 25vw;
transition: width 1s linear;
background-color: red;
height: 50px;
}
.parent:hover {
width: 50%;
}
.parent:hover > .child {
width: 100%;
}
<div class="parent">
<div class="child">
</div>
</div>
The issue is that you're child's width is technically not changing. It remains 100% of the parent's width, so though it's physical size as constrained within the parent changes, it's relative width value is still 100%, so no transition is being applied to it.
Using vw units will allow you to create a fluid layout with the width values being relative to the viewport (window) width instead of the containing div.
.parent {
height: 100px;
width: 25vw;
background-color: blue;
}
.child {
width: 25vw;
transition: width 1s;
background-color: red;
height: 50px;
}
.parent:hover, .parent:hover .child {
width: 50vw;
}
<div class="parent">
<div class="child">
</div>
</div>
I'm using transform to rotate an image according to its EXIF data. Then, I'd like to display it "full screen" by fitting it to its parent div.
The problem is, max-width / max-height and all other sizing directives "ignore" the rotation (which is normal, according to transform specs, the element's transformation is "ignored" in the flow.
Jsfiddle: http://jsfiddle.net/puddjm4y/2/
div.top {
position: fixed;
width: 100%;
height: 100%;
border: 1px solid blue;
}
img {
transform: rotate(90deg);
max-width: 100%;
max-height: 100%;
}
<div class="top">
<img src="http://www.androidpolice.com/wp-content/uploads/2014/02/nexusae0_wm_DSC02232.jpg">
</div>
Is there a way to achieve this?
For full screen display, the simplest solution is to use viewport units to specify width and height of images:
Normal image should be 100vw wide and 100vh tall
Rotated image should be 100vh wide and 100vw tall
The image could be moved to the middle using CSS transformations. Here is an example, it uses two images that are larger and smaller than the viewport:
body {
margin: 0;
}
img {
display: block;
}
img.normal {
max-width: 100vw;
max-height: 100vh;
transform: translatex(calc(50vw - 50%)) translatey(calc(50vh - 50%));
}
img.rotated {
max-width: 100vh;
max-height: 100vw;
transform: translatex(calc(50vw - 50%)) translatey(calc(50vh - 50%)) rotate(90deg);
}
/* demo */
.demo {
height: 100vh;
position: relative;
}
.demo:nth-child(odd) {
background-color: #CCC;
}
.demo:nth-child(even) {
background-color: #EEE;
}
.demo::after {
content: attr(title);
position: absolute;
left: 0;
top: 0;
padding: .25em .5em;
background-color: rgba(255, 255, 255, .8);
}
<div class="demo" title="Large image, normal"><img class="normal" src="https://i.stack.imgur.com/2DdPE.jpg"></div>
<div class="demo" title="Large image, rotated"><img class="rotated" src="https://i.stack.imgur.com/2DdPE.jpg"></div>
<div class="demo" title="Small image, normal"><img class="normal" src="https://i.stack.imgur.com/ustNQ.jpg"></div>
<div class="demo" title="Small image, rotated"><img class="rotated" src="https://i.stack.imgur.com/ustNQ.jpg"></div>
Make the height of an element equal it's width and vice versa, is a Javascript thing, since it can retrieve those values and set them back.
In CSS there's no way of accomplishing that, and also not possible with dynamic dimensions, we don't know what 100% would equal to exactly, and even if we did we wouldn't be able to use them, because there's no reference to them.
However if you would go with fixed values, that can be manipulated with media queries, then why not use variables, this way we have the value, and a reference to it.
:root {
--width: 100px;
--height: 140px;
}
div.top {
position: fixed;
width: var(--width);
height: var(--height);
border: 1px solid blue;
}
img {
width: var(--width);
height: var(--height);
animation: rotate 3s alternate infinite;
}
/* translate values are the difference between the height */
/* and width divided between the X and Y */
/* 100 - 140 = 40 / 2 = 20px each */
#keyframes rotate {
to {
transform: rotate(90deg) translate(20px, 20px);
width: var(--height);
height: var(--width);
}
}
<div class="top">
<img src="http://www.androidpolice.com/wp-content/uploads/2014/02/nexusae0_wm_DSC02232.jpg">
</div>
Then again, this is just an idea.
I would probably go for something like this (swapped max-width/height using viewport sizing)
* {
box-sizing:border-box;
}
html, body {
margin:0;
}
div.top {
position: fixed;
width: 100%;
height: 100%;
top:0;
left:0;
border: 1px solid blue;
display:flex;
}
img {
transform: rotate(90deg);
max-width: 100vh;
max-height: 100vw;
margin:auto;
}
<div class="top">
<img src="http://www.androidpolice.com/wp-content/uploads/2014/02/nexusae0_wm_DSC02232.jpg">
</div>
You could do this in JavaScript by checking the container height and setting the maxWidth of the image to the height of the container.
/**
* Set max width of a rotated image to container height
* #param {*} container
* #param {*} image
*/
function setRotatedImageWidth(container = null, image = null) {
if (!container || !image) {
return false; // exit if empty
}
var h = container.offsetHeight; // Container height
var w = image.offsetWidth; // Image width
// If image width is greater container height
if (w > h) {
image.style.maxWidth = h + 'px';
}
}
var container = document.querySelector('.container');
var image = container.querySelector('img');
setRotatedImageWidth(container, image);
I finally found the answer to what I needed for this problem, maybe it will help someone else.
I have a flex parent and the child I needed to be rotated based on EXIF.
I needed image-orientation: from-image;
imgBox {
flex: 1;
padding: 1rem;
overflow: hidden;
}
.img1 {
object-fit: cover;
max-width: 100%;
image-orientation: from-image;
}
Here's a scant attempt that requires manually syncing the width / height. For those who are willing to use JS, that should be fairly easy to sync.
Here it is:
div.top {
border: 1px solid blue;
box-sizing: border-box;
width: 100%;
height: 300px;/* SYNC */
position: relative;
overflow: hidden;
}
div.top:before {
content: "";
position: absolute;
width: 300px;/* SYNC */
height: 100%;
transform: rotate(90deg);
background-image: url(http://www.androidpolice.com/wp-content/uploads/2014/02/nexusae0_wm_DSC02232.jpg);
background-size: contain;
background-repeat: no-repeat;
}
<div class="top"></div>
Positioning becomes awkward. However, my hope is that someone will branch from here and conjure a better solution.
If you could ignore the transform part as it is a question of aspect ratio and there is no answer for it, but displaying an image to 100% of the parent element is possible and will not be needing any media queries to it. 100 percent is relative to the parent and with images it is the aspect ratio that rules the dimensions. we can stretch it but that will not serve the purpose. Hope below css might help you in some way.
div.top {
position: fixed;
width: 100%;
height: 100%;
border: 1px solid blue;
background-image:url("http://www.androidpolice.com/wp-content/uploads/2014/02/nexusae0_wm_DSC02232.jpg");
background-size:cover;
background-repeat:no-repeat;
background-position:50%;
}
div.top img {
/* transform: rotate(90deg); */
min-width: 100%;
min-height: 100%;
visibility:hidden;
}
I am using image natural width and height to calculate transform scale as I have documented at:
https://stackoverflow.com/a/61620946/7037600
For the exif part you can't do it with css as css ins't able to ready exif datas.
For the CSS part though, you need to use transform-origin, not just transform and also use width 100% and heigh auto to keep ratio.
Here is an exemple :
http://jsfiddle.net/yxqgt2d1/1/
I have an HTML page which is divided into 4 sections.
Header
Menu
Content
Footer
I am using 1 div for each section and 1 div which wraps all the 4 divs.
My header's height is 50px, the menu's height is 50px, and the footer's height is 20px.
Then I try setting the menu's height to 100%. Menu div is taking the height of its container which is creating scrollbars in my page.
The CSS is as follows:
html, body {
margin: 0px;
height: 100%;
width: 100%;
min-width: 1024px;
min-height: 500px;
}
#container {
width: 100%;
height: 100%;
}
#header {
width: 100%;
height: 50px;
}
#menu {
width: 100%;
height: 50px;
}
#content {
width: 100%;
height: 100%;
}
#footer {
width: 100%;
height: 20px;
}
Is it possible with CSS alone or I have to use JavaScript also?
Here is another Pure CSS solution, that works without specifying any height whatsoever.
[this solution deserves its own answer]
Here's a Working Fiddle
Why is it good?
because maybe your header will change one day affecting his height, or your menu will grow, or your footer will need an extra line causing his height to grow..
all of that changes will cause you to re-fix another height for the changing element, and recalculate the right height for the content.
my solution makes it easier, because all the parts are fluid.
let them take the space they need in the page, and the content will always take the remaining height.
Browser support:
Tested On: IE10, Firefox, Chrome, Safari, Opera. (not working on older IE, not tested on other browsers)
any Downsides?
yes. unfortunately, because of the way that this trick works, you will need to change the arrangement of your HTML.
I found a Pure CSS way to create a div container, with two child div's.
the first will take the exact height he needs, and the second will take the remaining of the container height's.
but what if I want the opposite scenario,
What if I want second div to take his exact space and the first div to take the container's remaining height?
I didn't find an easy way to do that with Pure CSS.
thats why, I actually reverse the order of the divs, the first holds the second data, and the second holds the first data, now we let the first div to take his exact height, and the second stretch to the end of the container as we want, and then I rotate their view via CSS to make them appear in order.
For your case it means that you will have to create the HTML in that order.
Header
Menu
Footer
Content
The Solution:
HTML:
<div class="Container">
<div class="Header">I'm in the header</div>
<div class="Menu">I'm in the menu</div>
<div class="HeightTaker">
<div class="Wrapper Container Inverse">
<div>
<div class="Footer">I'm in the footer</div>
</div>
<div class="HeightTaker">
<div class="Wrapper">
<div class="Content">
I'm in the content
</div>
</div>
</div>
</div>
</div>
</div>
CSS:
*
{
margin: 0;
padding: 0;
}
html, body, .Container
{
height: 100%;
}
.Container:before
{
content: '';
height: 100%;
float: left;
}
.HeightTaker
{
position: relative;
z-index: 1;
}
.HeightTaker:after
{
content: '';
clear: both;
display: block;
}
.Wrapper
{
position: absolute;
width: 100%;
height: 100%;
}
.Inverse, .Inverse > *
{
-moz-transform: rotateX(180deg);
-ms-transform: rotateX(180deg);
-o-transform: rotate(180deg);
-webkit-transform: rotateX(180deg);
transform: rotateX(180deg);
}
.Header
{
/*for demonstration only*/
background-color: #bf5b5b;
}
.Menu
{
/*for demonstration only*/
background-color: #6ea364;
}
.Content
{
height: 100%;
overflow: auto;
/*for demonstration only*/
background-color: #90adc1;
}
.Footer
{
/*for demonstration only*/
background-color: #b5a8b7;
}
Here's a thought. May not work for your specific problem, but it does address the issue of mixing pixels and percents. Under the current definition of the problem, you use a fixed height for both the top (header, menu) and bottom (footer). But you want to have the content take up the rest. One solution would be to pad the top and bottom of the container with the same height of the header and menu on top and the same height as the footer on the bottom. The problem then is that you have a 100% height container plus 100px on top and 20px on bottom. But there's a CSS convention for that. It's called box-sizing and is very cross browser compatible (as long as you include -moz). in effect, it calculates 100% height after including the padding. Therefore, 100% height plus all the padding still equals 100% height.
In practice it looks like this
HTML
<div class="container">
<div class="header"></div>
<div class="menu"></div>
<div class="content"></div>
<div class="footer"></div>
</div>
CSS
html, body, .container {
min-height: 100%;
background:#eee;
}
.header {
height: 50px;
position: relative;
z-index: 1;
}
.menu {
height: 50px;
position: relative;
z-index: 1;
}
.footer {
height: 20px;
width: 100%; /* needed because this one is position absolute */
bottom: 0%;
position:absolute;
}
.content {
height: 100%;
width: 100%; /* needed because this one is position absolute */
top: 0%;
left: 0%;
padding-top: 100px;
padding-bottom: 20px;
position:absolute;
box-sizing: border-box; /* here's the kicker */
-moz-box-sizing: border-box;
overflow: auto; /* don't panic. they take the place of normal scroll bars*/
}
Demo
http://jsfiddle.net/WLR5S
Source
http://jsfiddle.net/WLR5S/show
http://jsfiddle.net/WLR5S/6/show (with -moz for firefox)
Pros
Obviously, the point is that you can have 100% height elements with padding to compensate for footer and header
Cons
You have to use position absolute for the content and footer, and you have to apply position relative with z-index to the header area
EDIT
After a little more experimenting, I found that it's probably best to use height instead of min-height and apply overflow:auto or the like. That way the page has appropriate sidebars if the content gets to be too large: http://jsfiddle.net/WLR5S/2/ or http://jsfiddle.net/WLR5S/3/
Pure CSS Solution
using calc() (CSS3)
Working Fiddle
HTML:
<div id="container">
<div id="header">header</div>
<div id="menu">menu</div>
<div id="content">content</div>
<div id="footer">footer</div>
</div>
CSS:
html, body {
margin: 0px;
height: 100%;
/*min-width: 1024px;
min-height: 500px;*/ /*You can uncomment that back if you want)*/
}
#container {
height: 100%;
}
#header {
height: 50px;
}
#menu {
height: 50px;
}
#content {
height: calc(100% - 120px); /*120 = 50 + 50 + 20*/
overflow: auto;
}
#footer {
height: 20px;
}
notice I removed your width:100% because this is the default behavior of a block element like a div.
This can also be done without stating any height at all, with Pure CSS.
Check my second answer in that page.
How do I make an html div tag to be on top of everything? I tried adding z-index: 1000, but it remains the same.
In order for z-index to work, you'll need to give the element a position:absolute or a position:relative property. Once you do that, your links will function properly, though you may have to tweak your CSS a bit afterwards.
Yes, in order for the z-index to work, you'll need to give the element a position: absolute or a position: relative property... fine.
But... pay attention to parents!
The element's z-index may be limited by its parent's z-index value.
You have to go down the nodes of the elements to check if at the level of the common parent the first descendants have a defined z-index.
All other descendants can never be in the foreground if at the base there is a lower definite z-index.
In this snippet example, div1-2-1 has a z-index of 1000 but is nevertheless under the div1-1-1 which has a z-index of 3.
This is because div1-1 has a z-index greater than div1-2.
.div {
}
#div1 {
z-index: 1;
position: absolute;
width: 500px;
height: 300px;
border: 1px solid black;
}
#div1-1 {
z-index: 2;
position: absolute;
left: 230px;
width: 200px;
height: 200px;
top: 31px;
background-color: indianred;
}
#div1-1-1 {
z-index: 3;
position: absolute;
top: 50px;
width: 100px;
height: 100px;
background-color: burlywood;
}
#div1-2 {
z-index: 1;
position: absolute;
width: 200px;
height: 200px;
left: 80px;
top: 5px;
background-color: red;
}
#div1-2-1 {
z-index: 1000;
position: absolute;
left: 70px;
width: 120px;
height: 100px;
top: 10px;
color: red;
background-color: lightyellow;
}
.blink {
animation: blinker 1s linear infinite;
}
#keyframes blinker {
50% {
opacity: 0;
}
}
.rotate {
writing-mode: vertical-rl;
padding-left: 50px;
font-weight: bold;
font-size: 20px;
}
<div class="div" id="div1">div1</br>z-index: 1
<div class="div" id="div1-1">div1-1</br>z-index: 2
<div class="div" id="div1-1-1">div1-1-1</br>z-index: 3</div>
</div>
<div class="div" id="div1-2">div1-2</br>z-index: 1</br><span class='rotate blink'><=</span>
<div class="div" id="div1-2-1"><span class='blink'>z-index: 1000!!</span></br>div1-2-1</br><span class='blink'> because =></br>(same</br> parent)</span></div>
</div>
</div>
More simply :
For z-index:1000 to have an effect you need a non-static positioning scheme.
Add position:relative; to a rule selecting the element you want to be on top
You need to add position:relative; to the menu. Z-index only works when you have a non static positioning scheme.
z-index property enables you to take your control at front. the bigger number you set the upper your element you get.
position property should be relative because position of html-element should be position relatively against other controls in all dimensions.
element.style {
position:relative;
z-index:1000; //change your number as per elements lies on your page.
}
I gonna assumed you making a popup with code from WW3 school, correct?
check it css. the .modal one, there're already word z-index there. just change from 1 to 100.
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 100px; /* Location of the box */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
It seems like nesting an element inside a <dialog> element puts it on top of everything. It is placed both horizontally and vertically centered to the screen if you use showModal() but you lose the interactivity with other elements in the page.
document.querySelector("dialog").showModal();
<dialog>
<div class="element">I am on top of everything else</div>
</dialog>
<div class="backdrop">Backdrop element</div>
If you still want interactivity with the background elements, you can use the show() method. It is placed only horizontally centered to the screen.
document.querySelector("dialog").show();
<dialog>
<div class="element">I am on top of everything else</div>
</dialog>
<div class="backdrop">Backdrop element to check if I am underneath or not.</div>