Container shrinks at certain screen widths (CSS)

  • #1
Darkmisc
220
31
TL;DR Summary
I want to make a sticky navbar with a banner above it. The sticky navbar spans 100% of the screen for all screen widths, but the banner will shrink at seemingly random points so that it doesn't always fill 100% of the width.
Hi everyone

I have a Bootstrap navbar and I'd like to add a banner above it. The Bootstrap navbar fills 100% of the screen width for all screen widths.

I've added a styled component to make a Parent div and a Banner div. These occupy 100% of the screen width most of the time, but at 887px and 464px they shrink (see below).

I've had a similar issue before with a container and was able to fix it by using media queries to set the width back to 100%. I tried this again, but it didn't work.

Lines 12-43 are the only lines that I've added to the Bootstrap code. I also tried using Bootstrap to make the Parent and Banner, but got the same result.


banner.gif


Here is the code for the page.

StickNavbar.js:
import React, { useEffect } from 'react';
import { Link } from 'react-router-dom';
import Example from './Modal';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPhone } from '@fortawesome/free-solid-svg-icons';
import { useGlobals } from '../../Globals';
import "./BNavbar.css";
import logo from "../../images/MJNNavbarlogo.png";
import styled from 'styled-components';


const Parent = styled.div`
display:grid;
background:blue;
width:100vw;

    @media screen and (max-width: 887px) {
    display: grid;
    width:100%;}

    @media screen and (max-width: 464px) {
    display: grid;
    width:100%;}
`;


const Banner = styled.div`
display:grid;
  height: 80px;
  width: 100%;
  width:100vw;

  background: rgba(255, 0, 0, 0.5); /* Red with 50% opacity */

    @media screen and (max-width: 887px) {
    display: grid;
    width:100%;}

    @media screen and (max-width: 464px) {
    display: grid;
    width:100%;}
 
`;




const StickyNavbar = () => {
  const { PrimaryColour, GlobalFont } = useGlobals();


  useEffect(() => {
    // Set the CSS variable for primary color
    document.documentElement.style.setProperty('--primary-color', PrimaryColour);
    // Set the CSS variable for global font
    document.documentElement.style.setProperty('--global-font', GlobalFont);
  }, [PrimaryColour, GlobalFont]);


  const navbarStyle = {
    backgroundColor: PrimaryColour,
    height: "80px",
    boxShadow: '0 4px 8px rgba(0, 0, 0, 0.3)',
    position: 'fixed',
    top: "80px",
    left: 0,
    width: '100%',
    zIndex: 1000,
    alignItems: "center",
  };


  return (
    <Parent>
    <Banner/>
    <nav className="navbar navbar-expand-lg" style={navbarStyle}>
      <Link className="navbar-brand" to="/">
        <img src={logo} alt="Logo" />
      </Link>
      <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
        <span className="navbar-toggler-icon"></span>
      </button>
      <div className="collapse navbar-collapse custom-navbar-collapse" id="navbarNav">
        <ul className="navbar-nav ml-auto">
          <li className="nav-item active">
            <Link className="nav-link" to="/">Home</Link>
          </li>
          <li className="nav-item dropdown">
            <a className="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
              Services
            </a>
            <ul className="dropdown-menu" aria-labelledby="navbarDropdown">
              <li><Link className="dropdown-item" to="/services"
              style={{ fontFamily: 'Roboto, sans-serif' }}
              >Services</Link></li>
              <li><Link className="dropdown-item" to="/services/development"
              style={{ fontFamily: 'Roboto, sans-serif' }}>Development</Link></li>
              <li><hr className="dropdown-divider" /></li>
              <li><Link className="dropdown-item" to="/services/support"
              style={{ fontFamily: 'Roboto, sans-serif' }}
              >Support</Link></li>
            </ul>
          </li>
          <li className="nav-item d-flex align-items-center custom-phone-number" style={{ marginLeft: "25px" }}>
            <FontAwesomeIcon icon={faPhone} className="me-2" />
            <a href="tel:0412123456" className="nav-link phone-number">
              0412 123 456
            </a>
          </li>
          <li className="nav-item active" style={{ marginLeft: "25px" }}>
          <Example buttonText="Contact Us" />
          </li>
        </ul>
      </div>
    </nav>
    </Parent>
  );
};


