Search code examples
javascriptcssreactjswidth

Why does my page width only stretch to 100% with "fit-content"?


I have tried looking around for this but can't seem to find a question to match my current problem. I am trying to build a mock ecommerce website to practice using React. I have a header component. I want this component to be 100% of the screen width, so that the elements inside this component shrink whenever the page shrinks. I have some global css that sets the height and width of the html and body to 100%:

html, body{
    background-color: rgb(167, 72, 72);
    height: 100%;
    min-width: 100%;
}

I am currently facing two problems, neither of which I understand very well the causes of. When I set my header component (the outermost component) to have a width of 100%, the page shrinks correctly. But when I open up developer tools to check the responsiveness, something goes wrong so that the right side of my header is shrinking faster than the page header_shrink

I am able to fix this by setting the width of my header to "fit-content" instead of "100%". Here is what the header looks like when I shrink the page using developer tools.header_fixed But when I do it this way, the components inside of my header don't shrink correctly. For example, my search bar is supposed to decrease in width as I shrink the page, but when I use "fit-content", it just stays set to whatever size it is. search-bar-constant. When I have the width set to 100% instead of fit content, it looks the way it's supposed to search-bar-fixed.

Sorry for the long explanation, but this is the bulk of my problem. "Width: 100%" allows the items in my header component to shrink correctly, but not the component itself. And "width: fit-content" allows the outer header component to shrink correctly, but not the items inside of it.

Here is the JSX I have for reference:

import React from 'react'
import './Header.css'
import { BiSearchAlt2 as SearchIcon} from "react-icons/bi";
import {RiArrowDropDownLine as DropDownIcon} from "react-icons/ri";
import { CgProfile as Profile } from "react-icons/cg";
import { CgShoppingCart as Cart } from "react-icons/cg";

const Header = () => {

    const texts = [
        'ORDERS OF $5K SHIP FREE',
        'FREE SHIPPING ON SELECT ITEMS: SHOP NOW',
        'BUY A RIG AND YOUR ENTIRE ORDER SHIPS FREE'
      ];
      
      let currentTextIndex = 0;
      
      setInterval(() => {
        const shippingDealsText = document.querySelector('.shipping-deals-text');
        shippingDealsText.classList.add('out');
      
        setTimeout(() => {
          shippingDealsText.textContent = texts[currentTextIndex];
          shippingDealsText.classList.remove('out');
      
          currentTextIndex = (currentTextIndex + 1) % texts.length;
        }, 1000);
      }, 5000);

  return (
    <div className="header">
        <div className="header-top">
            <div className="top-logo">
                <h5 className='small-logo'>LEVIATHAN</h5>
            </div>
            <div className="space"></div>
            <div className="link-container">
                <div className="link-wrap">
                    <a href="/" className="gift-cards">Gift Cards</a>
                </div>
                <div className="link-wrap">
                    <a href="/" className="contact-us">Contact Us</a>
                </div>
                <div className="link-wrap">
                    <a href="/" className="order-status">Order Status</a>
                </div>
                <div className="link-wrap">
                    <a href="/" className="live-chat">Live Chat</a>
                </div>
            </div>
        </div>
        <div className="header-middle">
            <div className="middle-logo">
                <h5 className='big-logo'>LEVIATHAN</h5>
            </div>
            <div className="search-container">
                <div className="search-wrapper">
                    <input 
                        type="text" 
                        id="search-bar" 
                        placeholder="Search"
                        className='search'
                    />
                    <div className="search-icon-wrapper">
                        <SearchIcon className='search-icon'/>
                    </div>
                </div>
            </div>
            <div className="shipping-deals-container">
                <div className="button-container">
                    <div className="shipping-deals-button">
                        <span className="deals-text">DAILY SHIPPING DEALS </span>
                    </div>
                </div>
                <div className="text-container">
                    <div className="text-slideshow">
                        <p className="shipping-deals-text">BUY A RIG AND YOUR ENTIRE ORDER SHIPS FREE</p>
                    </div>
                </div>
            </div>
            <div className="icons-right">
                <Profile className='login-pic'/>
                <span>Log In</span>
                <Cart className='shopping-cart'/>
            </div>
        </div>
        <div className="header-bottom">
            <div className="nav-bar">
                <ul className='navigation'>
                    <li className='menu-items'>
                        <a href="/" className='button drop-down red'>Shop <DropDownIcon className='drop-icon'/></a>
                        <a href="/" className='button'>Equipment for Crossfit</a>
                        <a href="/" className='button'>New Gear</a>
                        <a href="/" className='button'>Barbells</a>
                        <a href="/" className='button'>Plates</a>
                        <a href="/" className='button'>Rigs and Racks</a>
                        <a href="/" className='button'>Shoes</a>
                        <a href="/" className='button'>Apparel</a>
                        <a href="/" className='button'>3 Ships Free</a>
                        <a href="/" className='button'>Zeus</a>
                        <a href="/" className='button drop-down'>The Index</a>
                    </li>
                </ul>
            </div>
        </div>
    </div>
  )
}

export default Header

Here is the styling I am currently applying:

.header {
    min-width: 100%;
    margin: 0;
    padding: 0;
}

