How to avoid expanding the parent flex element on hover - css

I have simple nav bar list and i need change item font weight on hover. But when I hover on item its width changes so other nav items position changes too. How to fix this issue?
Exampe:
.container {
margin: 0 auto;
max-width: 500px;
}
.nav {
display: flex;
justify-content: space-between;
list-style: none;
text-transform: uppercase;
}
.nav__item {
font-weight: 100;
cursor: pointer;
}
.nav__item:hover {
font-weight: bold;
}
<html>
<div class="container">
<ul class="nav">
<li class="nav__item">Home</li>
<li class="nav__item">About</li>
<li class="nav__item">Contacts</li>
<li class="nav__item">Donate</li>
<li class="nav__item">FAQ</li>
</ul>
</div>
</html>

An easy way is to set a vertical or horizontal text-shadow to mimic bold letters, transform with skew() or scale(), ... could also help making effects witouth having every thing jump .
example with an horizontal text-shadow
.container {
margin: 0 auto;
max-width: 500px;
}
.nav {
display: flex;
justify-content: space-between;
align-items:center;
list-style: none;
text-transform: uppercase;
}
.nav__item {
font-weight: 100;
cursor: pointer;
}
.nav__item:hover {
text-shadow: 1px 0;
}
<html>
<div class="container">
<ul class="nav">
<li class="nav__item">Home</li>
<li class="nav__item">About</li>
<li class="nav__item">Contacts</li>
<li class="nav__item">Donate</li>
<li class="nav__item">FAQ</li>
</ul>
</div>
</html>

This should help you out:
Inline elements shifting when made bold on hover
Although flex isnt used in this example, the top voted solution should prove to be a working work around as the li elements's width won't react to the change in width caused by the font weight change.

Related

I am trying to center align the menu