export default StickyNavbar;

I think the media queries work (just not in the way that I'd like). I tested to see what would happen if I used the media query to set the width to 150%. This makes the pink part appear, which didn't happen before.


150gif.gif


Does anyone know what's happening? I don't understand why I'm getting issues at (seemingly) random widths. Using media queries fixed a similar problem, and I don't understand why it's not working here also.


Thanks
 
Technology news on Phys.org
  • #2
Is this what you are trying to achieve:

HTML:
<style>
#parent{
    background: blue;
    width: 100vw;
    position: fixed;
    top: 0;
    height: 160px;
}

#banner{
    background: red;
    height: 80px;
    position: fixed;
    width: calc(155vw - 487px);
    max-width: 100vw;
    min-width: 50vw;
}
}

#menu{
    background: green;
    height: 80px;
    position: relative;
    top: 80px;
    left: 0;
    width: 100vw;
}

</style>

<div id=parent>
    <div id=banner>BANNER</div>
    <div id=menu>MENU</div>
</div>

Where the width of the banner calc(Avw - Bpx) is found by solving these two equations:
$$\frac{A}{100} W_{max} - B = W_{max}$$
$$\frac{A}{100} W_{min} - B = 0.5W_{min}$$
Where:
$$A = 100 \times \frac{W_{max} -0.5 W_{min}}{W_{max} - W_{min}}$$
$$B = \left( \frac{A}{100} - 1 \right) W_{max}$$
In your case for ##W_{max} = 887\ px## and ##W_{min} = 464\ px##, you get:

##A = 155##
##B = 487##

This will give you a full screen width at 887 px or more and a 50% screen width at 464 px or less and, of course, the banner width will be somewhere between 50% and 100% of the screen width anywhere else.
 
  • Like
Likes Darkmisc
  • #3
Using position:fixed in parent made the navbar and banner disappear, so I left the position as relative.

Using position:fixed in Banner made the banner disapppear (navbar was still there), so I had to use relative for that too.

Here's the code I ended up trying.

CSS:
const Parent = styled.div`
    width: 100vw;
    background:blue;
    height:160px;

    position: relative;  // bars won't show with asbolute or fixed. 
    top: 0;
`;

const Banner = styled.div`
  background: rgba(255, 0, 0, 0.5); /* Red with 50% opacity */
    height: 80px;
    width:100%;
    position: relative;
    width: calc(155vw - 487px);
    max-width: 100vw;
    min-width: 50vw;
`;

const Menu = styled.div`
    background: green;
    height: 80px;
    position: relative;
    // top: 80px;
    left: 0;
    width: 100vw;
`;

ezgif-1-6a126c960a.gif


There was no particular significance to the 150% in my original code. I just wanted to test if the media query worked. I'm a bit puzzled why the media query works to make the navbar wider than 100%, but seems to do nothing to keep the width at 100% (which is what I'm aiming for).
 
  • #4
I thought I'd try a workaround where the banner appears in another file and I just push the navbar down to leave a blank space. I messed it up (banner now appears under the navbar).

Anyhow, when the navbar appears on top, it becomes the thing to shrink, with the banner always being 100% screen width.

bannerunder.gif


Does this provide any clues as to what's going on?
 
  • #5
Darkmisc said:
Using position:fixed in parent made the navbar and banner disappear
You will have to find out why this happens because position: fixed is the only way to make a "sticky" element on your screen.

I don't understand why your navbar and parent are sharing the width of the banner. I'm not an expert with React, so I'm not sure how <Banner/> translates into HTML. Maybe you need to put this banner into a div to isolate it and apply the CSS to this div instead of the banner?
 
  • Like
Likes Darkmisc
  • #6
I think I found the problem. I had an image in the footer that wasn't shrinking with its container. That image was 464px at its smallest.

I don't know why it also created a problem at 887px, but it seems to be gone now.

So my navbar wasn't actually shrinking. It was that the image in the footer was overflowing beyond 100%.
 
  • Like
Likes jack action

Similar threads

Replies
2
Views
820
Replies
8
Views
1K
Replies
5
Views
318
Back
Top