Transparent fixed header with flexbox - html

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.

Related

CSS Make Div Expand to Fill Parent but not Overflow

I am working on a project which requires some basic HTML/CSS. I have a code pen which may be easier to visualize: https://codepen.io/Sean713/pen/yLEZVEe
My objective is to make the innerBottomHalf element expand to fully fill the bottomHalf element (barring any padding). I would also like the navbar + wholePage element to take up the full VH.
I currently have it set so that the wholePage takes up the full VH, I'm not sure how to subtract the navbar height from this.
I also see that my innerBottomHalf expands outside of my BottomHalf, I do not know why this is, because I've set its height to be 100%.
I tried a lot of solutions online, the GPT chatbot, and prodding around with the code, but have been unable to figure it out. I appreciate any help.
My code is as follows:
ul {
list-style-type: none;
display: flex;
align-items: center;
}
li a {
display: block;
text-align: center;
padding: 10px 15px;
text-decoration: none;
}
div {
padding: 10px;
}
.wholePage {
background-color: blue;
display: flex;
flex-direction: column;
height: 100vh;
}
.topHalf {
background-color: purple;
display: flex;
justify-content: space-between;
}
.bottomHalf {
background-color: grey;
height: 100%;
}
.innerBottomHalf {
background-color: brown;
height: 100%;
}
.topLeftHalf {
background-color: green;
flex: 1;
height: 50vh;
}
.topRightHalf {
background-color: orange;
flex: 1;
height: 50vh;
}
<ul>
<li><a>Solve</a></li>
<li><a>About</a></li>
<li><a>Other</a></li>
</ul>
<div class="wholePage">
<div class="topHalf">
<div class="topLeftHalf">
This is the top left
</div>
<div class="topRightHalf">
This is the top right
</div>
</div>
<div class="bottomHalf">
This is the bottom half
<div class="innerBottomHalf">
This is the inner bottom half
</div>
</div>
</div>
With height: 100% on nested elements you'll get an overflow because there are heights from other elements being added. Instead of percentage heights, just use flex properties all the way.
body {
display: flex;
flex-direction: column;
height: 100vh;
margin: 0; /* remove default margins */
}
.wholePage {
background-color: blue;
display: flex;
flex-direction: column;
/* height: 100vh; */
flex: 1; /* new */
}
.bottomHalf {
background-color: grey;
/* height: 100%; */
display: flex;
flex-direction: column;
flex: 1;
}
.innerBottomHalf {
background-color: brown;
/* height: 100%; */
flex: 1;
}
/* no adjustments below this line */
ul {
list-style-type: none;
display: flex;
align-items: center;
}
li a {
display: block;
text-align: center;
padding: 10px 15px;
text-decoration: none;
}
div {
padding: 10px;
}
.topHalf {
background-color: purple;
display: flex;
justify-content: space-between;
}
.topLeftHalf {
background-color: green;
flex: 1;
height: 50vh;
}
.topRightHalf {
background-color: orange;
flex: 1;
height: 50vh;
}
<ul>
<li><a>Solve</a></li>
<li><a>About</a></li>
<li><a>Other</a></li>
</ul>
<div class="wholePage">
<div class="topHalf">
<div class="topLeftHalf">
This is the top left
</div>
<div class="topRightHalf">
This is the top right
</div>
</div>
<div class="bottomHalf">
This is the bottom half
<div class="innerBottomHalf">
This is the inner bottom half
</div>
</div>
</div>

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.

Why does my second div element overlap my first?