.header-top {
    background-color: white;
    display: flex;
    height: 2.5rem;
    width: 100%;
}

.top-logo {
    position: relative;
    margin-left: 3rem;
}

.space {
    flex-grow: 1;
}

.small-logo {
    padding-top: 0.5em;
    position: relative;
    font-size: larger;
    color: rgb(133, 133, 133)
}


.link-container {
    display: flex;
    /*border: 1px solid red;*/
    margin-right: 3rem;
}

.link-wrap {
    /*border: 1px solid green;*/
    font-size: 14px;
    padding-left: 1rem;
    padding-top: 0.75rem;
}

.link-wrap a {
    text-decoration: none;
    color:#666666;
    cursor: pointer;
}




/* Large section of header, black background */
.header-middle {
    background-color: black;
    height: 7rem;
    display: flex;
}

/* Big LEVIATHAN text */
.middle-logo {
    /*border: 1px solid red;*/
    position: relative;
    margin-left: 3rem;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: co;
}


.big-logo {
    font-size: 48px;
    /*padding-top: 2rem;*/
    position: relative;
    color: white;
}

.big-logo:hover {
    color: rgb(210, 0, 0);
}

.search-container {
    position: relative;
    width: 40%;
    display: flex;
    flex-basis: 60%;
    margin-left: 3rem;
    align-items: center;
    justify-content: center;
}

/*This is what has the appearance of the search bar*/
.search-wrapper {
    min-width:100%;
    height: 35%;
    position: relative;
    background-color: white;
    display: flex;
    flex-basis: 50%;
}

.search-icon-wrapper {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 3rem;
}

.search-icon {
    color: black;
    font-size: 20px;
}

/*This is the actual search bar tucked inside*/
.search {
    width: 100%;
    height: 100%;
    border: none;
    outline: none;
    margin-left: 1em;
    font-size: 17px;
}


.search::placeholder {
    color:rgb(94, 94, 94);

    
}


/* This holds onto both our daily shipping deals button */
/* and our text slideshow */
.shipping-deals-container{
    width: 18em;
    margin-left: 2.5em;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: center;
    /*border: 2px solid rgb(136, 77, 255);*/

}

.shipping-deals-button {
    width: 65%;
    height: 44%;
    background-color: rgb(234, 2, 2);
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-top: 1.5em;
}

.button-container {
    width: 100%;
    height: 50%;
    /*border: 2px solid magenta;*/
}

.deals-text {
    color: white;
    font-size: 12px;
    position: relative;
    text-align: center;
    align-items: stretch;
    width: 100%;
}

.text-container {
    /*border: 2px solid rgb(20, 182, 11);*/
    width: 100%;
    height: 50%;
}

.text-slideshow {
    color: white;
    width: 100%;
    height: 50%;
    font-size: 12px;
}


.shipping-deals-text {
    transition: opacity 1s;
    opacity: 1;
    font-size: 13px;
}

.out {
    opacity: 0;
    transition: opacity 1s;
}


.shipping-deals-text-red{
    color: red;
}



.navigation {
    display: flex;
    align-items:flex-start;
    height: 3rem;
}

.menu-items {
    height: 100%;
    margin-left: 1.5rem;
    padding-right: 1.5rem;
    display: flex;
    align-items: flex-start;
    flex: 1;
}

ul {
    list-style-type: none;
    background-color: #333333;  
}


.button {
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    text-decoration: none;
    color: white;
    text-transform: uppercase;
    white-space: nowrap;
    padding: 1em;
    font-weight: bold;
}

.button:hover {
    color:rgb(210, 0, 0)
}

.red {
    background-color: rgb(210, 0, 0);
}

.red:hover {
    color: white;
}

.drop-icon {
    font-size: 25px;
}


.icons-right {
    height: 50%;
    margin-top: 2em;
    min-width: 10%;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-right: 1rem;
}

.login-pic {
    color: white;
    font-size: 20px;
}

.shopping-cart {
    color: white;
    font-size: 20px;
    margin-left: 1rem;
}

.icons-right span {
    color: white;
    margin-left: 0.5em;
}







@media (max-width: 1025px) {
    .shipping-deals-container {
        display: none;
    }
    .header-top {
        display: none;
    }
    .header-middle {
        height: 50%;
    }
    .search-wrapper {
        border: 2px solid white;
        height: 2rem;
    }
    .icons-right {
        margin-bottom: 2rem;
    }
}

I have tried altering the width of my body, and html, but nothing seems to be giving me the solution I am looking for


Solution

  • With width: 100% on .header it shrinks the header the way you want it. That seems to be correct actually.

    The element that prevents shrinking is <li class="menu-items"></li> because of display: flex;. Flexbox is by default not wrapping (flex-wrap: nowrap;).
    Add flex-wrap. wrap; and you'll see everything will shrink with fit-content or width: 100%;

    Hope this helps.


    On another note: You shouldn't use <li> (List-Element) as the list. Thats what <ul> (Unsorted list) is for.

    It should look more like this ->

    <ul>
        <li>
            <a href="">Shop</a>
        </li>
    
        <li>
            <a href="">Equipment for Crossfit</a>
        </li>
    
        <li>
            <a href="">New Gear</a>
        </li>
    
        <!-- ... -->
    </ul>