Pull the previous sibling element - html

You can use margin-right, for example, to push a next sibling as seen below:
#parent {
background: tan;
font-size: 0;
}
#parent * {
display: inline-block;
width: 50px;
height: 50px;
}
#child1 {
background: teal;
margin-right: 100px;
}
#child2 {
background: olive;
}
<div id="parent">
<div id="child1"></div>
<div id="child2"></div>
</div>
I know there is no previous sibling selector in CSS. However, I wonder if there's a workaround so #child2 can pull #child1 to a distance of say, 20px. Here's a before-after screenshot:
Note: I don't want to give a margin value to #child1 or alter the HTML. The effect should be achieved using #child2 only.

This code works for me, it doesn't touch #child1 but #parent. Changed to classes instead of ids just to show the same code works for all.
.parent {
background: tan;
font-size: 0;
display: flex;
}
.parent * {
display: inline-block;
width: 50px;
height: 50px;
}
.child1 {
background: teal;
margin-right: 100px;
}
.child2 {
background: olive;
}
.child3 {
background: red;
}
.parent > div:only-child {
margin-right:100px;
margin-left:0px;
}
.parent > div {
margin-right:20px;
}
.parent > div:first-child:not(:last-child) {
margin-left:60px;
}
<div class="parent">
<div class="child1"></div>
<div class="child2"></div>
<div class="child3"></div>
</div>
<br>
<div class="parent">
<div class="child1"></div>
<div class="child2"></div>
</div>
<br>
<div class="parent">
<div class="child1"></div>
</div>

There is no previous sibling selector using pure CSS.
The possible workaround is using CSS flexbox.
First, set display property as flex to the #parent element. reverse the order of displaying child elements
<div id="child2"></div>
<div id="child1"></div>
We can correct this visually by setting
order:-1 to #child1.
Then we will address the #child1 by using
#parent>div:first-child+div
This means the next div after the first div, ie, #child1. Then set the styles.
#parent>div:first-child+div {
margin-right: 20px;
margin-left: 80px;
}
#parent {
background: tan;
display: flex;
}
#parent * {
width: 50px;
height: 50px;
}
#child1 {
background: teal;
order: -1;
}
#child2 {
background: olive;
}
#parent>div:first-child+div {
margin-right: 20px;
margin-left: 80px;
}
<div id="parent">
<div id="child2"></div>
<div id="child1"></div>
</div>
For better understandability, hover the #child2 then you can see the color change of its previous sibling.
#child2:hover+div {
background: brown;
}
#parent {
background: tan;
display: flex;
}
#parent * {
width: 50px;
height: 50px;
}
#child1 {
background: teal;
order: -1;
}
#child2 {
background: olive;
}
#parent>div:first-child+div {
margin-right: 20px;
margin-left: 80px;
}
#child2:hover+div {
background: brown;
}
<div id="parent">
<div id="child2"></div>
<div id="child1"></div>
</div>

According to your replies on the given answers your question should have been:
Can you 'pull the previous sibling element' by using CSS (only), and without changing the HTML?
The answer to that question is as simple as unsatisfying:
No, there is not.
Not even when you change the reading direction. I am sorry.

I am not sure whether this is what the OP is asking, but the following code, pulls the first child only when the second child exists, so in a sense, the second child pulls the first one :)
#parent > div:first-child:nth-last-child(2) {
margin-left:60px;
margin-right:20px;
}
Here is a working fiddle:
https://jsfiddle.net/06urn796/
Removing the second child, leaves the first one intact:
https://jsfiddle.net/06urn796/1/

#parent {
background: tan;
font-size: 0;
}
#parent * {
display: inline-block;
width: 50px;
height: 50px;
}
#parent div{
margin: 0px 20px;
}
#child1 {
background: teal;
}
#child2 {
background: olive;
}
<div id="parent">
<div id="child1"></div>
<div id="child2"></div>
</div>

Related

Make empty Div in Flex 100% Height