I am a newbie in CSS. I am learning by playing with the code of a WordPress theme.
Last time I posted this issue but I contracted covid and was hospitalized for more than two weeks. I have deleted the old question and broken the initial question into two parts. This is the first part.
To remove the Site-Name on the left side. I used display: none.
<div id="header-left">
<div id="hgroup" class="logo-disable">
<h1 id="site-title">
Catch Kathmandu
</h1>
<h2 id="site-description"> Catch Kathmandu Theme is a fully responsive WordPress theme that looks elegant on any devices.</h2>
</div><!-- #hgroup -->
</div>
#header-left {
-webkit-text-size-adjust: 100%;
color: #404040;
line-height: 1.8;
text-rendering: optimizeLegibility;
word-wrap: break-word;
border: 0;
font-family: inherit;
font-size: 100%;
font-style: inherit;
font-weight: inherit;
margin: 0;
outline: 0;
padding: 0;
vertical-align: baseline;
float: left;
max-width: 100%;
display: none;
}
To center-align the menu on the right side.
<div id="header-right" class="header-sidebar widget-area">
<aside class="widget widget_nav_menu">
<div id="primary-menu-wrapper" class="menu-wrapper">
<div class="menu-toggle-wrapper">
<button id="menu-toggle" class="menu-toggle" aria-controls="main-menu" aria-expanded="false"><span class="menu-label">Menu</span></button>
</div><!-- .menu-toggle-wrapper -->
<div class="menu-inside-wrapper">
<nav id="site-navigation" class="main-navigation" role="navigation" aria-label="Primary Menu" aria-expanded="false">
<ul id="menu-primary-items" class="menu nav-menu"><li class="current-menu-item">Home</li><li class="page_item page-item-2">About</li><li class="page_item page-item-182">Home</li><li class="page_item page-item-46 page_item_has_children" aria-haspopup="true">Parent Page<button class="dropdown-toggle" aria-expanded="false"><span class="screen-reader-text">expand child menu</span></button><ul class="children"><li class="page_item page-item-49">Sub-page</li></ul></li></ul> </nav><!-- .main-navigation -->
</div>
#header-right {
-webkit-text-size-adjust: 100%;
color: #404040;
line-height: 1.8;
text-rendering: optimizeLegibility;
word-wrap: break-word;
border: 0;
font-family: inherit;
font-size: 100%;
font-style: inherit;
font-weight: inherit;
margin: 0;
outline: 0;
padding: 0;
vertical-align: baseline;
padding-top: 50px;
float: right;
margin-right: 33%;
}
I reached my center alignment by reducing the margin-right from 50% then to 33%. Though the sweet spot is between 32% to 33%.
I also tried center-align the menu with pixels(margin-right :400px).
The difference between both methods is visible when I reduce the screen size. 33% mostly remains center-align but the px changes the position of the menu, as the screen changes.
Is there any other way I could center the menu?
There are many ways to center items depending on their block type.
You can use display flex on the parent and then add a justify-content: center to center the children items on the page horizontally, see flex axis - in basic concepts of flex for more info.
Then you can use flex property on the children and can add a number to that property to tell CSS how much of the parents width that child will take up.
For example if I set both to child elements to flex: 1 they will take up 50%, if there were three child elements all with a flex: 1, they would then take up 33% of their parents width. I can also place a percentage on the flex property as well => .header set flex: 60% and .nav-parent set flex: 40%, they will then take up their set percentages of the parents width.
Furthermore I can add display: flex properties to the child elements as well to further center their contents, as I have done on the .menu class which is a child of the .nav-parent. These can then be further align and centered using the axis centering properties for flex, justify-content and align-items. The good thing is that these properties are dynamic in that they scale to fit browser sizes as well.
.nav-section {
display: flex;
justify-content: center;
font-family: sans-serif;
align-items: center;
padding: 1rem;
}
.header h1 {
line-height: 1px;
}
.header {
flex: 60%;
}
.nav-parent {
flex: 40%;
}
.header span {
font-size: .8rem;
font-weight: 100;
font-style: italic;
}
ul li {
list-style: none;
}
ul li ~ li {
margin-left: .5rem;
}
.btn {
flex: 1;
padding: .5rem 0;
text-align: center;
}
.menu {
display: flex;
justify-content: center;
color: #555;
font-size: .8rem;
}
.active {
background: skyblue;
}
<div class="nav-section">
<div class="header">
<h1>Catch Kathmandu</h1>
<span>Catch Kathmandu Theme is a fully responsive WordPress theme that looks elegant on any device.</span>
</div>
<div class="nav-parent">
<ul class="menu">
<li class="home active btn">Home</li>
<li class="about btn">About</li>
<li class="contact btn">Contact</li>
<li class="parent btn">Page</li>
</ul>
</div>
</div>
Is there any other way I could center the menu?
There are a good handful of ways you can center the menu.
If your menu is a block-level element with an explicitly declared width, one of the most basic techniques is applying the keyword auto to margin-right and margin-left:
.my-menu {
margin-top: 12px; // <= Just an example, you can use any value
margin-right: auto;
margin-bottom: 12px; // <= Just an example, you can use any value
margin-left: auto;
}
the CSS shorthand for these four declarations is:
.my-menu {
margin: 12px auto 12px auto;
}
or, since the vertical and horizontal values are the same, you can declare:
.my-menu {
margin: 12px auto;
}
Working Example:
.my-menu {
display: block;
margin: 12px auto;
}
.my-menu.vertical {
width: 100px;
}
.my-menu.horizontal {
width: 396px;
padding: 0;
}
.my-menu.horizontal li {
display: inline-block;
padding: 0 6px;
}
.my-menu.horizontal li::before {
content: '•';
display: inline-block;
padding-right: 6px;
font-size: 20px;
}
<ul class="my-menu vertical">
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
<li>List Item 4</li>
</ul>
<ul class="my-menu horizontal">
<li>List Item 1</li>
<li>List Item 2</li>
<li>List Item 3</li>
<li>List Item 4</li>
</ul>

Enable navigation list items to have a height of 100% of the parent flex container

I am trying to figure out how to force my <li> items within my flexbox navigation bar to take up 100% of the height of the header.
The goal is to have an active class to display a blue bar when the user hovers over the item. I have mocked up my simple example here: https://codepen.io/anon/pen/jZzeqL
I have tried to mess with the align-items, but everything I do seems to break the center horizontal alignment.
/* header styles */
.header {
grid-area: header;
background-color: #444;
color: #fff;
align-items: center;
display: flex;
margin: 0 2em;
}
#logo {
font-weight: 300;
font-size: 160%;
}
#logo, nav {
flex: 1;
}
nav ul {
display: flex;
list-style: none;
justify-content: flex-end;
font-size: 110%;
}
nav li {
font-size: 14px;
padding: 0px 10px;
}
nav li span.active {
border-bottom: 3px solid #00A2D3;
}
nav li > .username {
font-weight: 400;
padding-right: 3px;
}
<header class="header">
<div id="logo">Dashboard</div>
<nav>
<ul role=navigation>
<li><span class="far-li"><i class="far fa-bell"></i></span></li>
<li><span class="fas-li"><i class="fas fa-cog"></i></span></li>
<li><span class="username active">test-email#gmail.com</span><span class="fas-li"><i class="fas fa-caret-down"></i></span></li>
</ul>
</nav>
</header>

