Reputation: 63
This is easiest to understand when running the code below. I'm looking to trigger the hover state on both a column and the middle row when hovering over the red bar.
I'd like to keep the columns based on flex and have the bar absolutely positioned over them.
Is this possible?
EDIT:
I'd like just the column that the mouse is hovering over to turn blue. Sorry for the ambiguity. Snippet updated with desired result.
The columns are divided by a white line. Hover over a grey area to see the column highlighted.
Thanks.
.root {
width: 100px;
height: 100px;
background: grey;
position: relative;
display: flex;
}
.column {
display: flex;
flex: 1 1 auto;
border-right: 1px solid white;
}
.column:hover {
background: blue;
}
.bar {
position: absolute;
left: 0;
right: 0;
top: 33px;
bottom: 33px;
background: red;
}
.bar:hover {
background: green;
}
.green {
background: green;
}
.blue {
background: blue;
}
Hover over the middle of the square. I want the middle column to turn blue and the bar to turn green.
Right now, only the bar turns green.
<div class='root'>
<div class='column'>
</div>
<div class='column'>
</div>
<div class='column'>
</div>
<div class='bar'>
</div>
</div>
Desired result:
<div class='root'>
<div class='column'>
</div>
<div class='column blue'>
</div>
<div class='column'>
</div>
<div class='bar green'>
</div>
</div>
Final Edit:
I'm providing a fully fleshed out version of what my use case is. I don't think CSS will be able to solve this, but I've accepted an answer that works for my original question.
function enterColumn() {
document.getElementById('column-status').innerHTML = 'In column'
}
function leaveColumn() {
document.getElementById('column-status').innerHTML = 'Out of column'
}
function enterBar() {
document.getElementById('bar-status').innerHTML = 'In bar'
}
function leaveBar() {
document.getElementById('bar-status').innerHTML = 'Out of bar'
}
.root {
width: 100px;
height: 100px;
background: grey;
position: relative;
display: flex;
}
.column {
display: flex;
flex: 1 1 auto;
border-right: 1px solid white;
}
.column:hover {
background: blue;
}
.bar-container {
position: absolute;
left: 0;
right: 0;
top: 33px;
bottom: 33px;
}
.bar {
position: absolute;
top: 0;
bottom: 0;
background: red;
}
.bar:hover {
background: green;
}
.green {
background: green;
}
.blue {
background: blue;
}
Hovering over a column or bar should be independent. Right now you can never have the 'In column' and 'In bar' status at the same time :(
<br />
It should scale to support any number of columns and any number of bars (where bars can be absolutely positioned anywhere along the x-axis)
<br />
Javascript events should be called on mouse events for both columns and bars.
<div class='root'>
<div class='column' onmouseenter='enterColumn();' onmouseleave='leaveColumn()'>
</div>
<div class='column' onmouseenter='enterColumn();' onmouseleave='leaveColumn()'>
</div>
<div class='column' onmouseenter='enterColumn();' onmouseleave='leaveColumn()'>
</div>
<div class='bar-container'>
<div class='bar' style='left: 5px; right: 40px' onmouseenter='enterBar();' onmouseleave='leaveBar()'>
</div>
<div class='bar' style='left: 65px; right: 5px' onmouseenter='enterBar();' onmouseleave='leaveBar()'>
</div>
</div>
</div>
<div id='column-status'>
Out of column
</div>
<div id='bar-status'>
Out of bar
</div>
Upvotes: 5
Views: 698
Reputation: 11609
There you go, after 2 hours of trial and error I finally came up with this little hack.
.root {
width: 100px;
height: 100px;
background: grey;
position: relative;
display: flex;
}
.column {
display: flex;
flex: 1 1 auto;
border-right: solid #fff 1px;
}
.column:hover {
background: blue;
}
.column .toggle{
margin-top:33px;
height: 33px;
width: 100%;
}
.column .toggle:before{
content: "";
position: absolute;
width: 34px;
height: 33px;
}
.column .toggle:hover:after{
content: "";
position: absolute;
z-index: 10;
left: 0;
right: 0;
top: 33px;
bottom: 33px;
background: green;
pointer-events:none;
}
.bar {
position: absolute;
z-index: 1;
left: 0;
right: 0;
top: 33px;
bottom: 33px;
background: red;
pointer-events:none;
}
<div class='root'>
<div class='column'><div class='toggle'></div></div>
<div class='column'><div class='toggle'></div></div>
<div class='column'><div class='toggle'></div></div>
<div class='bar'></div>
</div>
Now if you need to bind some javascript events to the .bar
element, attach them to .toggle
instead.
Upvotes: 2
Reputation:
If rearrangement of divs
is allowed, you can position the .bar
just before the middle .column
and use adjacent sibling selector.
.bar:hover + .column {
background: blue;
}
.root {
width: 100px;
height: 100px;
background: grey;
position: relative;
display: flex;
}
.column {
display: flex;
flex: 1 1 auto;
border-right: 1px solid white;
}
.column:hover {
background: blue;
}
.bar {
position: absolute;
left: 0;
right: 0;
top: 33px;
bottom: 33px;
background: red;
}
.bar:hover {
background: green;
}
.bar:hover + .column {
background: blue;
}
.green {
background: green;
}
.blue {
background: blue;
}
<div class='root'>
<div class='column'>
</div>
<div class='bar'>
</div>
<div class='column'>
</div>
<div class='column'>
</div>
</div>
Upvotes: 1
Reputation: 1181
If I understand what you mean, you mean that if you hover over any element the .column
should turn blue and .bar
should turn green. If that's the case then actually its pretty simple. Just place your hover
event on .root
element instead like so:
.root {
width: 100px;
height: 100px;
background: grey;
position: relative;
display: flex;
}
.column {
display: flex;
flex: 1 1 auto;
border-right: 1px solid white;
}
.bar {
position: absolute;
left: 0;
right: 0;
top: 33px;
bottom: 33px;
background: red;
}
.root:hover .bar {
background: green;
}
.root:hover .column {
background: blue;
}
<div class='root'>
<div class='column'>
</div>
<div class='column'>
</div>
<div class='column'>
</div>
<div class='bar'>
</div>
</div>
If that' not the case and you want the color of the .column
to change when you hover over the .bar
then check out the snippet below. Note that I've a changed the HTML markup a bit. Since .bar
has position: absolute
so it won't affect at all where you place it inside the .root
element.
.root {
width: 100px;
height: 100px;
background: grey;
position: relative;
display: flex;
}
.column {
display: flex;
flex: 1 1 auto;
border-right: 1px solid white;
}
.bar {
position: absolute;
left: 0;
right: 0;
top: 33px;
bottom: 33px;
background: red;
}
.bar:hover {
background: green;
}
.bar:hover ~ .column {
background: blue;
}
<div class='root'>
<div class='bar'>
</div>
<div class='column'>
</div>
<div class='column'>
</div>
<div class='column'>
</div>
</div>
Let me know if that helps you :-)
Upvotes: 0