Using the following my .divider <div> is not showing. I guess this is because it is empty. If I add a "." in there, then I see it. Is it possible to make it 100% the height of the .wrapper without adding content?
.wrapper {
display: flex;
background-color: orange;
}
.left {
background-color: gray;
}
.divider {
background-color: green;
cursor: ew-resize;
width: 12px;
height: 100%;
}
.right {
flex-grow: 1;
background-color: yellow;
}
<div class="wrapper">
<div class="left">Left</div>
<div class="divider"></div>
<div class="right">Right</div>
</div>
https://jsfiddle.net/sub7fxk5/
Remove height: 100%; for .divider
.wrapper {
display: flex;
background-color: orange;
}
.left {
background-color: gray;
}
.divider {
background-color: green;
cursor: ew-resize;
width: 12px;
/* height: 100%; */
}
.right {
flex-grow: 1;
background-color: yellow;
}
<div class="wrapper">
<div class="left">Left</div>
<div class="divider"></div>
<div class="right">Right</div>
</div>
Removing the height and adding flex: 1 seems to help.
Is the result of the code below what you expect it to be?
The wrapper has no height, that means that setting a height to 100% would equal setting the height to 0.
the flex: 1 makes the item flexible even though it has no content and it shows.
Of course you can set a width too. So width: 12px would work. As would width: 100%; (which would push the left and right item to the other side)
You might also use a pseudo-element ::after as a divider. That would clean up your html a bit.
.wrapper {
display: flex;
background-color: orange;
}
.left {
background-color: gray;
}
.divider {
background-color: green;
cursor: ew-resize;
flex: 1;
}
.right {
flex-grow: 1;
background-color: yellow;
}
<div class="wrapper">
<div class="left">Left<br/><br/>Left</div>
<div class="divider"></div>
<div class="right">Right</div>
</div>

Multiple divs width transition with 100% fill of parent

I've got such an issue:
I want to increase hovered div width with simultaneously width decrease of his siblings. Everything works fine without setting transition property.
If I set transition and move mouse quickly. My divs don't fully fill their parent.
Here's my code:
#parent {
display: block;
position: relative;
}
#parent .child {
float: left;
height: 300px;
width: 20%;
background-color: red;
transition: width .5s;
}
#parent .child:nth-child(2) {
background-color: grey;
}
#parent .child:nth-child(3) {
background-color: green;
}
#parent .child:nth-child(4) {
background-color: yellow;
}
#parent .child:nth-child(5) {
background-color: brown;
}
#parent:hover .child {
width: 17.25%;
}
#parent:hover .child:hover {
width: 31%;
}
<div id="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
</div>
Do you have any ideas how to solve this problem? Can I fix it with pure CSS or I should use javascript for it?
Perhaps using Flexbox would give you a smoother effect.
You can adjust the flex property as you need to get the dimensions right.
body,
html {
/* for demo purposes */
padding: 0;
margin: 0;
}
#parent {
display: flex;
}
#parent .child {
height: 300px;
flex: 1 1 auto;
background-color: red;
transition: all .5s;
}
#parent .child:nth-child(2) {
background-color: grey;
}
#parent .child:nth-child(3) {
background-color: green;
}
#parent .child:nth-child(4) {
background-color: yellow;
}
#parent .child:nth-child(5) {
background-color: brown;
}
#parent .child:hover {
flex: 2 1 auto;
}
<div id="parent">
<div class="child">1</div>
<div class="child">2</div>
<div class="child">3</div>
<div class="child">4</div>
<div class="child">5</div>
</div>

Floating div to go below partner

Consider the following HTML structure,
<div class='floated' id='div1'></div>
<div class='floated' id='div2'></div>
<div class='floated' id='div3'></div>
with the following CSS:
.floated {
width: 50%;
float: left;
}
#div1 {
height: 300px;
background-color:red;
}
#div2 {
height: 30px;
background-color: green;
}
#div3 {
height: 30px;
background-color: yellow;
}
This way, #div1 will take up a 300px tall part of the left side of the page, while #div2 and #div3 will get floated to the right side of the page. How could I set up my CSS, so #div1 and #div2 takes up a single row(of height 300px, the maximum height of the two), and #div3 will be placed right below #div1?
I am not controling the height of these divs, this is dynamic, it is possible that sometimes the first one will be only 20 pixels, and the second one will be 1000 pixels, and the other way around is also a possibility
Here's a fiddle: https://jsfiddle.net/1u55fukj/
You can use Flexbox on parent element (body in this case) and use flex-wrap: wrap. This will always make both div's in same row equal height or equal to height of taller one DEMO
body {
display: flex;
flex-wrap: wrap;
}
.floated {
flex: 0 0 50%;
}
#div1 {
height: 300px;
background-color: red;
}
#div2 {
background-color: green;
}
#div3 {
height: 30px;
background-color: yellow;
}
<div class='floated' id='div1'></div>
<div class='floated' id='div2'></div>
<div class='floated' id='div3'></div>
If there will be only 2 divs in row, then you can try to give clear:left to odd child.
.floated {
width: 50%;
float: left;
}
#div1 {
height: 300px;
background-color: red;
}
#div2 {
height: 30px;
background-color: green;
}
#div3 {
height: 30px;
background-color: yellow;
}
div.floated:nth-child(odd) {
clear: left
}
<div class='floated' id='div1'>
</div>
<div class='floated' id='div2'>
</div>
<div class='floated' id='div3'>
</div>
flexbox is your best option i think.
you could use a div container and then use display flex
.container{
height: 500px;
width: 100%;
display: flex;
flex-flow: row wrap;
justify-content: center;
}
.floated {
width: 50%;
}
#div1 {
height: 30%;
background-color:red;
}
#div2 {
height: 60%;
background-color: green;
}
#div3 {
height: 40%;
background-color: yellow;
}
<div class="container">
<div class="floated" id="div1"></div>
<div class="floated" id="div2"></div>
<div class="floated" id="div3"></div>
</div>
you can also center the 3rd div and a lot more :D. Flexbox have a good crossbrowsing support using -moz-, -webkit- etc,

