Div with heading and text inside. When the div is hovered the background changes and a 'toast' rises from the bottom of the div. Entire div is clickable based on the heading link and done in css.
The problem : in all versions of IE the link is only clickable when the cursor is NOT over text within the div (same problem in the fiddle example). It works correctly in FF, Opera, and Safari.
JSFiddle - the example
<div class="one-third">
<div class="inside">
<h3>Testing</h3>
<p>This some text inside the testing blox blah blah blah blah blah.</p>
<p>and some more and some more.and some more and some morep>and some more and some moreand some more and some moreand some more and some moreand some more and some moreand some more and some moreand some more and some more.</p>
<span class="toast">View more stuff</span>
</div>
</div>
css:
.one-third{
border:1px solid #d8d8d8;
margin:35px 9px 0;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
border-radius: 6px;
background:#ffffff;
text-align:center;
position:relative;
overflow:hidden;
cursor: pointer;
padding:25px 0 0 0;
}
.one-third:hover{
background: #eeeeee;
}
.inside{
height:185px;
}
.inside h3 a, .inside h3 a:hover{ /*entire div is link*/
font-size: 20px;
color:#30629a;
text-decoration:none;
position:absolute;
width:100%;
height:100%;
top:13px;
left: 0;
z-index: 1;
}
.inside p{
padding:15px 15px 0 15px;
}
.toast{
background: rgb(71, 71, 71); /* Fall-back for browsers that don't support rgba */
background: rgba(0, 0, 0, .7);
display: block;
position: absolute;
left: 0;
width: 100%;
bottom: -30px;
line-height:30px;
color: #fff;
text-shadow:0 1px 1px #111111;
font-size:14px;
text-align: center;
transition: all 0.1s linear 0s; /*no moz, webkit, or o because radius is needed and won't scroll right*/
-moz-border-radius: 0 0 6px 6px;
-webkit-border-radius: 0 0 6px 6px;
border-radius: 0 0 6px 6px;
}
.one-third:hover .toast {
bottom: 0;
}
Another solution is to add
background:url("datdata:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
to .inside h3 a, .inside h3 a:hover. It's a base64 transparent gif that solves the problem for IE.
GIf found here: http://css-tricks.com/snippets/html/base64-encode-of-1x1px-transparent-gif/
One solution is to move the 'a' outside if the h3. IE is having a problem with that element being behind the 'p' tags.
<a href="/#"><h3>Testing</h3>
<p>...</p></a>
http://jsfiddle.net/Zp2Rp/14/
Related
I need to create a solid color inset border. This is the bit of CSS I'm using:
border: 10px inset rgba(51,153,0,0.65);
Unfortunately that creates a 3D ridged border (ignore the squares and dark description box)
You could use box-shadow, possibly:
#something {
background: transparent url(https://i.stack.imgur.com/RL5UH.png) 50% 50% no-repeat;
min-width: 300px;
min-height: 300px;
box-shadow: inset 0 0 10px #0f0;
}
#something {
background: transparent url(https://i.stack.imgur.com/RL5UH.png) 50% 50% no-repeat;
min-width: 300px;
min-height: 300px;
box-shadow: inset 0 0 10px #0f0;
}
<div id="something"></div>
This has the advantage that it will overlay the background-image of the div, but it is, of course, blurred (as you'd expect from the box-shadow property). To build up the density of the shadow you can add additional shadows of course:
#something {
background: transparent url(https://i.stack.imgur.com/RL5UH.png) 50% 50% no-repeat;
min-width: 300px;
min-height: 300px;
box-shadow: inset 0 0 20px #0f0, inset 0 0 20px #0f0, inset 0 0 20px #0f0;
}
#something {
background: transparent url(https://i.stack.imgur.com/RL5UH.png) 50% 50% no-repeat;
min-width: 300px;
min-height: 300px;
box-shadow: inset 0 0 20px #0f0, inset 0 0 20px #0f0, inset 0 0 20px #0f0;
}
<div id="something"></div>
Edited because I realised that I'm an idiot, and forgot to offer the simplest solution first, which is using an otherwise-empty child element to apply the borders over the background:
#something {
background: transparent url(https://i.stack.imgur.com/RL5UH.png) 50% 50% no-repeat;
min-width: 300px;
min-height: 300px;
padding: 0;
position: relative;
}
#something div {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border: 10px solid rgba(0, 255, 0, 0.6);
}
<div id="something">
<div></div>
</div>
Edited after #CoryDanielson's comment, below:
jsfiddle.net/dPcDu/2 you can add a 4th px parameter for the box-shadow that does the spread and will more easily reflect his images.
#something {
background: transparent url(https://i.stack.imgur.com/RL5UH.png) 50% 50% no-repeat;
min-width: 300px;
min-height: 300px;
box-shadow: inset 0 0 0 10px rgba(0, 255, 0, 0.5);
}
<div id="something"></div>
I would recomnend using box-sizing.
*{
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
-ms-box-sizing:border-box;
box-sizing:border-box;
}
#bar{
border: 10px solid green;
}
To produce a border inset within an element the only solution I've found (and I've tried all the suggestions in this thread to no avail) is to use a pseudo-element such as :before
E.g.
.has-inset-border:before {
content: " "; /* to ensure it displays */
position: absolute;
left: 10px;
right: 10px;
top: 10px;
bottom: 10px;
border: 4px dashed red;
pointer-events: none; /* user can't click on it */
}
The box-sizing property won't work, as the border always ends up outside everything.
The box-shadow options has the dual disadvantages of not really working and not being supported as widely (and costing more CPU cycles to render, if you care).
It's an old trick, but I still find the easiest way to do this is to use outline-offset with a negative value (example below uses -6px). Here's a fiddle of itβI've made the outer border red and the outline white to differentiate the two:
.outline-offset {
width:300px;
height:200px;
background:#333c4b;
border:2px solid red;
outline:2px #fff solid;
outline-offset:-6px;
}
<div class="outline-offset"></div>
If you want to make sure the border is on the inside of your element, you can use
box-sizing:border-box;
this will place the following border on the inside of the element:
border: 10px solid black;
(similar result you'd get using the additonal parameter inset on box-shadow, but instead this one is for the real border and you can still use your shadow for something else.)
Note to another answer above: as soon as you use any inset on box-shadow of a certain element, you are limited to a maximum of 2 box-shadows on that element and would require a wrapper div for further shadowing.
Both solutions should as well get you rid of the undesired 3D effects.
Also note both solutions are stackable (see the example I've added in 2018)
.example-border {
width:100px;
height:100px;
border:40px solid blue;
box-sizing:border-box;
float:left;
}
.example-shadow {
width:100px;
height:100px;
float:left;
margin-left:20px;
box-shadow:0 0 0 40px green inset;
}
.example-combined {
width:100px;
height:100px;
float:left;
margin-left:20px;
border:20px solid orange;
box-sizing:border-box;
box-shadow:0 0 0 20px red inset;
}
<div class="example-border"></div>
<div class="example-shadow"></div>
<div class="example-combined"></div>
I don't know what you are comparing to.
But a super simple way to have a border look inset when compared to other non-bordered items is to add a border: ?px solid transparent; to whatever items do not have a border.
It will make the bordered item look inset.
http://jsfiddle.net/cmunns/cgrtd/
Simple SCSS solution with pseudo-elements
Live demo: https://codepen.io/vlasterx/pen/xaMgag
// Change border size here
$border-width: 5px;
.element-with-border {
display: flex;
height: 100px;
width: 100%;
position: relative;
background-color: #f2f2f2;
box-sizing: border-box;
// Use pseudo-element to create inset border
&:before {
position: absolute;
content: ' ';
display: flex;
border: $border-width solid black;
left: 0;
right: 0;
top: 0;
bottom: 0;
border: $border-width solid black;
// Important: We must deduct border size from width and height
width: calc(100% - $border-width);
height: calc(100% - $border-width);
}
}
<div class="element-with-border">
Lorem ipsum dolor sit amet
</div>
You can do this:
.thing {
border: 2px solid transparent;
}
.thing:hover {
border: 2px solid green;
}
If box-sizing is not an option, another way to do this is just to make it a child of the sized element.
Demo
CSS
.box {
width: 100px;
height: 100px;
display: inline-block;
margin-right: 5px;
}
.border {
border: 1px solid;
display: block;
}
.medium { border-width: 10px; }
.large { border-width: 25px; }
HTML
<div class="box">
<div class="border small">A</div>
</div>
<div class="box">
<div class="border medium">B</div>
</div>
<div class="box">
<div class="border large">C</div>
</div>
I know this is three years old, but thought it might be helpful to someone.
The concept is to use the :after (or :before) selector to position a border within the parent element.
.container{
position:relative; /*Position must be set to something*/
}
.container:after{
position:relative;
top: 0;
content:"";
left:0;
height: 100%; /*Set pixel height and width if not defined in parent element*/
width: 100%;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
-ms-box-sizing:border-box;
box-sizing:border-box;
border:1px solid #000; /*set your border style*/
}
You may use background-clip: border-box;
Example:
.example {
padding: 2em;
border: 10px solid rgba(51,153,0,0.65);
background-clip: border-box;
background-color: yellow;
}
<div class="example">Example with background-clip: border-box;</div>
So I was trying to have a border appear on hover but it moved the entire bottom bar of the main menu which didn't look all that good I fixed it with the following:
#top-menu .menu-item a:hover {
border-bottom:4px solid #ec1c24;
padding-bottom:14px !important;
}
#top-menu .menu-item a {
padding-bottom:18px !important;
}
I hope this will help someone out there.
Simpler + better | img tag | z-index | link image | "alt" attribute
I figured out a method where you do not need to use the image as a background image but use the img HTML tag inside the div, and using z-index of the div as a negative value.
Advantages:
The image can now become a link to a lightbox or to another page
The img:hover style can now change image itself, for example:
black/white to color, low to high opacity, and much more.
Animations of image are possible The image is more accessible because
of the alt tag you can use.
For SEO the alt tag is important for keywords
#borders {
margin: 10px auto;
width: 300px;
height: 300px;
position:relative;
box-shadow: inset 0 0 0 10px rgba(0, 255, 0, 0.5);
}
img {
position:absolute;
top:0;
bottom:0;
left:0;
right: 0;
z-index: -1;
}
<div id="borders">
<img src="https://i.stack.imgur.com/RL5UH.png">
</div>
I can't understand why the text I'm trying to get in the bubble box won't be there.
Here is the link to a picture of what I see
I'm super newbie and this might be a very stupid question, but I spent like 40 minutes trying to figure out what's wrong.
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
.bubble
{
position: absolute;
width: 230px;
height: 33px;
text-align: left;
font-size: 10px;
line-height: 100px;
background-color: #00ff00;
border-radius: 10px;
margin-top: 100px;
margin-left: 200px;
}
.bubble:after
{
content: '';
position: absolute;
width: 0;
height: 0;
left: 20px;
top: 33px;
border: 22px solid;
border-color: #00ff00 transparent transparent #00ff00;
}
</style>
</head>
<div class="bubble">im lemon im a little spaghetti</div>
</html>
Help
You should define line-height: 33px, because that is the height of your bubble
See fiddle
I suggest you add a bit of padding, so that the text won't be stuck at the left border of the bubble. Like that :
padding: 0 5px;
That will add 5px of padding to the left and to the right, that is a shorthand for :
padding: 0 5px 0 5px; which is itself a shorthand for
padding-top: 0;
padding-right: 5px;
padding-bottom: 0;
padding-left: 5px;
See updated fiddle
Looks like its overlapping. You should look at this example, there are variety of layouts and other css options to accomplish what you're trying to do covering multiple browsers.
http://nicolasgallagher.com/pure-css-speech-bubbles/demo/
Here is the CSS for the first bubble text:
.triangle-isosceles {
position:relative;
padding:15px;
margin:1em 0 3em;
color:#000;
background:#f3961c; /* default background for browsers without gradient support */
/* css3 */
background:-webkit-gradient(linear, 0 0, 0 100%, from(#f9d835), to(#f3961c));
background:-moz-linear-gradient(#f9d835, #f3961c);
background:-o-linear-gradient(#f9d835, #f3961c);
background:linear-gradient(#f9d835, #f3961c);
-webkit-border-radius:10px;
-moz-border-radius:10px;
border-radius:10px;
}
/* Variant : for top positioned triangle
------------------------------------------ */
.triangle-isosceles.top {
background:-webkit-gradient(linear, 0 0, 0 100%, from(#f3961c), to(#f9d835));
background:-moz-linear-gradient(#f3961c, #f9d835);
background:-o-linear-gradient(#f3961c, #f9d835);
background:linear-gradient(#f3961c, #f9d835);
}
The complete CSS:
http://nicolasgallagher.com/pure-css-speech-bubbles/demo/default.css
Basically you'd put the text inside the paragraph tag by calling the class:
<p class="triangle-isosceles">This only needs one HTML element.</p>
#ref: http://nicolasgallagher.com/pure-css-speech-bubbles/demo/
I'm making a website where there's a menu, but the problem is that menu always has opacity even when the option is not included, and when i hover over an option in it, i notice that the mouse can click on some element beneath this menu, i don't want this to happen so how to prevent this from happening ?
As you see those two rounded check marks still can be clicked even if the menu is open.
EDIT:
It turned out to be position:absolute; that causes this problem, i have no idea why is that. Actually i'm not even sure about that. Still waiting for an answer.
And turned out too that any element in the page that has position:absolute; behaves the same!
<div class="mainTaskWrapper clearfix">
<!-- All ID names are to be changed later on -->
<div class="mainMarker"></div>
<label for="task1">This is task1</label>
<!-- holder, checkButton and optTrigger are the underneath elements -->
<div class="holder"></div>
<div class="subTrigger"></div>
<div class="checkButton"></div>
<div class="optTrigger"></div>
<!-- the following is for the drop-down menu -->
<div class="mainOptions">
<ul>
<li id="mainInfo">Details</li>
<li id="mainDivide">Divide</li>
<li id="mainEdit">Edit</li>
<li id="mainDelete">Delete</li>
</ul>
</div>
</div>
And that's the styling of it :
//This is for the tick buttons underneath the drop-down menu
div.holder , div.checkButton, div.optTrigger {
display: inline-block;
opacity: 0.2;
height: 20px;
width: 20px;
float:right;
margin-top: 0px;
margin-left:5px;
cursor: pointer;
}
div.checkButton {
background: url('../img/check_checked.png') no-repeat center;
}
div.checkButton:hover {
opacity: 1.0;
}
div.optTrigger {
background: url('../img/toggle_down_light.png') no-repeat center;
}
div.optTrigger:hover{
opacity: 1.0;
}
div.optTrigger.active{
opacity: 0.9;
border-radius: 5px 5px 0px 0px;
background: url('../img/toggle_down_light_opened.png') no-repeat center darkslategray;
}
div.holder {
opacity: 1.0;
background: url('../img/holder.png') no-repeat center;
cursor: move;
}
//The following is for the drop-down menu
.mainOptions {
display:inline-block;
position:absolute;
background : darkslategrey;
opacity: 1.0;
left : 626px;
top:25px;
border-radius: 5px 0px 5px 5px;
}
.mainOptions li {
color : lightgrey;
border-bottom: 1px solid grey;
padding:5px 15px;
font-size : 12px;
cursor:pointer;
}
.mainOptions li:hover {
background : grey;
}
.mainOptions li:last-of-type:hover{
border-radius: 0px 0px 5px 5px;
}
.mainOptions li:first-of-type:hover{
border-radius: 5px 0px 0px 0px;
}
.mainOptions li:last-of-type{
border:none;
}
How to implement this type of style to text using only css3, means a horizontal line in the middle of the tag... Can it be possible using pure css...
Here's my structure:-
<p class="datedAside">4 weeks ago</p>
You can achieve this with pure css using linear gradient as background:
<p class="datedAside">4 weeks ago</p>
<style>
p {
background: linear-gradient(180deg,
rgba(0,0,0,0) calc(50% - 1px),
rgba(192,192,192,1) calc(50%),
rgba(0,0,0,0) calc(50% + 1px)
);
}
</style>
https://jsfiddle.net/klesun/aujrkpLk/
Here's one way to do it by adding a span inside the p.
HTML:
<p class="datedAside"> <span> 4 weeks ago </span> </p>β
CSS:
p {background: #000; height:1px; margin-top:10px;}
p span{background: #fff; padding:10px; position:relative; top:-10px; left: 20px}β
DEMO: http://jsfiddle.net/9GMJz/
One of the simplest way I know, you can achieve this like this:
HTML
<p>Your text goes here</p>
<hr>
β
CSS
p {
background: #fff; // or whatever is your bg-color
display:inline-block;
padding-right: 1em;
line-height: 1.2em;
}
p+hr {
margin-top: -0.6em;
}
JSFiddle
http://jsfiddle.net/cTMXa/1/
You can do it with a 1% gradient like this
.datedAside {
background: linear-gradient(0deg, transparent 49%, #000 50%, transparent 51%);
}
.datedAside span{
background: #FFF;
padding: 0 0.5rem;
}
You'll nedd the extra span to be the same background color as the background of the component to make it look like it has "deleted" the line going behind the text.
You could add a pseudo-element to the paragraph selector like so:
p {
::before {
border-top: 10px solid #0066a4;
content:"";
margin: 0 auto; /* this centers the line to the full width specified */
position: absolute; /* positioning must be absolute here, and relative positioning must be applied to the parent */
top: 12px; left: 0; right: 0; bottom: 0;
z-index: -1;
}
}
See this CodePen by Eric Rasch for a working example: https://codepen.io/ericrasch/pen/Irlpm
An alternative with flex and ::before and ::after.
With this solution, you don't need to use a background for the content.
With this HTML markup :
<p class="datedAside"><span>4 weeks ago</span></p>
And this CSS :
.datedAside {
display: flex;
flex-flow: nowrap;
justify-content: space-between;
align-items: center;
}
.datedAside span {
padding: 1em;
}
.datedAside::before,
.datedAside::after {
flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
content: " ";
height: 0px;
border-bottom: 1px solid black;
}
Artur's solution creates a line however if you increase the px value it becomes clear that the line is still a gradient. This can be fixed by using a start and stop for the middle colour as such:
p {
background: linear-gradient(to bottom, white calc(50% - 1px), black calc(50% - 1px) calc(50% + 1px), white calc(50% + 1px));
}
The line will be double the thickness of the px value given (due to +px -px) so the above gives a horizontal 2px line across the center of the element.
Another way would be to use the linear-gradient as a background and place it in the middle of the paragraph or div.
p {
background-image: linear-gradient(red, red);
background-size: 100% 1px; /* add your height of the line here*/
background-repeat: no-repeat;
background-position: 50% 50%; /*place it in the middle */
}
I was update from fork for my solution.
http://jsfiddle.net/0f9catjy/
Html Block
<h1 class="lined"><span>H1 Lined Sample</span></h2>
<h2 class="lined"><span>H2 Lined Sample</span></h2>
<h3 class="lined"><span>H3 Lined Sample</span></h2>
<h1 class="lined lined-double"><span>H1 Double-lined Sample</span></h1>
<h2 class="lined lined-double"><span>H1 Double-lined Sample</span></h2>
Css Block
/**
* Horizontal Type Line Behind Text
* Inspired by this discussion # CSS-Tricks: http://css-tricks.com/forums/discussion/comment/51357#Comment_51357
* Available on jsFiddle: http://jsfiddle.net/ericrasch/jAXXA/
* Available on Dabblet: http://dabblet.com/gist/2045198
* Available on GitHub Gist: https://gist.github.com/2045198
*/
h1, .h1 { font-size: 2.5rem; }
h2, .h2 { font-size: 2rem; }
h3, .h3 { font-size: 1.75rem; }
h4, .h4 { font-size: 2.5rem; }
h5, .h5 { font-size: 1.25rem; }
h6, .h6 { font-size: 1rem; }
h1.lined, h2.lined, h3.lined, h4.lined, h5.lined, h6.lined
{
font-family: sans-serif;
position: relative;
text-align: left;
z-index: 1;
}
h1.lined:before,
h2.lined:before,
h3.lined:before,
h4.lined:before,
h5.lined:before,
h6.lined:before
{
border-top: 2px solid #dfdfdf;
content: "";
margin: 0 auto;
position: absolute;
top: calc(50% - 2px);
left: 0;
right: 0;
bottom: 0;
width: 95%;
z-index: -1;
}
h1.lined span,
h2.lined span,
h3.lined span,
h4.lined span,
h5.lined span,
h6.lined span
{
background: #fff;
padding: 0 15px;
}
h1.lined-double:before,
h2.lined-double:before,
h3.lined-double:before,
h4.lined-double:before,
h5.lined-double:before,
h6.lined-double:before
{
border-top: none;
}
h1.lined-double:after,
h2.lined-double:after,
h3.lined-double:after,
h4.lined-double:after,
h5.lined-double:after,
h6.lined-double:after
{
border-bottom: 1px solid blue;
-webkit-box-shadow: 0 3px 0 0 red;
-moz-box-shadow: 0 3px 0 0 red;
box-shadow: 0 3px 0 0 red;
content: "";
margin: 0 auto;
position: absolute;
top: calc(50% - 6px);
left: 0;
right: 0;
width: 95%;
z-index: -1;
transform: translateY(calc(-50% + 3px));
}
/** END
* Horizontal Type Line Behind Text
*/
I have an unordered list full or anchors. I have a CSS :Hover event that adds borders to it but all the anchors to the left slightly adjust when i hover because it is adding 1px to the width and auto adjusting. how do i make sure the positioning is absolute?
div a:visited, #homeheader a{
text-decoration:none;
color:black;
margin-right:5px;
}
div a:hover{
background-color:#D0DDF2;
border-radius:5px;
border:1px solid #102447;
}
div li{
padding:0;
margin:0px 10px;
display:inline;
font-size:1em;
}
<div>
<ul>
<li>this</li>
<li>that</li>
<li>this again</li>
<li>that again</li>
</ul>
</div>
I made a JS Fiddle demo here.
You can add a transparent border to the non-hover state to avoid the "jumpiness" when the border appears:
http://jsfiddle.net/TEUhM/3/
#homeheader a:visited, #homeheader a{
border:1px solid transparent;
}
You can also use outline, which won't affect the width i.e. so no "jump" effect. However,support for a rounded outline may be limited.
You could use a box shadow, rather than a border for this sort of functionality.
This works because your shadow doesn't 'take size in the DOM', and so won't affect the positioning, unlike that of a border.
Try using a declaration like
box-shadow:0 0 1px 1px #102447;
instead of your
border:1px solid #102447;
on your hover state.
Below is a quick demo of this in action:
DEMO
#homeheader a:visited,
#homeheader a {
text-decoration: none;
color: black;
margin-right: 5px;
}
#homeheader a:hover {
background-color: #D0DDF2;
border-radius: 5px;
box-shadow: 0 0 1px #102447;
}
#homeheader li {
padding: 0;
margin: 0px 10px;
display: inline;
font-size: 1em;
}
<div id="homecontainer">
<div id="homeheader">
<ul>
<li>this
</li>
<li>that
</li>
<li>this again
</li>
<li>that again
</li>
</ul>
</div>
</div>
Add a margin of 1px and remove that margin on hover, so it is replaced by the border.
http://jsfiddle.net/TEUhM/4/
After taking a long time pressure i found a cool solution.
Hope that it will help others.
on the add the folloing code :
HTML
<div class="border-test">
<h2> title </h2>
<p> Technology founders churn rate niche market </p>
</div>
CSS
.border-test {
outline: 1px solid red;
border: 5px solid transparent;
}
.border-test:hover {
outline: 0px solid transparent;
border: 5px solid red;
}
Check live : Live Demo
Hope it will help.
No one has mentioned it here, but the best and simplest solution to this in my opinion is to use "box shadow" instead of borders. The magic is on the "inset" value which allows it be like a boarder.
box-shadow: inset 0 -3px 0 0 red;
You can offset the X or Y to change top/bottom and use -negative value for opposite sides.
.button {
width: 200px;
height: 50px;
padding: auto;
background-color: grey;
text-align: center;
}
.button:hover {
box-shadow: inset 0 -3px 0 0 red;
background-color: lightgrey;
}
<div class="button"> Button </div>
You can use box-shadow which does not change your box-size, unlike border.
Here is a little tutorial.
Just add the following code into your css file
#homeheader a {
border:1px solid transparent;
}
The CSS "box-sizing" attribute fixed this problem for me. If you give your element
.class-name {
box-sizing: border-box;
}
Then the width of the border is added to the inside of the box when the browser calculates its width. This way when you turn the border style on and off, the size of the element doesn't change (which is what causes the jittering you observed).
This is a new technology, but the support for border-box is pretty consistent. Here is a demo!
The easiest method I found was using 'outline' instead of 'border'.
#home:hover{
outline:1px solid white;
}
instead of
#home:hover{
border:1px solid white;
}
Works the best!
https://www.kirupa.com/html5/display_an_outline_instead_of_a_border_hover.htm
Add a negative margin on hover to compensate:
#homeheader a:hover{
border: 1px solid #102447;
margin: -1px;
}
updated fiddle
In the fiddle the margin: -1px; is a little more complex because there was a margin-right getting overridden, but it's still just a matter of subtracting the newly-occupied space.
I too was facing the same problem. The fix mentioned by Wesley Murch works! i.e. adding a transparent border around the element to be hovered.
I had a ul on which :hover was added to every li. Every time, I hovered on each list item, the elements contained inside li too moved.
Here is the relevant code:
html
<ul>
<li class="connectionsListItem" id="connectionsListItem-0">
<div class="listItemContentDiv" id="listItemContentDiv-0">
<span class="connectionIconSpan"></span>
<div class="connectListAnchorDiv">
Test1
</div>
</div>
</li>
</ul>
css
.listItemContentDiv
{
display: inline-block;
padding: 8px;
right: 0;
text-align: left;
text-decoration: none;
text-indent: 0;
}
.connectionIconSpan
{
background-image: url("../images/connection4.png");
background-position: 100% 50%;
background-repeat: no-repeat;
cursor: pointer;
padding-right: 0;
background-color: transparent;
border: medium none;
clear: both;
float: left;
height: 32px;
width: 32px;
}
.connectListAnchorDiv
{
float: right;
margin-top: 4px;
}
The hover defn on each list item:
.connectionsListItem:hover
{
background-color: #F0F0F0;
background-image: linear-gradient(#E7E7E7, #E7E7E7 38%, #D7D7D7);
box-shadow: none;
text-shadow: none;
border-radius: 10px 10px 10px 10px;
border-color: #AAAAAA;
border-style: solid;
}
The above code used to make the containing elements shift, whenever I hovered over connectionsListItem. The fix was this added to the css as:
.connectionsListItem
{
border:1px solid transparent;
}
Use :before to create the border, that way it won't modify the actual content and gives you more freedom. Check it out here:
http://codepen.io/jorgenrique/pen/JGqOMb
<div class='border'>Border</div>
<div class='before'>Before</div>
div{
width:300px;
height:100px;
text-align:center;
margin:1rem;
position:relative;
display:flex;
justify-content:center;
align-items: center;
background-color:#eee;
}
.border{
border-left:10px solid deepPink;
}
.before{
&:before{
content:"";
position:absolute;
background-color:deepPink;
width:10px;
height:100%;
left:0;
top:0;
}
&:hover{
background-color:#ccc;
&:before{
width:0px;
transition:0.2s;
}
}
}
Be careful if you also use padding.
In my case, I had a 5px padding inside the hover defn. It should be moved inside the actual class of the element you want to hover over.
Code snippet