I need 2 elements (in the demo marked #a and #b) to both fill their parent entirely. I need element #a filling it's parent (this is easy, I just set flex to 1), and I need element #b to be atop of #a and have exactly same size as #a. How to make #b have the same size? If I set width/height to 100% #b will overflow.
body {
margin: 0;
display: flex;
width: 100vw;
height: 100vh;
}
nav {
background-color: silver;
}
main {
flex: 1;
border: 5px solid green;
display: flex;
}
#a {
border: 1px solid aqua;
flex: 1;
}
#b {
position: absolute;
border: 1px dashed blue;
flex: 1;
}
<nav>sidebar of variable width</nav>
<main>
<div id="a">aaa</div>
<div id="b">bbb</div>
</main>
If you set the parent (main) to position: relative while #b is position: absolute then you should be able to size it in relation to main (100% width and height in this case) and position it to top and left 0.
body {
margin: 0;
display: flex;
width: 100vw;
height: 100vh;
}
nav {
background-color: silver;
}
main {
flex: 1;
border: 5px solid green;
display: flex;
position: relative;
}
#a {
border: 1px solid aqua;
flex: 1;
}
#b {
position: absolute;
border: 1px dashed blue;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
<nav>sidebar of variable width</nav>
<main>
<div id="a">aaa</div>
<div id="b">bbb</div>
</main>
Related
For a picture preview I want to put 2 invisble divs (red/blue in the picture) in front of a picture for next/previous image functionality.
I would like to have the div ("pictureContainer"/ green bordered zone) to automatically take over the dimension of the containing picture but I can't find a PURE CSS solution without setting the width and the height manually.
.container {
position: fixed;
width: 100%;
height: 100%;
border: 3px solid black;
}
.pictureContainer {
/* I don't want to set width and hight manuyally.
The container should have the size if the contained image. */
height: 50%;
width:300px;
position: relative;
margin: auto;
border: 3px solid green;
}
.leftSide {
background-color: blue;
float: left;
height: 100%;
width: 50%;
opacity: 80%;
}
.rightSide {
background-color: red;
float: right;
height: 100%;
width: 50%;
opacity: 80%;
}
.picture {
position: absolute;
top: 0;
left: 0;
margin: auto;
z-index: -1;
}
<div class="container">
<div class="pictureContainer">
<div class="leftSide"></div>
<img class="picture" src="https://www.9skips.com/wp-content/uploads/2018/01/anger-300x300.jpg">
<div class="rightSide"></div>
</div>
</div>
Also the container should be horizontally aligned.
Note: The full screen white div with the black border is used to close the picture preview.
You should change so the divs have absolut: position, let the image have it's natural size, container should be display: inline-block;
.container {
display: flex;
align-items: center;
justify-content: center;
position: fixed;
width: 100%;
height: 100%;
border: 3px solid black;
}
.pictureContainer {
position: relative;
display: inline-block;
margin: 0 auto;
border: 3px solid green;
}
.picture {
display: block;
}
.leftSide {
position: absolute;
top: 0;
bottom: 0;
left: 0;
background-color: blue;
width: 50%;
opacity: 80%;
z-index: 1;
}
.rightSide {
position: absolute;
top: 0;
bottom: 0;
right: 0;
background-color: red;
height: 100%;
width: 50%;
opacity: 80%;
z-index: 1;
}
<div class="container">
<div class="pictureContainer">
<div class="leftSide"></div>
<img class="picture" src="https://www.9skips.com/wp-content/uploads/2018/01/anger-300x300.jpg">
<div class="rightSide"></div>
</div>
</div>
I know that fixed positioning does not work relative to the parent, only to the browser window and the solution is absolute, but I also have a problem with that.
In the div in which I need a scroll inside, I have to put the icon always visible in the bottom right corner.
My fiddle: https://jsfiddle.net/nck7o0jL/
Below is my code.
.big {
height: 600px;
width: 600px;
border: 2px solid black;
}
.small {
height: 300px;
width: 300px;
border: 2px solid red;
overflow: auto;
position: relative;
resize: both;
}
img {
width: 30px;
height: 30px;
position: absolute;
right: 15px;
bottom: 15px;
}
<div class="small"><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-close-circled-128.png">
<div class="big">
</div>
</div>
As you can see, by stretching the div.small the icon is held, but during the scroll it is not.
Will someone give a helping hand?
You can approximate this using flexbox and position:sticky
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.big {
height: 600px;
width: 600px;
flex-shrink: 0;
}
.small {
height: 300px;
width: 300px;
border: 2px solid red;
overflow: auto;
resize: both;
display: flex;
}
img {
width: 30px;
height: 30px;
margin: auto 0 15px auto;
position: sticky;
order: 1;
right: 15px;
top: calc(100% - 45px);
}
<div class="small"><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-close-circled-128.png">
<div class="big">
</div>
</div>
I have a wireframe below and want to see what's the best way to code this with flexbox.
I have coded a simple flexbox grid system but my wireframe requires more customization than what I have on my grid system.
I have parent div has display: flex and have 2 child divs have flex:1 and flex: 0 0 40%.
What is the best way to add content div(gray boxes inside on blue and red) that will stay with rest of main wrapper(entire gray box sets to max-width: 1400px)?
Thank you.
Here's the general idea.
Positioned pseudo-elements, one for each section of the row. With a suitable width (note that the body should have overflow-x:hidden) and appropriate positioning values.
* {
box-sizing: border-box;
}
body {
overflow-x: hidden;
}
.wrapper {
min-height: 100vh; /* for demo purposes */
width: 60%;
margin: auto;
background: grey;
display: flex;
flex-direction: column;
}
header {
height: 20vh;
background: green;
}
.inner {
height: 30vh;
display: flex;
}
main {
background: blue;
flex: 1;
border: 2px solid black;
}
aside {
background: red;
flex: 0 0 40%;
border: 2px solid black;
}
.other {
background: pink;
flex: 1;
}
/* magic section */
.extend {
position: relative;
}
.extend::after {
content: '';
position: absolute;
width: 100vw;
top: 0;
height: 100%;
background: inherit;
z-index: -1;
}
.left::after {
right: 0;
}
.right::after {
left: 0;
}
<div class="wrapper">
<header></header>
<div class="inner">
<main class="extend left"></main>
<aside class="extend right"></aside>
</div>
<div class="other"></div>
</div>
In this JSFiddle example I've made a screen layout using divs and css, then added a canvas element inside each region with a black border so I can see its extent.
In this screenshot you can see the borders are correct for the 3 main elements of the left side-bar, but the top and bottom elements are cut off as if underneath the label div element.
I've given my canvas class the following properties:
.fitcanvas {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
border: 1px solid black;
}
The intention is for the canvas to fill the area remaining (or 100% if there's nothing else in the parent). I've tried putting it inside another div but cannot get it to work correctly.
What did I do wrong?
In your fiddle, you have given a 11% height to top and bottom css class, but to the remaining divs, it used .content which is 26% in height. This is making heights uneven. You can give 25% to all to make them of same height.
Your labels are overlapping your canvas area, because, you have given 100% height to canvas w.r.t its container, and the container includes label as well. Hence the problem. Please check fiddle here
The css looks like:
* {
box-sizing: border-box;
}
html,
body,
.wrapper {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
border: 1px solid black;
}
.left,
.right {
float: left;
}
.left {
position: relative;
width: 10%;
height: 100%;
}
.left .label-top,
.left .label-bottom {
position: absolute;
width: 100%;
background-color: #fff;
}
.left .label-top {
top: 0;
left: 0;
}
.left .label-bottom {
bottom: 0;
left: 0;
}
.left .content,
.left .top,
.left .bottom {
border: 1px solid white;
}
.left .top,
.left .bottom {
height: 25%;
}
.left .content {
height: 25%;
}
.colourred {
background-color: red;
}
.colourgreen{
background-color: green;
}
.colourblue {
background-color: blue;
}
.right {
width: 85%;
height: 100%;
background-color: gray;
}
.right::after {
content: '';
display: table;
clear: both;
}
.slider {
}
.fitcanvas {
max-width: 100%;
height: 100%;
border: 1px solid black;
margin:1px;
}
With the following html, when I hover over child, I get a green background on parent. How can I stop that from happening? I do want the green background if I am hovering outside of the child element.
CSS3 is fine.
.parent {
padding: 100px;
width: 400px;
height: 400px;
}
.parent:hover {
background-color: green;
}
.child {
padding: 100px;
width: 200px;
height: 200px;
}
.child:hover {
background-color: blue;
}
<div class="parent">
<div class="child">Child</div>
</div>
So this is REALLY ugly, but it works (kind of). I'm basically creating a duplicate of parent as a sibling of child. parent-overwrite is hidden by default, then displayed on the hover of child. Chrome doesn't like it unless you use the + selector instead of the ~ selector. This isn't very scalable, but it may work.
As the other guys posted, javascript would likely be a better solution.
<style>
.parent { padding: 100px; width: 400px; height:400px; position: relative; z-index: 998; }
.parent:hover { background-color: green; }
.child { padding: 100px; width: 200px; height:200px; position: relative; z-index: 1000; }
.child:hover { background-color: blue; }
.parent-overwrite { padding: inherit; width: inherit; height: inherit; position: absolute; top: 0; left: 0; z-index: 999; background-color: #FFF; display: none; }
.child:hover ~ .parent-overwrite { display: block; }
</style>
<div class="parent">
<div class="child">Child</div>
<div class="parent-overwrite"></div>
</div>
In 2022:
This can be now achieved using a combination of the :has and :not pseudo-classes, with the following expression:
.parent:hover:not(:has(.child:hover)) {}
To break it down:
.parent
/* When this element is hovered */
:hover
/* but it does not */
:not(
/* have a child node .child, that is also hovered */
:has(.child:hover)
) {
/* apply these rules */
}
A working modification of the original snippet is below:
.parent {
padding: 100px;
width: 400px;
height: 400px;
}
.parent:hover:not(:has(.child:hover)) {
background-color: green;
}
.child {
padding: 100px;
width: 200px;
height: 200px;
}
.child:hover {
background-color: blue;
}
<div class="parent">
<div class="child">Child</div>
</div>
It can also be made recursive by reusing the .parent selector in place of the .child selector.
See browser support here. At the time of writing, all major browser support it—except Firefox, which still has a flawed experimental implementation.
I can only do this with adding additional markup. An empty div needs to be added that essentially functions as the parent background. Take a look at the CSS here.
HTML Part:
<div class="parent">
Parent
<div class="child">
Child
<div class="grandson">
Grandson
<div class="grandson-bg"></div>
</div>
<div class="child-bg"></div>
</div>
<div class="parent-bg"></div>
</div>
CSS part:
article, aside, figure, footer, header, hgroup, menu, nav, section { display: block; }
.parent { display: block; position: relative; z-index: 0;
height: auto; width: auto; padding: 25px;
}
.parent-bg { display: block; height: 100%; width: 100%;
position: absolute; top: 0px; left: 0px;
border: 1px solid white; z-index: 0;
}
.parent-bg:hover { border: 1px solid red; }
.child { display: block; position: relative; z-index: 1;
height: auto; width: auto; padding: 25px;
}
.child-bg { display: block; height: 100%; width: 100%;
position: absolute; top: 0px; left: 0px;
border: 1px solid white; z-index: 0;
}
.child-bg:hover { border: 1px solid red; }
.grandson { display: block; position: relative; z-index: 2;
height: auto; width: auto; padding: 25px;
}
.grandson-bg { display: block; height: 100%; width: 100%;
position: absolute; top: 0px; left: 0px;
border: 1px solid white; z-index: 0;
}
.grandson-bg:hover { border: 1px solid red; }
http://jsbin.com/ubiyo3/edit
The easiest thing to do may be to use JS for this sort of CSS. Maybe you can try to rethink your implementation. Why are you trying to do something like this?
This is not possible using plain-vanilla CSS. You're asking for a pseudo-class of a child (child:hover) to affect the background declaration of a parent. There's no way to specify that sort of thing using regular css.
This can definitely be done using javascript.
I have what i think is a better solution, since it is scalable to more levels, as many as wanted, not only two or three.
I use borders, but it can also be done with whatever style wanted, like background-color.
With the border, the idea is to:
Have a different border color only one div, the div over where the mouse is, not on any parent, not on any child, so it can be seen only such div border in a different color while the rest stays on white.
You can test it at: http://jsbin.com/ubiyo3/13
And here is the code:
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Hierarchie Borders MarkUp</title>
<style>
.parent { display: block; position: relative; z-index: 0;
height: auto; width: auto; padding: 25px;
}
.parent-bg { display: block; height: 100%; width: 100%;
position: absolute; top: 0px; left: 0px;
border: 1px solid white; z-index: 0;
}
.parent-bg:hover { border: 1px solid red; }
.child { display: block; position: relative; z-index: 1;
height: auto; width: auto; padding: 25px;
}
.child-bg { display: block; height: 100%; width: 100%;
position: absolute; top: 0px; left: 0px;
border: 1px solid white; z-index: 0;
}
.child-bg:hover { border: 1px solid red; }
.grandson { display: block; position: relative; z-index: 2;
height: auto; width: auto; padding: 25px;
}
.grandson-bg { display: block; height: 100%; width: 100%;
position: absolute; top: 0px; left: 0px;
border: 1px solid white; z-index: 0;
}
.grandson-bg:hover { border: 1px solid red; }
</style>
</head>
<body>
<div class="parent">
Parent
<div class="child">
Child
<div class="grandson">
Grandson
<div class="grandson-bg"></div>
</div>
<div class="child-bg"></div>
</div>
<div class="parent-bg"></div>
</div>
</body>
</html>