Select sibling div above current div - css

I'm trying to make a harmonica effect by changing the height of divs when hovering over another one.
My HTML looks like this:
<html><body>
<div class="section1"></div>
<div class="section2"></div>
<div class="section3"></div>
<div class="section4"></div>
</body></html>
Every section has a height of 25%.
When hovering over section1, all the other divs should reduce in size while section1 expands. This is easily done with the following CSS:
.section1 {
height: 40%;
}
.section1:hover ~ div:not(section1) {
height: 20%;
}
The problem is that the ~ selector only selects sibling divs that are below the current div. So if I use the same code for section2, only section3 and section4 will be affected. Section1 will have it's original height of 25% because it's above the current div.
Can I solve this problem with just CSS?

Yes. Put a wrapper around your sections and reduce their height on hover on the wrapper. Then increase the height of the one section you are hovering.
DEMO
HTML becomes:
<div class='section-wrapper'>
<div class="section1"></div>
<div class="section2"></div>
<div class="section3"></div>
<div class="section4"></div>
</div>
Relevant CSS:
.section-wrapper {
height: 500px;
}
.section-wrapper div {
height: 25%;
outline: dotted 1px;
}
.section-wrapper:hover div {
height: 20%;
}
.section-wrapper div:hover {
height: 40%;
}

Try this
HTML
<html>
<body>
<div class="container">
<div class="section1">1</div>
<div class="section2">2</div>
<div class="section3">3</div>
<div class="section4">4</div>
</div>
</body>
</html>
CSS ​
.container:hover div {
height:20px;
}
.container .section1,.container .section1:hover,
.container .section2,.container .section2:hover,
.container .section3,.container .section3:hover,
.container .section4,.container .section4:hover{
height: 50px;
}
​

Simple Add a parent container to the sections
<div class="parent">
<div class="section1">section1</div>
<div class="section2">section2</div>
<div class="section3">section3</div>
<div class="section4">section4</div>
</div
And style them as
.parent div{height: 25%; border:solid 1px #f00}
.parent:hover div{height: 20%; }
.parent div:hover {height: 40%; }

Related

CSS selector to target element where sibling does not have a specific class

I'm working on a slider that has previous button, content and next button as sibling nodes. I'm hiding disabled buttons and I need to adjust the margin for the content
I'm having difficulties with the selectors. I want to target the container to adjust the margin based on if the button is disabled or not. My initial idea was to do this with flex but it's an old
I've been trying something like
.content {
&:not(+ .button-disabled) {
margin-left: 50px;
}
}
but it seems I'm not allowed to have a +inside :not(). Is there any other way I can target this?
You can define a class to the parent container of the three siblings, like
<div class="disabled-button">
<div class="prev"></div>
<div class="cont"></div>
<div class="next"></div>
</div>
And define CSS for them, like:
.wrapper {
width: 80%;
height: 30px;
display: inline-flex;
}
.wrapper > div {
width: 33%;
height: 100%;
border: 1px solid black;
background-color: green;
}
.wrapper.disabled-button .prev {
margin-left: 50px;
}
<div class="disabled-button wrapper">
<div class="prev"></div>
<div class="cont"></div>
<div class="next"></div>
</div>
<div class="wrapper">
<div class="prev"></div>
<div class="cont"></div>
<div class="next"></div>
</div>

How to put a div below in another div (overlapping another div in between)?

Now I can just put the ABC div to the right but below Body div. How do I put ABC div below Header div? Overlapping is needed.
<div style="width:500px;margin:0 auto;">
<div style="background-color:yellow;height:100px">Header</div>
<div style="background-color:aquamarine; height: 400px">Body</div>
<div style="background-color:red;width:100px;margin-left:auto">ABC</div>
</div>
I have added 2 answers. 1st is for external stylesheet , 2nd is for inline styling (just like how you wrote your code).
Firstly, don't use inline styling. If possible, always use external stylesheet.
Now, for your question, use relative position for the parent and absolute for the child. In this case, parent is your main container and child is that ABC div.
Try this:
#container {
width: 500px;
margin: 0 auto;
position: relative;
}
.header {
background-color:yellow;
height:100px
}
.body {
background-color:aquamarine;
height: 400px;
}
.abc {
background-color:red;
width:100px;
position: absolute;
top: 100px;
right: 0;
}
<div id="container">
<div class="header">Header</div>
<div class="body">Body</div>
<div class="abc">ABC</div>
</div>
Explanation:
Since your .header is 100px, you can set the .abc to top: 100px; and set the right: 0 to move it to the extreme right within the parent since .abc is absolutely positioned to its parent.
If you are only allowed to use inline-styling, then try this:
<div style="width:500px;margin:0 auto;position:relative;">
<div style="background-color:yellow;height:100px">Header</div>
<div style="background-color:aquamarine; height: 400px">Body</div>
<div style="background-color:red;width:100px;position:absolute;top:100px;right:0;">ABC</div>
</div>
I added float: right to place the ABC div on the BODY div (overlap) and interchanged the position of the div BODY and ABC
<div style="width:500px;margin:0 auto;">
<div style="background-color:yellow;height:100px">Header</div>
<div style="background-color:red;width:100px;float: right;">ABC</div>
<div style="background-color:aquamarine; height: 400px">Body</div>
</div>
go to https://www.w3schools.com/css/css_positioning.asp for more information
To make layout you can use flexbox utilities. It's the most common and probably the easiest way to make layout.
I hope this is what you need.
For more infos check DOCS
*,
*::before,
*::after {
box-sizing: border-box;
}
.container-fluid{
width:100%;
}
header{
width:100%;
height:100px;
background:yellow
}
.row{
display:flex;
flex-wrap:wrap;
}
.col-left{
width:100%;
flex:0 0 75%;
max-width:75%;
background:blue;
height:100px
}
.col-right{
width:100%;
flex:0 0 25%;
max-width:25%;
background:red;
}
<div class="container-fluid">
<header></header>
<div class="row">
<div class="col-left"></div>
<div class="col-right"></div>
</div>
</div>

