CSS Navigation Bar width exceeds a screen view - html

I have a HTML file and CSS file with code:
body {
border: 0px;
padding: 0px;
margin: 0px;
}
/* HEADER STYLE */
header .top-nav {
padding: 10px;
margin: 0;
position: fixed;
width: 100%;
background-color: aqua;
display: flex;
flex: 1;
align-items: center;
justify-content: space-between;
}
header .top-nav-right-block {
display: flex;
}
<header>
<nav class="top-nav">
Home
<div class="top-nav-right-block">
Portfolio
Contacts
</div>
</nav>
</header>
The problem is when I set a 10px padding of .top-nav I expect to have a 100% width navbar with 10px of padding from each side but what I get instead is just a content pushed out of screen from right side. Inspecting the code in a browser indicates that I have a position-right: -20px.
I understand that paddings applied from left side only and pushes content to the right on respective value, but I don't understand why.

Change the box-sizing on your nav bar to border-box;
See: https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing
body {
border: 0px;
padding: 0px;
margin: 0px;
}
/* HEADER STYLE */
header .top-nav {
padding: 10px;
margin: 0;
position: fixed;
width: 100%;
background-color: aqua;
display: flex;
flex: 1;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
}
header .top-nav-right-block {
display: flex;
}
<header>
<nav class="top-nav">
Home
<div class="top-nav-right-block">
Portfolio
Contacts
</div>
</nav>
</header>
Alternately, removing the width and fixed position would resolve the issue, but I'm assuming you want to keep the fixed positioning.

Try setting the box-sizing property to border-box for the .top-nav element, like this:
body {
border: 0px;
padding: 0px;
margin: 0px;
}
/* HEADER STYLE */
header .top-nav {
box-sizing: border-box;
padding: 10px;
margin: 0;
position: fixed;
width: 100%;
background-color: aqua;
display: flex;
flex: 1;
align-items: center;
justify-content: space-between;
}
header .top-nav-right-block {
display: flex;
}
<header>
<nav class="top-nav">
Home
<div class="top-nav-right-block">
Portfolio
Contacts
</div>
</nav>
</header>
box-sizing defaults to content-box if not specified which means that the padding and border are added to the width and height of the element, rather than being included within the specified width and height.

You can add to css:
* {
box-sizing: border-box;
}
https://codepen.io/rachkovartem/pen/ZEMbVJE
https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing

Related

CSS border bottom on Navigation bar

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.

flex direction "row" inside a flexbox with flex-direction "column"

I am trying to make a navbar using flexbox. In my code I have the actual navbar wrapped with flex- direction:"row" to align the logo and the button.
Now I want to have the nav-inner (the beige div) under the navbar (that should be 100vw wide), but actually it sits next to the navbar.
I have tried to change the flex-direction to "column" inside my nav-menu div, but the Hamburger button goes out of the screen. Am I doing something wrong?
body {
margin: 0;
overflow: hidden;
}
/* defaults */
.safe-view {
display: flex;
height: 100vh;
}
.hamburger {
height: 30px;
width: 30px;
}
/**/
/* navbar */
.navbar {
position: sticky;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 30px;
width: 100vw;
font-size: 1.2em;
height: 100px;
}
.nav-menu {
width: 100%;
display: flex;
flex-direction:row;
/*flex-direction:column;*/
position: absolute;
height: 100%;
overflow: hidden;
background-color: white;
}
.nav-inner {
height: 100%;
width: 100%;
background-color: blanchedalmond;
}
/**/
<div class="safe-view">
<div class="nav-menu">
<div class="navbar">
<h1>logo</h1>
<button class="hamburger"></button>
</div>
<div class="nav-inner"></div>
</div>
</div>
This is a CSS box-model issue. You need to add box-sizing: border-box. This will ensure that padding is included in calculation of the width.
*{
box-sizing: border-box;
}
By default box-sizing is set to content-box. This will only care about the element content and shift padding and border outside of the element. That is why you saw the button push out to the right! This can also help you to understand further.
Also, flex-direction for .nav-menu needs to be set to column in order to position .nav-inner below.
Heres an alternative. I removed padding and just used calc() function to create padding. But always include box-sizing:border-box in your CSS :)
*{
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
overflow: hidden;
}
.safe-view {
display: flex;
height: 100vh;
}
.navbar {
position: sticky;
display: flex;
flex-direction:row;
align-items: center;
justify-content: space-between;
width: calc(100vw - 60px);
margin: 0 auto;
font-size: 1.2em;
height: 100px;
}
.nav-menu {
width: 100%;
display: flex;
flex-direction:column;
position: absolute;
height: 100%;
overflow: hidden;
background-color: white;
}
.nav-inner {
height: 50px;
width: 100%;
background-color: blanchedalmond;
}
<div class="safe-view">
<div class="nav-menu">
<div class="navbar">
<h1 class="logo">logo</h1>
<button class="hamburger">button</button>
</div>
<div class="nav-inner"></div>
</div>
</div>

Flexbox align center