Center aligning the top menu categories via CSS

I needed to center align my menu categories, such that the menu categoreis should sit for a width of 1200px and there should be even gaps (i.e. margin-right) between the category items in the menu and last item should sit to the right more corner in the screen (i.e. margin-right:0). Please find below the sample code for the same.
https://jsfiddle.net/es0o324t/1/
HTML:
<div class="navigationbarcollectioncomponent">
<div id="nav_main">
<ul>
<li class="La parent">
Clothing
</li>
<li class="La parent">
Denim
</li>
<li class="La parent">
Accessories
<li class="La parent">
Online Exclusives
</li>
<li class="La parent">
Sale
</li>
<li class="La parent">
Hot offers
</li>
</ul>
</div>
</div>
CSS:
body {
margin:0;
padding:0;
}
ul{
margin-left:0;
}
ul,li{
list-style: none;
padding:0;
}
.navigationbarcollectioncomponent {
width: 1200px;
margin: 0 auto;
}
#nav_main li.La{
float: left;
}
#nav_main li.La > a {
color: #373737;
display: inline-block;
font-family: "Lato-Regular";
font-size: 16px;
line-height: 36px;
margin: 0;
padding: 0px 8px;
text-transform: uppercase;
}
I had achieved this via JavaScript and by reading the width of each of the categories in the menu and then calculating the gap b/w the categories based on the category count.
But the issue is i need to do this only via CSS not using JavaScript. bcoz the calculation via JS is taking some time.
Also the count of number of categories is dynamic. Hence i cannot hardcode the margin-right value for each of the categories (i.e. li tag).
Please let me know if there is a solution for the same.
PFA for the snapshot on expected result.
First category should be left most aligned in 1200px width and last category should be aligned to the right and the categories that are b/w first and last categories should be center aligned with even spacing
As you tagged this question with CSS3, why not use flex?
Make your container ul set to display flex with justify-content set to space-between.
ul {
width: 100%; padding: 8px;
display: flex;
justify-content: space-between;
}
Your Fiddle: https://jsfiddle.net/abhitalks/es0o324t/2/
To center you nav menu, please add this css too.
#nav_main{
margin: 0 auto;
display: table;
}
check this fiddle : jsfiddle.net/shiyaspathiyassery/6jqy6702/1/
You have added float: left; Please remove that.
Here's something close enough. Run the code snippet to see the result:
although the leftmost and rightmost menu are not sticking to the sides, respectively, since the <li> text-align is set to center in order to achieve even space between the menus.
body {
margin:0;
padding:0;
}
ul{
display: -webkit-box;
display: -moz-box;
display: box;
width: 100%;
}
ul,li{
list-style: none;
padding:0;
}
.navigationbarcollectioncomponent {
display: inline-block;
width: 1200px;
margin: 0 auto;
}
#nav-main{
display: inline-block;
width: 100%;
}
#nav_main li.La{
text-align: center;
-webkit-box-flex: 1;
-moz-box-flex: 1;
box-flex: 1;
}
#nav_main li.La > a {
color: #373737;
display: inline-block;
font-family: "Lato-Regular";
font-size: 16px;
line-height: 36px;
margin: 0;
padding: 0px 8px;
text-transform: uppercase;
}
<div class="navigationbarcollectioncomponent">
<div id="nav_main">
<ul>
<li class="La parent">
Clothing
</li>
<li class="La parent">
Denim
</li>
<li class="La parent">
Accessories
<li class="La parent">
Online Exclusives
</li>
<li class="La parent">
Sale
</li>
<li class="La parent">
Hot offers
</li>
</ul>
</div>
</div>
table-layout: fixed can be used to achieve what you are looking for.
In table-layout: fixed the horizontal layout only depends on the table's width and the width of the columns irrespective of the contents of the cells.
So your table width will be equally divided for each columns.
Add/modify these css properties for ul and #nav_main li.La
ul{
margin-left:0;
display: table;
table-layout: fixed;
width: 100%;
text-align: center;
}
#nav_main li.La{
display:table-cell;
}
https://jsfiddle.net/f03mqxd7/

How to center the nav