Css - add top property to each div, with top property multiply?

I have 10 div, and every one of them has position absolute, width: 100px and height 100px. In this case, we will see only one div, as rest of div overlaps each other.
So i wanted to ask, if i can in pure CSS, select those div, and add every one, top property which should look like:
fist div : top:0
second div: top:100px
third div: top:200px
And so on...
I tried with for example with this formula, but without success:
:nth-child(n+x);
Thanks.
Yes you can do that..
e.g.
<div id="wrapper">
<div class="first-div">
<div class="second-div">
</div>
<style type="text/css">
/* for first div */
#wrapper > div:nth-child(1) {
top: 0px;
}
</style>
using jQuery, you can set top dynamically.
e.g.
jQuery('#wrapper > div').each(function(index){
jQuery(this).css('top', index * 100);
});
If you want to use Alpesh Panchal approach and still have variable height divs, you can just store the total height in a variable:
http://jsfiddle.net/4u9jLm95/2/
HTML:
<div id="wrapper">
<div class="first"> </div>
<div class="second"> </div>
<div class="third"> </div>
<div class="fourth"> </div>
</div>
CSS:
#wrapper div {
background-color: teal;
width: 100px;
position: absolute;
}
.first {
height: 100px;
}
.second {
height: 200px;
}
.third {
height: 50px;
}
.fourth {
height: 150px;
}
JS:
var total = 0;
$('#wrapper > div').each(function(index){
$(this).css('top', total);
total += $(this).height() + 100;
});
However, as others said, using position: absolute might not be the best option here.

why does div continue to occupy 100% of the parent even if it has explicit width of 50%

