I have a navigation bar and I added a red line on the bottom when hovering any item of the list, but I want to move that red line under the header (something like "Services"), any idea how to achieve this?
I added an small sample in codepen so you can easily check the HTML and CSS code
header {
background-color: lightblue;
padding-top: 1rem;
position: sticky;
top: 0;
display: flex;
align-items: center;
justify-content: space-around;
}
header nav {
min-width: 50%;
}
header nav ul {
margin: 0;
height: 100%;
list-style: none;
padding-left: 0;
display: flex;
align-items: center;
justify-content: space-between;
}
header li:hover {
height: 100%;
border-bottom: 2px solid red;
}
<header>
<a href="/">
<p>Whatever logo</p>
</a>
<nav>
<ul>
<li>About us</li>
<li>Services</li>
<li>Pricing</li>
<li>Blog</li>
</ul>
</nav>
CONTACT
</header>
Link to check the code
You can fix the header height and also fix the height of navbar items.
Also, you had one issue where on hover li elements are moving. You can also fix that with always adding border with transparent color to the element, so the overall height of the element won't change on hover state.
Here is the fixed CSS
header {
background-color: lightblue;
position: sticky;
display: flex;
height: 60px;
align-items: center;
justify-content: space-around;
}
header nav {
min-width: 50%;
}
header nav ul {
margin: 0;
height: 100%;
list-style: none;
padding-left: 0;
display: flex;
align-items: center;
justify-content: space-between;
height: 60px;
}
header li {
display: flex;
align-items: center;
border-bottom: 2px solid transparent;
height: 60px;
}
header li:hover {
border-bottom: 2px solid red;
}
https://codepen.io/swarajgk/pen/JjZewPo?editors=1100
I think just giving height to all list elements the same as the header will work.
Like this:-
header {
background-color: lightblue;
padding-top: 1rem;
height: 3rem;
position: sticky;
top: 0;
display: flex;
align-items: center;
justify-content: space-around;
}
header nav {
min-width: 50%;
height : 100%;
}
header nav ul {
margin: 0;
height: 100%;
list-style: none;
padding-left: 0;
display: flex;
align-items: center;
justify-content: space-between;
}
header li{
height: inherit;
}
header li:hover {
border-bottom: 2px solid red;
}
<body>
<header>
<a href="/"
><p>Whatever logo</p></a>
<nav>
<ul>
<li>About us</li>
<li>Services</li>
<li>Pricing</li>
<li>Blog</li>
</ul>
</nav>
CONTACT
</header>
</body>
Hope this solves the issue.
header {
background-color: lightblue;
padding-top: 1rem;
height: 3rem;
position: sticky;
top: 0;
display: flex;
align-items: center;
justify-content: space-around;
}
header nav {
min-width: 50%;
height : 100%;
}
header nav ul {
margin: 0;
height: 100%;
list-style: none;
padding-left: 0;
display: flex;
align-items: center;
justify-content: space-between;
}
header li{
height: inherit;
}
header li:hover {
border-bottom: 2px solid red;
}
I'd suggest the following approach, with explanatory comments in the CSS:
/* removing default padding and margin from all
elements, and forcing the browser to use the
same sizing algorithm - border-box - to calculate
element sizes, including the padding and border
widths in the declared size: */
*, ::before, ::after {
box-sizing: border-box;
padding: 0;
margin: 0;
}
/* setting common properties for the two element
groups: */
header,
header nav ul {
/* using display: flex layout: */
display: flex;
/* forcing the flex-items within the flex parent
to take the full height of that parent: */
align-items: stretch;
}
header {
background-color: lightblue;
block-size: 3em;
position: sticky;
justify-content: space-around;
}
/* using :is() to combine the two selectors
header a,
header li
into one selector: */
header :is(a, li) {
/* using grid layout: */
display: grid;
/* positioning the - including text - content
at the center of the element: */
place-items: center;
}
header nav {
min-width: 50%;
}
header nav ul {
/* the <ul> isn't a flex-item so we have to specify
that we want it to take all available space on
the block-axis (equivalent to 'height' in left-to-right
languages such as English): */
block-size: 100%;
list-style: none;
justify-content: space-between;
}
header li {
/* to prevent the jumping content: */
border-bottom: 2px solid transparent;
}
header li:hover {
/* to style the color of the bottom border: */
border-bottom-color: red;
}
<header>
<a href="/">
<p>Whatever logo</p>
</a>
<nav>
<ul>
<li>About us</li>
<li>Services</li>
<li>Pricing</li>
<li>Blog</li>
</ul>
</nav>
CONTACT
</header>
JS Fiddle demo.
References:
align-items.
display.
justify-content.
place-items.
Bibliography:
"Aligning items in a flex container," MDN.
"Basic concepts of flexbox," MDN.
"Box alignment in grid layout," MDN.
Related
My header should be fixed on the page so i couldn't use float:right;. I'm %150 newbie around here. Logo should be on right side of the navbar and also responsive. I tried margin, float and other flex properties. I'm just going to be mad. Where is the mistake.
#import url('https://fonts.googleapis.com/css2?family=Oswald&display=swap');
body {
margin: 0;
font-family: 'Trebuchet MS', sans-serif;
background-color: #efefef;
}
.wrapper {
position: relative;
}
.header-logo {
width: 20vw;
height: 20vw;
}
header {
width: 100%;
height: 4rem;
background: #609F92;
position: fixed;
display: flex;
font-family: Oswald, sans-serif;
font-size: 1.5rem;
}
#header-img {
width: 100%;
height: 100%;
border-radius: 50%;
box-shadow: 1px 1px 2px 1px;
}
#nav-bar {
display: flex;
flex-direction: row;
}
#nav-bar ul {
display: flex;
flex-direction: row;
align-items: center;
list-style: none;
}
#nav-bar li {
margin: 10px;
}
<div class="wrapper">
<header id="header">
<nav id="nav-bar">
<ul>
<li>Features</li>
<li>About Us</li>
<li>Contact</li>
</ul>
<div class="header-logo">
<img id="header-img" src="https://thumbnails-photos.amazon.com/v1/thumbnail/lFJOXJpuTKGgtJYa9-wScA?viewBox=943%2C943&ownerId=A4PYAHHROL8LR&groupShareToken=OSTx_M1GRRS1y_rPWtVfGA.8mpQdgJWAet53NrSPN2TyS">
</div>
</nav>
</header>
</div>
The issue is mainly caused because you nesting so many flexboxes within each other. As such the elements will not span the entire available width automatically.
Give the nav tag a width of 100% to fill out the entire containers width: #nav-bar { width: 100% }
to align the logo to the right within a flexbox use margin-left: auto: .header-logo { margin-left: auto; }
Also you could improve your code by removing the ID from the nav element and target the nav element directly. As semantically you should only have one nav element it would be unecessary to asign an id to it. Same rule also counts for the header element.
Then you could remove display: flex; from the header which has only one child element in the first place and as such is useless. IMHO it would be smarter though to close the nav with the ul as the logog is semantically not part of the navbar.
Last but not least you could remove flex-direction: row as it is the default value anyways.
#nav-bar {
width: 100%;
}
.header-logo {
margin-left: auto;
}
/* original CSS */
#import url('https://fonts.googleapis.com/css2?family=Oswald&display=swap');
body {
margin: 0;
font-family: 'Trebuchet MS', sans-serif;
background-color: #efefef;
}
.wrapper {
position: relative;
}
.header-logo {
width: 20vw;
height: 20vw;
}
header {
width: 100%;
height: 4rem;
background: #609F92;
position: fixed;
display: flex;
font-family: Oswald, sans-serif;
font-size: 1.5rem;
}
#header-img {
width: 100%;
height: 100%;
border-radius: 50%;
box-shadow: 1px 1px 2px 1px;
}
#nav-bar {
display: flex;
flex-direction: row;
}
#nav-bar ul {
display: flex;
flex-direction: row;
align-items: center;
list-style: none;
}
#nav-bar li {
margin: 10px;
}
<div class="wrapper">
<header id="header">
<nav id="nav-bar">
<ul>
<li>Features</li>
<li>About Us</li>
<li>Contact</li>
</ul>
<div class="header-logo">
<img id="header-img" src="https://thumbnails-photos.amazon.com/v1/thumbnail/lFJOXJpuTKGgtJYa9-wScA?viewBox=943%2C943&ownerId=A4PYAHHROL8LR&groupShareToken=OSTx_M1GRRS1y_rPWtVfGA.8mpQdgJWAet53NrSPN2TyS">
</div>
</nav>
</header>
</div>
I also created a Codepen for you where I corrected the code to be semantically correct and to shroten it to the necessary lines: Codepen
I've been trying to make a page with a fixed transparent header, using flexbox. At first, I found that somehow this causes a confliction (the fixed positioning and the flex) and the justify-content or align-items properties won't work on the child elements of the wrapper flex-fixed parent. The child elements of the fixed parent won't space appropriately.
But then I saw this https://templated.co/industrious, and somehow it works!
So I cannot understand why it doesn't work with my code. It seems to me I'm not doing it differently.
The header-fixed-flex div wraps the LOGO, NAV and search (svg) elements, but I cannot make the justify-content or align-items option to work on header-nav and navigation div's.
body {
height: 2500px;
}
.header-fixed-flex {
max-width: 150rem;
width: 100%;
position: fixed;
top: 0;
left: 0;
z-index: 100;
display: flex;
justify-content: space-between;
transform: translate(19.2rem, 0);
}
.header_nav {
max-width: 155rem;
display: flex;
justify-content: space-around;
align-items: center;
}
.header_logo {
max-height: 9.7rem;
background: rgba(3, 12, 77, 0.4);
}
.header_link {
padding: 0.5rem;
}
.navigation {
background: rgba(191, 218, 218, 0.4);
display: flex;
}
.navigation_list {
list-style: none;
letter-spacing: 0.4rem;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
align-items: center;
height: 100%;
}
.navigation_item:not(:last-child) {
margin-right: 3rem;
}
.navigation_link:link, .navigation_link:visited {
color: #fff;
text-decoration: none;
padding: 0.8rem;
}
.navigation_button {
border: none;
background: none;
display: flex;
align-items: center;
}
.navigation_search-input {
border: none;
background: rgba(255, 255, 255, 0.1);
outline: none;
width: 5rem;
}
.navigation_icon {
padding: 0.5rem;
width: 3rem;
fill: #fff;
}
.hero_img {
background: url(https://twimg0-a.akamaihd.net/a/1350072692/t1/img/front_page/jp-mountain#2x.jpg) top/cover;
height: 100vh;
}
<div class="header-fixed-flex">
<div class="header_nav">
<header class="header_logo">
LOGO
</header>
<nav class="navigation">
<ul class="navigation_list">
<li class="navigation_item">
Profile
</li>
<li class="navigation_item">
Services
</li>
<li class="navigation_item">
Articles
</li>
<li class="navigation_item">
Contact
</li>
</ul>
<button class="navigation_button">
<input type="text" class="navigation_search-input" id="search-query"/>
<label for="search-query" class="navigation_search_label"></label>
<svg class="navigation_icon"></svg>
</button>
</nav>
</div>
</div>
<section class="hero">
<div class="hero_img"></div>
</section>
Or a codepen link with scss
https://codepen.io/tantoniou/pen/QoGmba
Remove the header-fixed-flex element and apply this style on header_nav
width: 100%;
top: 0;
left: 0;
position: fixed;
z-index: 100;
display: flex;
justify-content: space-between;
It's really tough to determine what you want from your writeup with no design comp or wireframe provided, but my initial guess is things aren't happening as you expect because .header-fixed-flex only has one child. So maybe setting flex: 1 or just width: 100% on .header_nav will get things working as you like.
I want to build a navigation in the header containing three items where the first two ones are aligned left and the third one is aligned right. Tried it by use of flexbox but there is an arror: The ul is exceeding the width of it's parent container.
header {
width: 100%;
background: #417690;
margin-left: 10px;
margin-right: 10px;
font-size: 20px;
height: 70px;
}
header ul {
height: 100%;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
/* justify-content: center; */
}
header ul li {
display: inline-block;
padding-right: 15px;
margin-left: 10px;
}
.filler {
flex-grow: 1;
}
<header>
<ul>
<li>Logo</li>
<li>New article</li>
<li class="filler"></li>
<li>username</li>
</ul>
</header>
How can I fix this?
Tested in FF and Opera.
Reset margin to zero and add box-sizing: border-box to all elements to include the padding in the size calculations. You may also reset the padding for the ul element - see demo below:
* { /* ADDED */
box-sizing: border-box;
}
header {
width: 100%;
background: #417690;
/*margin-left: 10px;
margin-right: 10px;*/
font-size: 20px;
height: 70px;
}
header ul {
height: 100%;
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
/* justify-content: center; */
padding: 0; /* ADDED */
}
header ul li {
display: inline-block;
padding-right: 15px;
margin-left: 10px;
}
.filler {
flex-grow: 1;
}
<header>
<ul>
<li>Logo</li>
<li>New article</li>
<li class="filler"></li>
<li>username</li>
</ul>
</header>
Try this:
header ul {
box-sizing: border-box;
padding: 0;
}
For some reason my navbar is not becoming 100% width. I tried to make .main-header 100% width but still not sure what the problem. The reason to make the navbar 100% is for all the nav items fit on one line. Any ideas what I am doing wrong?
Here is what the navbar looks like on the machine
http://imgur.com/a/za9LH
HTML
**Css**
/* Navigation */
.main-header {
display: flex;
justify-content: space-between;
align-items: center;
background-color: purple;
width: 100%;
}
.logo-name {
margin-left: 1%;
background-color: red;
}
.main-nav {
display: flex;
background-color: yellow;
}
.main-nav li {
padding: 0.3em;
align-items: flex-end;
background-color: transparent;
font-size: 17px;
}
<header class="main-header">
<!--<h1 class="logo-name"><li>R.J Roofer</li></h1>-->
<h1 class="logo-name">R.J Roofer</h1>
<nav class="main-nav">
<li class="nav-item-1">home</li>
<li>services</li>
<li>gallery</li>
<li>about us</li>
<li>contact</li>
<!--<li>FREE QUOTE</li>-->
</nav>
</header>
By default body take 8px margin, thats why your navbar is not fullwifth. So add margin:0 in your body tag. Here is the codepen: https://codepen.io/bhuwanb9/pen/XgmegE
body{
margin:0;
}
Probably all you need is the padding and margin for html and body to be set to zero. You may want to consider using a generic reset like this or this.
/* Navigation */
html, body {
padding: 0;
margin: 0;
}
.main-header {
display: flex;
justify-content: space-between;
align-items: center;
background-color: purple;
width: 100vw;
}
.logo-name {
margin-left: 1%;
background-color: red;
}
.main-nav {
display: flex;
background-color: yellow;
}
.main-nav li {
padding: 0.3em;
align-items: flex-end;
background-color: transparent;
font-size: 17px;
}
<header class="main-header">
<!-- <h1 class="logo-name"><li>R.J Roofer</li></h1>
-->
<h1 class="logo-name">R.J Roofer</h1>
<nav class="main-nav">
<li class="nav-item-1">home</li>
<li>services</li>
<li>gallery</li>
<li>about us</li>
<li>contact</li>
<!-- <li>FREE QUOTE</li>
-->
</nav>
</header>
The problem was, that the container wasn't full width. And the list items were also too small. Here is a pen: https://codepen.io/praedictus/pen/zzvpez
/* Navigation */
.main-header {
display: flex;
justify-content: space-between;
align-items: center;
background-color: purple;
width: 100%;
}
.logo-name {
margin-left: 1%;
background-color: red;
}
.main-nav {
display: flex;
background-color: yellow;
width: 100%;
}
.main-nav li {
padding: 0.3em;
align-items: flex-end;
background-color: transparent;
font-size: 17px;
display: block;
float: left;
width: 20%;
text-align: center;
}
I am styling a header of a webpage. I want the header to be a single line which includes a logo and some navigational links. I feel the best, most modern way to layout this header today is with CSS3's flexbox, so that is what I would like to use.
I would like for the logo to be as far left in the flex container as possible, and the remaining navigation items to be as far right as possible. This could easily be achieved by floating the elements left and right, but that is not what I would like to do. So...
How do you align child elements of a flexbox container to opposite far ends of the main axis?
There is a property for the flexbox child elements that allows you to do this on the cross axis, align-self, but it seems there is none to do this on the main axis.
The best way I have come up with to achieve this is to insert an additional, empty, element in between the logo and the navigational links to serve as a spacer. But part of the reason I am choosing to use flexbox for this header is to cohere with a responsive design and I do not know of a way to make the spacing element take up all the remaining space, regardless of the width of the viewing window.
Here is where I currently stand with the mark-up, simplified to only include the elements pertinent to this situation.
HTML
<ul>
<!-- Should be as far left as possible -->
<li id="main">Some Logo <span>Some tag line.</span></li>
<!-- Should be as far right as possible -->
<li>Home</li>
<li>Products</li>
<li>Price Sheet</li>
<li>Capabilities</li>
<li>Contact</li>
</ul>
CSS
ul {
width: 100%;
display: flex;
flex-flow: row nowrap;
justify-content: flex-end;
align-items: center;
padding: 0;
margin: 0;
list-style: none;
}
li {
margin: 0 8px;
padding: 8px;
font-size: 1rem;
text-align: center;
font-weight: bold;
color: white;
background: green;
border: solid 4px #333;
}
#main { font-size: 2rem; }
#main span { font-size: 1rem; }
From your question:
I do not know of a way to make the spacing element take up all the remaining space, regardless of the width of the viewing window.
This is exactly what the flex-grow CSS rule was designed for. If only one child element has the flex-grow attribute set, then it will take up all the remaining space in the flex container. The only markup you will need in this case is the following:
HTML:
<li id="spacer"></li>
CSS:
#spacer {
visibility: hidden;
flex-grow: 1;
}
Full Live Demo:
ul {
width: 100%;
display: flex;
flex-flow: row nowrap;
justify-content: flex-end;
align-items: center;
padding: 0;
margin: 0;
list-style: none;
}
li {
margin: 0 8px;
padding: 8px;
font-size: 1rem;
text-align: center;
font-weight: bold;
color: white;
background: green;
border: solid 4px #333;
}
#main { font-size: 2rem; }
#main span { font-size: 1rem; }
#spacer {
visibility: hidden;
flex-grow: 1;
}
<ul>
<!-- Should be as far left as possible -->
<li id="main">Some Logo <span>Some tag line.</span></li>
<!-- Spacer element -->
<li id="spacer"></li>
<!-- Should be as far right as possible -->
<li>Home</li>
<li>Products</li>
<li>Price Sheet</li>
<li>Capabilities</li>
<li>Contact</li>
</ul>
JSFiddle Version: https://jsfiddle.net/7oaahkk1/
I think the only flexibility that is needed, at least on large screens, should go on the first flex-item in the list. The one you want to place your logo at.
By setting this items flex-grow rule to 1 and the text-align to left it will stay on the left side, growing in size, making sure all other items stay on the right side. Since the logo may have a greater height value than all the other items it would make sense to change the align-items rule to baseline, making sure all items are horizontally aligned.
Furthermore i have added a few media queries to change the flex settings accordingly.
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: border-box;
}
body {
margin: 0;
}
ul {
width: 100%;
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: stretch;
padding: 0;
margin: 0;
list-style: none;
}
li {
margin: 0;
padding: 8px;
font-size: 1rem;
text-align: center;
font-weight: bold;
color: white;
background: green;
border: solid 4px #333;
}
li:first-child {
font-family: sans;
font-size: 2em;
text-align: center;
}
li:first-child span {
font-size: initial;
}
#media (min-width: 34em) {
ul {
flex-flow: row wrap;
justify-content: space-between;
align-items: flex-start;
}
li {
flex: 1;
}
#main {
flex: 0 0 100vw;
}
}
#media (min-width: 48em) {
ul {
justify-content: flex-end;
align-items: baseline;
}
li {
flex: none;
}
#main {
flex: 1 0 auto;
text-align: left;
}
}
<ul>
<!-- Should be as far left as possible -->
<li id="main">Some Logo <span>Some tag line.</span></li>
<!-- Should be as far right as possible -->
<li>Home</li>
<li>Products</li>
<li>Price Sheet</li>
<li>Capabilities</li>
<li>Contact</li>
</ul>
Essentially you need a row container with two child columns
container is a flexible div
column one is a flexed div with the logo
column two is a flexible ul with flexed li's
AND 'justify-content: space-between' to move the columns to the far ends
Check my snippet (full page)!
.container,
.menu {
display: flex;
}
.container {
justify-content: space-between;
width: 100%;
}
.menu {
padding: 0;
margin: 0;
list-style: none;
}
li,
.logo {
margin: 0 8px;
padding: 8px;
font-size: 1rem;
text-align: center;
font-weight: bold;
color: white;
background: green;
border: solid 4px #333;
}
#main {
font-size: 2rem;
}
#main span {
font-size: 1rem;
}
<div class="container">
<div id="main" class="logo">Some Logo <span>Some tag line.</span>
</div>
<ul class="menu">
<li>Home</li>
<li>Products</li>
<li>Price Sheet</li>
<li>Capabilities</li>
<li>Contact</li>
</ul>
</div>
JSfiddle Demo
Wrap a ul over the rest of the list items and use nested flex container. This is to provide flexbox to act on two elements.
Use justify-content: space-between on the main flexbox parent to equally space the two elements.
.parent-menu {
width: 100%;
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
/* Modify */
align-items: center;
padding: 0;
margin: 0;
list-style: none;
}
li {
margin: 0 8px;
padding: 8px;
font-size: 1rem;
text-align: center;
font-weight: bold;
color: white;
background: green;
border: solid 4px #333;
}
#main {
font-size: 2rem;
}
#main span {
font-size: 1rem;
}
.right-menu {
display: flex;
/* Add */
}
<ul class="parent-menu">
<!-- Should be as far left as possible -->
<li id="main">Some Logo <span>Some tag line.</span>
</li>
<ul class="right-menu">
<!-- Should be as far right as possible -->
<li>Home</li>
<li>Products</li>
<li>Price Sheet</li>
<li>Capabilities</li>
<li>Contact</li>
</ul>
</ul>
One posibility is to set a right margin on the first element
ul {
width: 100%;
display: flex;
flex-flow: row nowrap;
justify-content: flex-end;
align-items: center;
padding: 0;
margin: 0;
list-style: none;
}
li {
margin: 0 8px;
padding: 8px;
font-size: 1rem;
text-align: center;
font-weight: bold;
color: white;
background: green;
border: solid 4px #333;
}
#main {
font-size: 2rem;
margin-right: auto; /* create a right margin as needed */
}
#main span { font-size: 1rem; }
#spacer {
visibility: hidden;
flex-grow: 1;
}
<ul>
<!-- Should be as far left as possible -->
<li id="main">Some Logo <span>Some tag line.</span></li>
<!-- Should be as far right as possible -->
<li>Home</li>
<li>Products</li>
<li>Price Sheet</li>
<li>Capabilities</li>
<li>Contact</li>
</ul>