I found this really simple way to make responsive menu on w3schools (article) but I have been struggling for a few days trying to center it horizontally.
html
<ul class="topnav">
<li>Home</li>
<li>News</li>
<li>Contact</li>
<li>About</li>
<li class="icon">
☰
</li>
</ul>
CSS
/* Remove margins and padding from the list, and add a black background color */
ul.topnav {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333;
}
/* Float the list items side by side */
ul.topnav li {float: left;}
/* Style the links inside the list items */
ul.topnav li a {
display: inline-block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
transition: 0.3s;
font-size: 17px;
}
/* Change background color of links on hover */
ul.topnav li a:hover {background-color: #111;}
/* Hide the list item that contains the link that should open and close the topnav on small screens */
ul.topnav li.icon {display: none;}
I made a fiddle from you linked code: https://jsfiddle.net/gqm7zdf9/
A solid option is to add a wrapper around your UL so that you can move the background-color there. Then you position it inside its wrapper.
HTML
<div class="nav-wrapper">
<ul class="topnav">
...
</ul>
</div>
additional CSS
div.nav-wrapper {
background-color: #333;
}
div.nav-wrapper ul.topnav {
display: inline-block;
position: relative;
left: 50%;
transform: translateX(-50%);
}
 
If you're able (depending on the browsers you need to support) to use display:flex, there's an even way more simple option. You just need to add some CSS:
ul.topnav {
/* ... */
display: flex;
justify-content: center;
}
https://jsfiddle.net/gqm7zdf9/1/
 
I think you'll be able to continue with your media-queries from there...

100% children height in horizontal navigation with dynamic logo/element height

I've browsed around for a while but I believe I have a slightly more unique situation here.
I have a simple navigation which is a <ul> list, with each <li> containing an anchor <a>. The first <li> contains an image which is the logo.
I'd like for each of the subsequent <li> AND <a> elements to expand to the height of the logo, whatever it may be (I would like for the only static height in this solution to be defined on the logo's image, if possible).
The elements should also be vertically centered.
When you hover on the <a> tags, the background and cursor selection should cover the entire height.
I've tried using display: flex; and display: table-cell, with vertical-align: middle and a bunch of other things. I've almost got it but there is some empty space above and below the <a> tags. The only way I can see to fix it is to use a static height on the <a> tags, but I'm posting here to see if anyone knows of any alternatives.
Please note that this doesn't have to be a cross-browser solution (although that would be nice).
Also note that these elements will include a sub-navigation dropdown, so solutions which might include overflow: hidden may not be applicable in that case.
Here is the code:
a {
font-family: 'Trebuchet MS';
text-decoration: none;
}
nav {
background: #444;
}
nav > ul > li {
display: table-cell;
vertical-align: middle;
}
nav > ul > li img {
display: table-cell;
vertical-align: middle;
height: 24px;
padding: 24px;
}
nav > ul > li a {
display: table-cell;
vertical-align: middle;
padding: 24px;
color: #fff;
}
nav > ul > li:hover a {
cursor: pointer;
background: white;
color: #444;
}
<nav role="navigation">
<ul>
<li>
<img src="http://i.imgur.com/ZPB7f3l.png" />
</li>
<li>About
</li>
<li>Work
</li>
<li>Ideas
</li>
<li>Contact
</li>
</ul>
</nav>
Here is the fiddle: http://jsfiddle.net/0br6r0sh/1
Any advice is appreciated!
Thanks,
Ryan
I've tried to implement your requirements using Flexbox. Unfortunately not in a cross browser fashion as it only works on Chrome.
The <img> is given a display: block to remove all padding/margin around it. I've used three sets of display: flex, for the <ul>, <li> and <a>.
a {
font-family: 'Trebuchet MS';
text-decoration: none;
}
nav {
background: #444;
}
nav > ul {
display: flex;
flex-direction: row;
align-items: stretch;
}
nav > ul > li {
background-color: #555;
display: flex;
}
nav > ul > li img {
height: 24px;
padding: 24px;
background-color: #ccc;
display: block;
}
nav > ul > li a {
display: flex;
flex-direction: column;
justify-content: center;
padding: 0 24px;
color: #fff;
background-color: #666;
}
nav > ul > li:hover a {
cursor: pointer;
background: white;
color: #444;
}
<nav role="navigation">
<ul>
<li>
<img src="http://i.imgur.com/ZPB7f3l.png" />
</li>
<li>About
</li>
<li>Work
</li>
<li>Ideas
</li>
<li>Contact
</li>
</ul>
</nav>

Resources