When I create a new div, the second one, whether it be an image or text. It overlaps the first div container. I figured it may be something to do with the display: flex;, but I'm not sure. Also I am super new so sorry if this is elementary.
* {
font-family: Helvetica;
font-size: 22px;
color: seashell;
background-color: black;
opacity: 0.9;
}
.container {
height: 69px;
border-bottom: 1px solid seashell;
position: fixed;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.container li {
display: inline;
text-decoration: underline;
justify-content: flex-end;
margin-right: 20px;
}
.header-image {
height: 50px;
margin-left: 10px;
}
.container li:hover {
text-decoration: none;
cursor: pointer;
color: darkgray;
}
<div class="container">
<img class="header-image"
src="https://content.codecademy.com/courses/freelance-1/unit-4/img-tea-cozy-logo.png">
<ul>
<li>Mission</li>
<li>Featured Tea</li>
<li>Locations</li>
</ul>
</div>
<div>
<p>Hello</p>
</div>
Thank you.
It's because your container has positioned: fixed; assigned to it. If you add a margin to your second div and apply top: 0 to your container you can push it down without affecting your container element like below:
* {
font-family: Helvetica;
font-size: 22px;
color: seashell;
background-color: black;
opacity: 0.9;
}
.container {
height: 69px;
border-bottom: 1px solid seashell;
position: fixed;
top: 0rem; /* force container to the top of the page */
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.container li {
display: inline;
text-decoration: underline;
justify-content: flex-end;
margin-right: 20px;
}
.header-image {
height: 50px;
margin-left: 10px;
}
.container li:hover {
text-decoration: none;
cursor: pointer;
color: darkgray;
}
div:nth-of-type( 2 ) {
margin-top: 4rem; /*give the second div top margin to push it down */
}
<div class="container">
<img class="header-image"
src="https://content.codecademy.com/courses/freelance-1/unit-4/img-tea-cozy-logo.png">
<ul>
<li>Mission</li>
<li>Featured Tea</li>
<li>Locations</li>
</ul>
</div>
<div>
<p>Hello</p>
</div>
just remove position: fixed form .container or if you wants it to be fixed you can add z-index: 1
Your second div ('Hello' block) overlaps first div(header container), because first div has position: fixed style.
When you apply position: fixed or position: absolute to element, the element is become removed from the normal document flow, and no space is created for the element in the page layout(https://developer.mozilla.org/en-US/docs/Web/CSS/position).
Since div is removed from document flow it doesn't take any space in document, imagine that div is flying on another separate layer.
If you want to keep position: fixed property you need to compensate it's height by applying:
padding-top: 69px to div's parent -> body.
and
top: 0 to .container to make header stick to the top of the screen;
This way all next elements will have right position from beginning and you will not need to offset each of them.
* {
font-family: Helvetica;
font-size: 22px;
color: seashell;
background-color: black;
opacity: 0.9;
}
/* HERE */
body {
padding-top: 69px;
}
.container {
height: 69px;
border-bottom: 1px solid seashell;
/* HERE */
top: 0;
position: fixed;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
}
.container li {
display: inline;
text-decoration: underline;
justify-content: flex-end;
margin-right: 20px;
}
.header-image {
height: 50px;
margin-left: 10px;
}
.container li:hover {
text-decoration: none;
cursor: pointer;
color: darkgray;
}
<div class="container">
<img class="header-image"
src="https://content.codecademy.com/courses/freelance-1/unit-4/img-tea-cozy-logo.png">
<ul>
<li>Mission</li>
<li>Featured Tea</li>
<li>Locations</li>
</ul>
</div>
<div>
<p>Hello</p>
</div>
<div>
<p>Second Hello</p>
</div>

I have a navbar. How do I set the height of the items to be 100% of the navbar?

I've been trying to make a navbar but I haven't quite been succesful. The navbar div has a height of 60px, however, I can't seem to be able to increase the height of the inside elements in any way. (except padding) What am I doing wrong?
What I'm getting
What I'm trying to get
#navbar {
width: 100vw;
height: 60px;
background: #deff00;
box-shadow: 0 0 50px black;
z-index: 2;
position: relative;
top: 85px;
}
#navbar ul {
height: 100%;
list-style: none;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.navbar-link {
text-decoration: none;
color: black;
height: 60px;
padding: 0 20px;
}
.navbar-link:hover {
background: #adc703;
}
<div id="navbar">
<ul>
<li>
<a href="#" style="font-weight: bold;" class="navbar-link"
>ÚVODNÍ STRÁNKA</a
>
</li>
<li>
ŠKOLA
</li>
<li>STUDIUM</li>
<li>FOTOGALERIE</li>
<li>KONTAKT</li>
</ul>
</div>
Thanks!
Try this:
#navbar {
width: 100vw;
height: 60px;
background: #deff00;
box-shadow: 0 0 50px black;
z-index: 2;
position: relative;
top: 85px;
}
#navbar ul {
height: 100%;
list-style: none;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
#navbar li {
display: table;
}
.navbar-link {
text-decoration: none;
color: black;
height: 60px;
padding: 0 20px;
vertical-align: middle;
display: table-cell;
}
.navbar-link:hover {
background: #adc703;
}
Just added display: table; for the li, and vertical-align: middle;display: table-cell for the a tag, sometimes this old technics fit perfect)
Codepen: https://codepen.io/Liveindream/pen/mdyXmxj?editors=1100
If I'm understanding this question correctly, you want to raise the elements in height. The thing that is constricting you from doing that is inside of your CSS
#navbar ul {
height: 100%;
list-style: none;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
Remove align-items: center; from #navbar ul
So that it looks like this:
#navbar ul {
height: 100%;
list-style: none;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
Now you should be able to increase and/or decrease it in height to correctly align it onto your div tag the way you'd like.

How to get two divs centered vertically and have their background fill browser

I have two divs, but they are at the top, I want them in the middle, also each one has a background color that I'd like to fill their half of the screen.
.contenedor {
display: flex;
justify-content: space-around;
align-items: center;
font-size: 50px;
}
.español {
background: red;
}
.english {
background: blue;
}
a {
text-decoration: none;
}
<div class="contenedor">
<div class="español">
Español
</div>
<div class="english">
English
</div>
</div>
How would I go about doing this?
A picture says more than a thousand words
Thanks!
There's quite a lot to add to your code. If you want to use flex (as you did for the container), use the following settings for the elements:
html,
body {
height: 100%;
margin: 0;
}
.contenedor {
display: flex;
justify-content: space-around;
align-items: center;
font-size: 50px;
height: 100%;
}
.contenedor>div {
width: 100%;
height: 100%;
text-align: center;
position: relative;
display: flex;
flex-direction: column;
justify-content: center;
}
.español {
background: red;
}
.english {
background: blue;
}
a {
text-decoration: none;
color: white;
}
<div class="contenedor">
<div class="español">
Español
</div>
<div class="english">
English
</div>
</div>
There are many approaches you could choose.
A simple one is to set the 2 divs with abolute positionning, with each a width of 50%.
This way each div will occupy the whole height of the page and you don't have to worry about body margins or padding.
.contenedor {
font-size: 50px;
}
.espanol,
.english {
position: absolute;
top: 0;
bottom: 0;
width: 50%;
}
.espanol {
background: red;
left: 0;
}
.english {
background: blue;
left: 50%;
}
.contenedor a {
color: #fff;
text-align: center;
text-decoration: none;
display: flex;
justify-content: center;
flex-direction: column;
height: 100%;
}
<body>
<div class="contenedor">
<div class="espanol">
Español
</div>
<div class="english">
English
</div>
</div>