Embedded divs in header: css issue

I am trying to create the following structure using embedded divs inside a header:
The height and width of the red part is known and fix
The height of the green rectangle is known and fix
The overall width of the frame can vary, but is never smaller than the red part
I have tried with the following html code:
<header id="header">
<div id="yellowAndGreen">
<div id="yellow"></div>
<div id="green"></div>
</div>
<div id="red"></div>
</header>
and the following CSS:
#header {
width: 400px;
}
#yellowAndGreen {
}
#yellow {
background-color: yelow;
}
#green {
background-color: green;
height: 40px;
}
#red {
height: 150px;
width: 150px;
background-color: red;
}
but it does not work. I have created a JsFiddle. Can anyone modify it to create what I am looking for?
Use float:right; to make the red box float to the right. You'll need to adjust the html:
<header id="header">
<div id="alldivs">
<div id="red"></div>
<div id="yellow"></div>
<div id="green"></div>
</div>
</header>
and the css:
#header {
width: 400px;
}
#yellow {
background-color: yellow;
height:110px;
}
#green {
background-color: green;
height: 40px;
}
#red {
height: 150px;
width: 150px;
background-color: red;
float:right;
}
Please note you had misspelled "yellow", and that you need to set a height for the yellow <div>.
Finally here is the adjusted fiddle
Hope this helps
This uses flexbox, which has some support drop off on older browsers. I've excluded vendor-specific attirbutes for simplicity.
#header {
width: 400px;
display: flex;
}
#yellowAndGreen {
flex: 1 1 auto;
display: flex;
flex-direction: column;
}
#yellow {
background-color: yellow;
flex-grow: 1;
}
#green {
background-color: green;
height: 40px;
}
#red {
height: 150px;
width: 150px;
background-color: red;
}
No floats or flexbox necessary!
Rearranged your HTML a bit. Set #header background-color to red and min-width so it will never be too small. Use calc() for #yellow's width so that the background red of it's parent will always be 150px wide.
#header {
width: 400px;
background-color: red;
width: 100%;
min-width: 150px;
}
#yellow {
height: 150px;
width: calc(100% - 150px);
background-color: yellow;
}
#green {
background-color: green;
height: 40px;
}
<header id="header">
<div id="yellow"></div>
<div id="green"></div>
</header>

Div content in wrong position

I'm trying to put 3 divs in the same row as the following code.
My CSS and HTML:
.row {
display: table;
width: 100%
}
.row > div {
display: table-cell;
height:30px; /*demo purposes */
}
#left-bar {
width: 10%;
background-color: #FF0000;
}
#middle-bar {
width: 70%;
background-color: #6600FF;
}
#right-bar {
width: 20%;
background-color: #99FF99;
}
<div class="row">
<div id="left-bar"> here I have an accordion </div>
<div id="middle-bar"> heve a have my canvas </div>
<div id="right-bar"> and here I have an editor</div>
</div>
Somehow the content of the middle-bar(my canvas) is positioned in the correct place, but the other two divs contents are in the bottom of the page as you can see here see photo. Do you guys know why this is happening?
After discussing the project further with you in the comments, and in chat, I think you should take an approach that uses flexbox instead. The code is fairly straight forward:
.container {
display: flex;
}
.left { flex-basis: 10%; background: #F99; }
.right { flex-basis: 20%; background: #99F; }
.middle { flex-basis: 70%; background: #9F9; }
<div class="container">
<div class="left">L</div>
<div class="middle">C</div>
<div class="right">R</div>
</div>
I only managed width.
There's nothing problematic see this.
.row {
display: table;
width: 100%
}
.row > div {
display: table-cell;
height:30px; /*demo purposes */
}
#left-bar {
width: 20%;
background-color: #FF0000;
}
#middle-bar {
width: 60%;
background-color: #6600FF;
}
#right-bar {
width: 20%;
background-color: #99FF99;
}
<div class="row">
<div id="left-bar"> here I have an accordion </div>
<div id="middle-bar"> heve a have my canvas </div>
<div id="right-bar"> and here I have an editor</div>
</div>