So my understanding, which is demonstrated by the code below, is that :hover is true for a block element if the mouse is over the area defined for the element, or over any of its overflowed content or children. Note that the .outer div turns blue even if it is not over the text content, in particular.
I haven't yet been successful in isolating a small test case from an extremely complex page, however, which demonstrates that in some cases, the :hover effect only happens for the content, and the blank areas of the element do not cause :hover to be enabled.
This happens in both Firefox and Chrome. So my question is, what feature(s) causes blank regions of a div to be ignored for :hover effects? I haven't found reference in the css documents to such interactions, neither by starting at the description of the :hover feature, or any other references I can find to :hover.
And the other question would be, if there is some feature(s) that causes such behavior, would be conformant to the standard, or a bug in the browsers?
.outer:hover { background: blue; }
.outer {
font-size: 30px;
width: 10em;
height: 2.7em;
overflow: visible;
z-index: 4;
}
<div>
Just some uninvolved stuff
</div><div class=outer>
<p class=inner>item 1</p>
<p class=inner>longer item 2</p>
</div>
<div>
<p>
Just some more uninvolved stuff
</p>
</div>
#victoria I came to a solution, if there is no height give p float:left; clear:both; and hover on outer should make paragraph color blue that will remove white space hover.
Hope this will help !
.outer p{ float: left; clear:both;}
.outer:hover p{ background: blue; }
.outer {
font-size: 30px;
width: 10em;
height: 2.7em;
overflow: visible;
z-index: 4;
}
<div>
Just some uninvolved stuff
</div><div class=outer>
<p class=inner>item 1</p>
<p class=inner>longer item 2</p>
</div>
<div>
<p>
Just some more uninvolved stuff
</p>
</div>
If I understand correctly you want the same blue background area on hover but only while hovering on the "item 1" text. For this I would use a pseudo element to create the background color. One minor changes needed to the HTML, add a new unique class to the "hover trigger element:
<p class="inner trigger">item 1</p>
Then remove the rule for .outer:hover and add position: relative to the .outer div that will serve as the bounds of the blue background pseudo element we will add:
.outer {
// ...pre-existing CSS for .outer
position: relative;
}
Now you can have an absolutely positioned pseudo element with the blue background, only on hover of the "item 1" element:
.trigger:hover:before {
content: '';
position: absolute;
height: 100%;
width: 100%;
background-color: blue;
z-index: 0;
}
.content:hover {
background: #00c;
color: #cff;
cursor: default;
padding:0.2em;
}
.outer {
font-size: 30px;
width: 10em;
height: 2.7em;
overflow: visible;
z-index: 4;
}
<div>
Just some uninvolved stuff
</div><div class=outer>
<p><span class="content">item 1</span></p>
<p class=inner>longer item 2</p>
</div>
<div>
<p>
Just some more uninvolved stuff
</p>
</div>
The thing to remember is that with respect to CSS and HTML pages, there is a concept of a box model:
The CSS box model describes the rectangular boxes that are generated
for elements in the document tree and laid out according to the visual
formatting model.
See more here
So, if you just wish the background to be blue over specific text, you can target that text with SPAN tags and then assign a class, such as combining the pseudo hover class with .content, the class of the pair of SPAN tags enveloping "item 1". Note, I took the liberty of adding some other things to the hover event, such as also changing the color of the text and adding a little padding.
If you mean to hover over the div containing the text content and then have only the text content background and possibly text colors change, you could use JavaScript to program these changes, as follows:
var divs = document.getElementsByTagName("div");
var spans = document.getElementsByTagName("span");
divs[1].onmouseover = function() {
spans[0].style.backgroundColor = '#00c';
spans[0].style.color = '#ccf';
};
divs[1].onmouseout = function() {
spans[0].style.backgroundColor = '#fff';
spans[0].style.color = '#000';
};
.outer:hover {
cursor:crosshair;
}
.outer {
font-size: 30px;
width: 10em;
height: 2.7em;
overflow: visible;
z-index: 4;
}
<div>
Just some uninvolved stuff
</div>
<div class="outer">
<p><span>item 1</span></p>
<p class=inner>longer item 2</p>
</div>
<div>
<p>
Just some more uninvolved stuff
</p>
</div>
Related
Absolutely positioned element's width constrained when parent is relative
I have a navbar that has a menu on hover. The menu will contain tags and the length of the text in the tags will vary.
I want the menu to have a minimum and maxmium width child div has to have min-width/max-width set to. But no matter what the width of the menu is constrained to the min-width point.
Is it possible to make the child div ignore the width of the parent, while still keeping it a child (I cannot move this out of the parent, which I know would be an easy solution)?
here is an example of the behavior I am encountering: https://codepen.io/vee1234/pen/omQxWP
.navBar {
background-color: #222;
width: 50px;
min-height: 100%;
height: 100vh;
}
.navItem {
color: #a1a1a1;
padding-top: 15px;
padding-bottom: 15px;
position: relative;
}
.menu {
font-family: "Open Sans", sans-serif;
position: absolute;
display: none;
min-width: 200px;
max-width: 600px;
background-color: #333;
z-index: 100;
left: 100%;
top: 20%;
}
.menu div a {
display:block;
border: 1px solid red;
}
.navItem:hover .menu {
display: block;
}
<div class="navBar">
<div class="navItem">
<div>Nav Menu Trigger</div>
<div class="menu">
<div class="link">
<a>string of any length</a>
<a>string of any length - but this one is super long</a>
</div>
</div>
</div>
<div class="navItem">
<div>Nav Menu Trigger</div>
<div class="menu">
<div class="link">
<a>string of any length</a>
<a>string of any length - but this one is super long</a>
</div>
</div>
</div>
<div class="navItem">
<div>Nav Menu Trigger</div>
<div className="menu">
<div className="link">
<a>string of any length</a>
<a>string of any length - but this one is super long</a>
</div>
</div>
</div>
</div>
One trick is to make the relative element to be bigger by adding some padding-right that will not affect how text goes inside but will be counted in the width calculation of the absolute element. Then simply color only the part you want. You may also add negative margin to rectify the padding added.
.menu {
width:50px;
padding-right:500px;
margin-right:-500px;
background:#000 content-box;
height:100px;
position:relative;
color:#fff;
}
.menu div{
position:absolute;
top:0;
left:50px;
background:blue;
min-width:200px;
max-width:500px;
}
.menu div a {
border:1px solid;
display:block;
}
<div class="menu">
some text here
<div>
<a>some text here</a>
<a>some text here some text here some text here some text here some text here some text here some text here some text here</a>
<a>some text here</a>
</div>
</div>
Absolute positioning takes the element out of where it actually sits in the DOM and positions it where you tell it to. Because of this, the element looses references to parent elements that would help determine the width. You will need to set the width explicitly.
I am attempting to animate a block of content (collapsing 5 seconds after display), which is working, but I have this artifact where the display: none content after the collapse transition is still affecting layout, even when specifying overflow: hidden.
The code is as follows (and here is the codepen, as I am getting errors in the SO code runner):
setTimeout(() => {
$('#container').addClass('closing')
}, 5 * 1000)
#container {
transition: all linear 0.5s;
margin-bottom: 0rem;
min-height: 4rem;
opacity: 1;
.step {
transition: all linear 0.5s;
& * {
transition: all linear 0.5s;
}
}
&.closing {
min-height: 0rem;
height: 0rem;
opacity: 0;
overflow: hidden;
& * {
overflow: hidden;
min-height: 0rem;
height: 0rem;
padding-top: 0rem;
padding-bottom: 0rem;
}
}
}
#bottom-block {
height: 5rem;
width: 100%;
color: white;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.13/semantic.min.css" rel="stylesheet"/>
<div id="container" class="ui closing steps">
<div class="completed step">
<div class="content">
<div class="title">Shipping</div>
<div class="description">Choose your shipping options</div>
</div>
</div>
<div class="completed step">
<div class="content">
<div class="title">Billing</div>
<div class="description">Enter billing information</div>
</div>
</div>
<div class="active step">
<i class="info icon"></i>
<div class="content">
<div class="title">Confirm Order</div>
<div class="description">Verify order details</div>
</div>
</div>
</div>
<div id="bottom-block">
Testing
</div>
I have hacked around in the Styles on chrome to see if I can figure out what is causing this, but even when manually removing all the :before and :after pseudo-elements, it is still not fully collapsing.
Any ideas on how to get this to work?
(Note also that I am not using JQuery in the real code, but rather am setting classes through state management in React. Not relevant, just wanted to avoid "Why not use JQuery animations?" replies.)
Update:
Here is the forked codepen with the implemented change from below. Thanks for the help!
Your .ui.steps element has display inline-flex: therefore it's an inline element that is represented by a line box (https://www.w3.org/TR/2007/WD-css3-box-20070809/#line-box.).
It will occupy at least one line-height of vertical space in it's parent element, in this case the body element.
To illustrate that try reducing the font-size and line-height of your body: you'll see the space shrink. Of course hacking font-size is not a good solution, you can't even make it totally disappear because most browser will ignore font sizes of 0.
Edit : as #cmprogram have said, using display: none is usually the best move here.
Also, there is no such thing as display:hidden, I think you are confusing with visibility:hidden
The Problem is located in your
display: inline-flex;
Try using:
display: block;
or
display: flex;
instead.
Please look at this fiddle:
http://jsfiddle.net/Smartix/98sdrnkk/
The :before css property doesn't seem to work on a bootstrap row.
In the example above a centered red line should be displayed in the bacground of the div with class myline.
apply your :after pseudo class to this rule instead (after col-xs-12) :
<div class="row myline">
<div class="col-xs-12 myline">
<p>A red line should appear in the background of this row</p>
<p>The line should span from the top of the row...</p>
<p>... till here. Why is there no line?</p>
</div>
</div>
LIVE DEMO
or just add a height value and it will work properly :
.myline:before {
content: '';
top: 0;
bottom: 0;
position: absolute;
width: 4px;
background-color: red;
left: 50%;
margin-left: -1.5px;
height: 100px;
}
Live Demo
Updated question:
I have a bunch of DIV, they are part of a menusystem and are displayed using display:inline-box. Each div contains text. I want to have different background-color on the different DIVs and that the background fills up the whole height of the div and I also want the text to be vertically aligned along all the div. The fiddle below shows that the background color is only used around the text.
Old text:
I've spent hours on this. I found the vertical alignment quite easy (for example here: How to vertically align div inside another div without display:table-cell) but cannot figure out how i i can fill the whole div with the background color.
My example code is on fiddle: http://jsfiddle.net/joche/s7beksLt/
<div class="DivParent">
<div class="DivWhichNeedToBeVerticallyAligned bg1">
one line
</div>
<div class="DivWhichNeedToBeVerticallyAligned bg2">
<p>one line</p>
</div>
<div class="DivWhichNeedToBeVerticallyAligned bg3">
<p>one line</p>
<p>two line</p>
</div>
<div class="DivHelper"></div>
</div>
css:
.DivParent {
height: 100px;
border: 1px solid lime;
white-space: nowrap;
background-color:#deadad;
}
.DivWhichNeedToBeVerticallyAligned {
display: inline-block;
vertical-align: middle;
white-space: normal;
}
.bg1 {
background-color:#ffaaff;
}
.bg2 {
background-color:#ffffff;
}
.bg3 {
background-color:#ffffa9;
height:100%
}
.DivHelper {
display: inline-block;
vertical-align: middle;
height:100%;
}
I looked at your JSfiddle, and based on your code and question it's a little misleading. Especially since the code at the fiddle is not the code you posted in your question.
So you are trying to fill each div "cell" with a different background color? If so, those "cells" are of the .DivParent class. The internal divs (which you have labeled .bg1, .bg2, .bg3) are simply composed of the text itself - these divs only extend to the boundaries of the text they include (plus any margins, padding, etc.) The .DivParent is actually the entire "cell". See this image to see what I mean: http://i.imgur.com/67y3iWV.png
So all you need to do is apply the classes .bg1, .bg2, etc. to the parent classes. Here is my fiddle with each "cell" a different background color: http://jsfiddle.net/Arkatect/8vmp0124/
Notice in the HTML that the separate bg classes are on the parents, not the divs that just have the text:
<div class="DivParent bg2">
<div class="DivWhichNeedToBeVerticallyAligned">
<p>Two</p>
<p>Lines</p>
</div><div class="DivHelper"></div>
</div>
I hope this is what you were looking for.
Take a look at this one i made for you without .table-cell :http://jsfiddle.net/csdtesting/sos5sxkj/
.DivParent {
height: 100px;
border: 1px solid lime;
white-space: nowrap;
background: gray;
text-align: center;
position: relative;
}
.DivWhichNeedToBeVerticallyAligned {
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
background: red;
}
.DivHelper {
display: inline-block;
vertical-align: middle;
height: 100%;
}
<div class="DivParent">
<div class="DivWhichNeedToBeVerticallyAligned">one line</div>
<div class="DivHelper"></div>
</div>
<div class="DivParent">
<div class="DivWhichNeedToBeVerticallyAligned">
<p>Two</p>
<p>Lines</p>
</div>
<div class="DivHelper"></div>
</div>
<div id="parent" style="height:250px;width:250px;display:inline">
<div id="child" style="height:100%;width:100%;z-index:10001"></div>
<select style="height:100%;width:100%;z-index:10000"><option/></select>
</div>
My requirement is to include the select and child div elements inside the parent div in such a way that the child div is on top of the select element and completely covers it. Later I want to hide the child div based on an event and make the select element visible.
Both child div and select elements should occupy the entire size of parent div each on their own.
how can I achieve this?
http://jsfiddle.net/dyBjZ/2
#parent {
position: relative;
overflow: auto;
}
.child {
position: absolute;
height:100%;
width:100%;
}
<div id="parent">
<div class="child">
<select>
<option>One</option>
<option>Two</option>
</select>
</div>
<div class="child" id="child">Click me</div>
</div>
Taking input from the comments above, I was able to solve my problem. Here is what I did. Posting it here in case someone else lands up on this page searching.
<div id="parent" style="height:250px;width:250px">
<div id="child" style="display:block;height:100%;width:100%"></div>
<div id="selectParent" style="display:none;height:100%;width:100%">
<select><option/></select>
<div>
</div>
Based on the javascript event, I toggle display from block to none for child div. And toggle display from none to block in selectParent.
First issue is to give the #parent div a size, thus remove display: inline from its style.
Next, you could toggle for both elements from display: none to display: block, and v.v. But to reduce this by half, you could use absolute positioning which takes the element out of the default markup layout, as shown in this example.
HTML:
<div id="parent">
<div id="child"></div>
<select></select>
</div>
CSS:
#parent {
height: 250px;
width: 250px;
position: relative;
}
#child {
position: absolute;
background: #aaa;
height: 100%;
width: 100%;
}
select {
height: 100%;
width: 100%;
}
#child.hidden {
display: none;
}