I have two divs inside their parent div:
<div>
<div class="col-1"></div>
<div class="col-2"></div>
</div>
.col-1, .col-2 {
width: 50%;
}
They both have width of 50%. Yet they continue to occupy 100% of their parent even though their background is indeed 50% of the parent. Why so?
A div needs to be thought of as a division which, unless you tell it to float, will take all the width of a line, even though it may not fill it, this is because of the inherent css property display:block that's applied to a div. If you tell both divs to float by adding float:left; or float:right; to their css, they will allow other elements to share the width of their parent. Here's a snippet (you can see the result by clicking on the run button) of what it will look like
#container .child{
width:50%;
float:left;
}
.red{background:red;}
.blue{background:blue}
<div id='container'>
<div class='child red'>a</div>
<div class='child blue'>b</div>
</div>
Try this:
.col-1{
float:left;
}
.col-2{
float:right;
}
you can also experiment with the display property, for example display:inline-block could help you
Here is the Example program... You can use "float"
<div id="container" style="width:100%">
<div id="menu" style="background-color:blue; height:200px; width:50%; float:left; color:white;">
Div1</div>
<div id="content" style="background-color:#EEEEEE;height:200px;width:50%;float:left;">
Div2</div>
</div>
</body>
</html>
If you want to precisely control the position of a <div>, you should use position: absolute
<style>
.container {
position: relative;
}
.col-1, .col-2 {
position: absolute;
width: 50%;
top: 0;
}
.col-1 { left: 0; }
.col-2 { left: 50%; }
</style>
[...]
<div class="container">
<div class="col-1">[...]</div>
<div class="col-2">[...]</div>
</div>

Split page vertically using CSS

Sorry guys for the really simple question but I have tried to float one div left and one right with predefined widths along these lines
<div style="width: 100%;">
<div style="float:left; width: 80%">
</div>
<div style="float:right;">
</div>
</div>
Although this 'mostly' works it seems to mess up the other elements on the page below it.
So what is the correct why to split a HTML page vertically into two parts using CSS without effecting other elements on the page?
you can use..
<div style="width: 100%;">
<div style="float:left; width: 80%">
</div>
<div style="float:right;">
</div>
</div>
<div style="clear:both"></div>
now element below this will not be affected.
Just add overflow:auto; to parent div
<div style="width: 100%;overflow:auto;">
<div style="float:left; width: 80%">
</div>
<div style="float:right;">
</div>
</div>
Working Demo
I guess your elements on the page messes up because you don't clear out your floats, check this out
Demo
HTML
<div class="wrap">
<div class="floatleft"></div>
<div class="floatright"></div>
<div style="clear: both;"></div>
</div>
CSS
.wrap {
width: 100%;
}
.floatleft {
float:left;
width: 80%;
background-color: #ff0000;
height: 400px;
}
.floatright {
float: right;
background-color: #00ff00;
height: 400px;
width: 20%;
}
There can also be a solution by having both float to left.
Try this out:
Working Demo
P.S. This is just an improvement of Ankit's Answer
Check out this fiddle:
http://jsfiddle.net/G6N5T/1574/
CSS/HTML code:
.wrap {
width: 100%;
overflow:auto;
}
.fleft {
float:left;
width: 33%;
background:lightblue;
height: 400px;
}
.fcenter{
float:left;
width: 33%;
background:lightgreen;
height:400px;
margin-left:0.25%;
}
.fright {
float: right;
background:pink;
height: 400px;
width: 33.5%;
}
<div class="wrap">
<!--Updated on 10/8/2016; fixed center alignment percentage-->
<div class="fleft">Left</div>
<div class="fcenter">Center</div>
<div class="fright">Right</div>
</div>
This uses the CSS float property for left, right, and center alignments of divs on a page.
Alternatively, you can also use a special function known as the linear-gradient() function to split browser screen into two equal halves.
Check out the following code snippet:
body
{
background-image:linear-gradient(90deg, lightblue 50%, skyblue 50%);
}
Here, linear-gradient() function accepts three arguments
90deg for vertical division of screen.( Similarly, you can use 180deg for horizontal division of screen)
lightblue color is used to represent the left half of the screen.
skyblue color has been used to represent the right half of the split screen.
Here, 50% has been used for equal division of the browser screen. You can use any other value if you don't want an equal division of the screen.
Hope this helps. :)
Happy Coding!
Here is the flex-box approach:
CSS
.parent {
display:flex;
height:100vh;
}
.child{
flex-grow:1;
}
.left{
background:#ddd;
}
.center{
background:#666;
}
.right{
background:#999;
}
HTML
<div class="parent">
<div class="child left">Left</div>
<div class="child center">Center</div>
<div class="child right">Right</div>
</div>
You can try the same in js fiddle.

Resources