Inline elements shifting when made bold on hover
Pre-set the width by using an invisible pseudo-element which has the same content and styling as the parent hover style. Use a data attribute, like title
, as the source for content.
li {
display: inline-block;
font-size: 0;
}
li a {
display:inline-block;
text-align:center;
font: normal 16px Arial;
text-transform: uppercase;
}
a:hover {
font-weight:bold;
}
/* SOLUTION */
/* The pseudo element has the same content and hover style, so it pre-sets the width of the element and visibility: hidden hides the pseudo element from actual view. */
a::before {
display: block;
content: attr(title);
font-weight: bold;
height: 0;
overflow: hidden;
visibility: hidden;
}
<ul>
<li><a href="#" title="height">height</a></li>
<li><a href="#" title="icon">icon</a></li>
<li><a href="#" title="left">left</a></li>
<li><a href="#" title="letter-spacing">letter-spacing</a></li>
<li><a href="#" title="line-height">line-height</a></li>
</ul>
change of font-weight to bold is unwantingly changing width of element
Other than the width
route here are two other possibilities, it's down to personal preference as to whether you think they are suitable or not. Both these ideas work on the same principal, that you use a separate element to show the bold state, and this element either doesn't (idea one) or does (idea two) affect the UI with it's dimensions.
http://jsfiddle.net/3Jyge/2/
Idea one
Use pseudo selectors. This method relies on the browser supporting quite recent advances i.e. :before
and content: attr()
so probably isn't reliable just yet.
- https://developer.mozilla.org/en-US/docs/Web/CSS/attr#Browser_Compatibility
- https://developer.mozilla.org/en-US/docs/Web/CSS/::before#Browser_compatibility
css:
ul {
list-style: none;
}
ul li {
float: left;
}
ul li:hover a {
visibility: hidden;
}
ul li:hover:before {
position: absolute;
font-weight: bold;
content: attr('data-text');
}
markup:
<ul>
<li data-text="one"><a href="#">one</a></li>
<li data-text="two"><a href="#">two</a></li>
<li data-text="three"><a href="#">three</a></li>
</ul>
Idea two
The other is a bit more straight-forward, although it relies on preping your markup first — and those who use screen readers may understandably dislike your site; unless you can find a nice way to hide the duplicate text from them.
markup:
<ul>
<li><a href="#">
<span class="a">one</span>
<span class="b">one</span>
</a></li>
<li><a href="#">
<span class="a">two</span>
<span class="b">two</span>
</a></li>
<li><a href="#">
<span class="a">three</span>
<span class="b">three</span>
</a></li>
</ul>
css:
ul {
margin: 0; padding: 0;
list-style: none;
}
ul li {
float: left;
}
ul li a span.b {
visibility: hidden;
font-weight: bold;
}
ul li a span.a {
position: absolute;
}
ul li:hover a span.b {
visibility: visible;
}
ul li:hover a span.a {
visibility: hidden;
}
At the end of the day the better solutions would be:
- Set a width, although I can understand not wanting to do this.
- Use JavaScript to calculate dimensions.
- Choose a different highlight, one that doesn't alter the dimensions of the text.
bold font makes width change
Your div is inline-block
and doesn't have an explicit width, so it shrink-wraps the content. The font is a proportional font, so it gets thicker (and takes up more horizontal space) when it is made bold.
Either give the div a fixed width, set it to block
, or use a monospace font.
CSS to avoid a container from resizing to fit bold text
Here is an idea, use the before and after attributes to size the element based on the bold text width. Unfortunately, this requires a change to your markup.
#txt { line-height: 1.4em; padding: 5px; text-align: center;}#txt::before { content: attr(data-content); display: block; font-weight: bold; height: 0px; visibility: hidden;}#txt::after { content: attr(data-content); font-weight: normal;}#txt:hover::after { font-weight: bold;}#test { display: inline-block; border: solid 1px black; min-width: 100px;}
<div id="test"> <div id="txt" data-content="This is some text"></div></div>
How to stop Button text italic hover effect from shifting button width?
The problem is the italicized font is actually thinner than the standard version. The suggestion to use a fixed width is probably the cleanest way of solving the problem but may not be desirable in all cases.
Adding padding will not necessarily fix the issue.
This answer contains an interesting suggestion which you could modify for your use case: CSS: bolding some text without changing its container's size . You already have the title
attribute on your button, so you could take the same approach but set the psuedo element to font-style: normal
.
button {
border-width: 1px;
border-color: #EEEEEE;
font-family: "Adobe Garamond Pro";
font-weight: normal;
border-style: solid;
color: #595959;
font-size:30px;
padding:0 1em;
position:relative;
}
button:hover {
font-style: italic;
}
button::after {
display: block;
content: attr(title);
height: 0;
font-style:normal;
color: transparent;
overflow: hidden;
visibility: hidden;
}
<button id="loginbutton" type="button" title="Enter">Enter</button>
Reducing the text view container size in css
Ok, so i set the max-width to about 20% and added margin:auto and it works.
making font weight bold not moving rest of content
This snippet builds on the idea in the given code - have a pseudo element which also contains the text.
However, it changes things around so that the actual item element has bold but is first shown with color transparent - this makes it as wide as it needs to be even when active.
The text seen initially is in the before pseudo element which has weight normal and is positioned over its owning element.
When made active the colors are reversed so we see the bold, but the size is as it has always been.
For the number in the badge it's only necessary to change normal/bold as the badge's size is already fixed.
.list {
display: flex;
gap: 2rem;
list-style: none;
}
.item {
display: flex;
position: relative;
cursor: pointer;
font-weight: bold;
color: transparent;
}
.item::before {
display: block;
content: attr(title);
height: 0;
color: black;
z-index: 1;
position: absolute;
font-weight: normal;
}
.item:active {
font-weight: bold;
color: black;
}
.item:active::before {
color: transparent;
}
.badge {
width: 20px;
height: 20px;
background: lightblue;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
color: black;
font-weight: normal;
}
.item:active .badge {
font-weight: bold;
}
<ul class="list">
<li class="item" title="First">First
<div class="badge">5</div>
</li>
<li class="item" title="Second">Second
<div class="badge">5</div>
</li>
<li class="item" title="Third">Third
<div class="badge">5</div>
</li>
</ul>
Finer Control of Text Accent/Boldness Through CSS
What is happining
The way fonts works now is that a font has various font-weights it can use. To use a font weight they need to be available in your users browser. Browsers usually do not have the fonts installed to support the 9 typical font-weights( 100, 200, 300, 400, 500, 600, 700, 800, 900 ). It will round up or down to the nearest one available.
What you can do about it
You could try to find a font that supports all the font-weights you want and import it. I found some on google fonts: https://fonts.google.com/?stylecount=18.
Modified code
All I changed was importing 'Montserrat' to your code and assigning the Montserrat font to your body.
@import url('https://fonts.googleapis.com/css?family=Montserrat:100,200,300,400,500,600,700,800,900');
body { padding: 0; margin: 0; font-family: 'Montserrat', sans-serif; font-weight: normal; font-size: 15px; font-style: normal; font-variant: normal; text-transform: none; font-synthesis: none; color: #383838; width: 100%; height: 100%; -webkit-text-size-adjust: none !important; -ms-text-size-adjust: none !important; -moz-text-size-adjust: none !important; border: none; text-align: center; text-rendering: optimizelegibility; min-width: 300px !important;}
h3,h4,h5,h6 { display: block; font-family: inherit; line-height: 1.1; color: #000; opacity: 1.0; font-weight: normal; text-align: center; margin: 10px auto 6px auto; font-size: 1em;}
h3 { font-size: 1.05em;}
h4 { font-size: 1.1em;}
h5 {}
h6 { margin: .25em auto;}
.center-block { display: block; width: auto; text-align: center; margin-right: auto; margin-left: auto;}
.test-boldness { text-shadow: 1px 0.1px rgba(0, 0, 0, 0.23);}
.bold { font-weight: 500; color: #000;}
.bolder { font-weight: 500; color: #000; text-shadow: 1px 0.1px rgba(0, 0, 0, 0.35);}
.boldest { color: #000; font-weight: 600;}
.test-boldness { text-shadow: 1px 0.1px rgba(0, 0, 0, 0.35);}
.test-boldness-1pxsolid { text-shadow: 1px 1px #999;}
div { font-family: inherit; color: #383838;}
<!DOCTYPE html>
<head></head><html>
<body> <br /> <br /> <div class="center-block"><span class="test-boldness-1pxsolid">How Used: </span>Visible accent. This one has most blurring on all required OS/devices.</div> <br /> <div> <span style='font-weight: 300'>300</span> <span style='font-weight: 400'>400</span> <span style='font-weight: 500'>500</span> <span class='test-boldness'>Custom 550</span> <span style='font-weight: 600'>600</span> <span style='font-weight: 700'>700</span> <br /> <br /> <div class="center-block"><span class="test-boldness">How Used: </span>Visible accent. Less blurring/most uniform on required OS/devices. Is there a better way to do this?</div> <br /> <br /> <div class="center-block"><span class="boldest">How Used: </span>Visible accent. This one is clearest but too bold, especially on some of the required OS/devices.</div> <br /> <h3>Test Cases</h3> <br /> <h3 class="test-boldness-1pxsolid">TEST ABCDKTM test abcdktm-1pxsolid</h3> <h3 class="test-boldness">TEST ABCDKTM test abcdktm 0.1px Op LT 1</h3> <h3>TEST ABCDKTM test abcdktm</h3> <h4 class="test-boldness-1pxsolid">TEST ABCDKTM test abcdktm-1pxsolid</h4> <h4 class="test-boldness">TEST ABCDKTM test abcdktm 0.1px Op LT 1</h4> <h4>TEST ABCDKTM test abcdktm</h4> <h5 class="test-boldness-1pxsolid">TEST ABCDKTM test abcdktm-1pxsolid</h5> <h5 class="test-boldness">TEST ABCDKTM test abcdktm 0.1px Op LT 1</h5> <h5>TEST ABCDKTM test abcdktm</h5> <h6 class="test-boldness-1pxsolid">TEST ABCDKTM test abcdktm-1pxsolid</h6> <h6 class="test-boldness">TEST ABCDKTM test abcdktm 0.1px Op LT 1</h6> <h6>TEST ABCDKTM test abcdktm</h6> <div class="center-block bold test-boldness">TEST ABCDKTM test abcdktm 0.1px Op LT 1</div> <div class="center-block bold">TEST ABCDKTM test abcdktm</div> <div class="center-block bolder test-boldness">TEST ABCDKTM test abcdktm font-weight: 500</div> <div class="center-block bolder">TEST ABCDKTM test abcdktm font-weight: 500</div> <div class="center-block boldest">TEST ABCDKTM test abcdktm font-weight: 600</div> <div class="center-block boldest">TEST ABCDKTM test abcdktm font-weight: 600</div>
</body>
</html>
Related Topics
Are CSS3 ::Before and ::After Pseudo Elements Supported by IE9 or Not
How to Specify an Element After Which to Wrap in CSS Flexbox
Flex Auto Margin Not Working in Ie10/11
Background Color of Tabs in Shiny Tabpanel
How to Make Twitter Bootstrap Modal Full Screen
Styling Mat-Select in Angular Material
Repeat CSS Background Image a Set Number of Times
Why Don't CSS Resets Use '*' to Cover All Elements
iOS Forces Rounded Corners and Glare on Inputs
How to Apply Border Radius in IE8 and Below IE8 Browsers
Why Don't Margin-Top: Auto and Margin-Bottom:Auto Work the Same as Their Left and Right Counterparts
Using Font Awesome Icon for Bullet Points, with a Single List Item Element
Pure CSS Multiple Stacked Position Sticky
How to Create the Masonry Effects with Just Bootstrap 3 Grid System and CSS
Anyway to Prevent the Blue Highlighting of Elements in Chrome When Clicking Quickly
Background-Size with Svg Squished in IE9-10