I have a side nav-bar. I want the items to be evenly spaced so that it fills out the whole 'bar'.
I've tried making my 'container' have justify-content: space-between. However, it's not taking the flex attribute.
I'll post my code as it'll show what I mean.
I also would like it that it stays 'fixed' but doing so cuts the 'container' to about 50% height.
https://codepen.io/azhorabai/pen/MOOwrJ
* {
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
font-family: "Dosis", sans-serif;
}
body {
display: flex;
min-height: 100vh;
flex-flow: row wrap;
margin: auto;
background-color: black;
}
.side-menu {
background-color: lightcoral;
font-size: 2em;
text-transform: uppercase;
justify-content: space-between;
}
.side-menu ol {
list-style-type: none;
max-width: 100%;
padding: 0px 30px;
}
.side-menu li {
line-height: 5em;
}
#projects {}
.top-header {
background-color: lightgreen;
height: 20vh;
box-sizing: border-box;
}
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Dosis:400,700" rel="stylesheet">
</head>
<body>
<title>X. Quisite</title>
<nav class="side-menu">
<ol>
<li class="about-me">About</li>
<li class="projects">Projects
<li>
<li class="skills">Services</li>
<li class="contact">Contact</li>
</ol>
</nav>
</body>
</html>
The justify-content property applies only to flex containers. So it must apply to an element that also has display: flex or display: inline-flex (read more).
body {
display: flex;
height: 100vh;
margin: 0;
background-color: black;
}
.side-menu {
background-color: lightcoral;
font-size: 2em;
text-transform: uppercase;
justify-content: space-between;
display: flex; /* new */
flex-direction: column; /* new */
}
a {
padding: 0px 30px;
}
<nav class="side-menu">
<a class="about-me">About</a>
<a class="projects">Projects</a>
<a class="skills">Services</a>
<a class="contact">Contact</a>
</nav>
When applying flex rules like justify-content: space-between; you need to apply them to an element with the rule display: flex declared.
These flex rules will apply to direct descendant nested elements only, so you should declare them to the unordered list item (ol), then specify the flex-direction: column so that you can justify the content vertically. In addition, you can declare align-items: center; to horizontally align the list items (these rules typically work in reverse if the direction has been specified horizontal, or row, e.g: flex-direction: row).
Lastly, your fixed navigation will occupy the full height of the viewport if you declare top: 0 and bottom: 0 properties.
*{
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
font-family: 'Dosis', sans-serif;
}
body{
display: flex;
min-height: 100vh;
flex-flow: row wrap;
margin: auto;
background-color: black;
}
.side-menu {
background-color: lightcoral;
font-size: 2em;
text-transform: uppercase;
position: fixed;
top: 0;
bottom: 0;
}
.side-menu ol {
list-style-type: none;
max-width: 100%;
padding: 0px 30px;
display: flex;
flex-direction: column;
justify-content: space-around;
margin: 0;
height: 100%;
align-items: center;
}
.side-menu li{
/*line-height: 5em;*/ /* unset for code snippet preview */
}
#projects{
}
.top-header{
background-color: lightgreen;
height: 20vh;
box-sizing: border-box;
}
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Dosis:400,700" rel="stylesheet">
</head>
<body>
<title>X. Quisite</title>
<nav class="side-menu">
<ol>
<li class="about-me">About</li>
<li class="projects">Projects</li>
<li class="skills">Services</li>
<li class="contact">Contact</li>
</ol>
</nav>
</body>
</html>

List exceeds width of parent container

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;
}

How to use Flex Vertical Center and Viewport Units vh?

I have a simple page layout with a vertical centered content box using flex.
I use min-height: 70vh; to stretch the container height to allow the content-box to vertical center.
I also have a footer which height gap is stretched to the bottom of the page using flex: 1;.
https://jsfiddle.net/Lvod41L2/
Problem
If the content-box has enough content that makes it taller than the page the footer is not pushed to the bottom and scrolls with the page. Example: height: 2000px;
If I remove min-height: 70vh; the footer is pushed to the bottom of the page as it should look.
HTML/CSS
<!DOCTYPE html>
<html>
<head>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
flex-direction: column;
}
.header {
min-height: 40px;
padding: 0.8em 2em;
background: black;
color: white;
}
.flex-container {
display: flex;
align-items: center;
min-height: 70vh;
padding: 2em;
background: gray;
}
.content-box {
width: 300px;
height: 300px;
margin: auto;
padding: 2em;
text-align: center;
background: black;
color: white;
}
.footer {
z-index: 100;
position: relative;
flex: 1;
padding: 2em;
background: black;
color: white;
}
</style>
</head>
<body>
<div class="header">
Header
</div>
<div class="flex-container">
<div class="content-box">
Content Box
</div>
</div>
<div class="footer">
Footer
</div>
</body>
</html>
SOLUTION - JSFIDDLE
Add flex: 0 0 auto; to the container
.flex-container {
display: flex;
align-items: center;
min-height: 70vh;
padding: 2em;
background: gray;
flex: 0 0 auto; /* Added rule */
}
I hope that solves the issue.