AlePouroullis
AlePouroullis

Reputation: 501

Position: fixed not working as intended for modal window in React (Next.js)

I'm trying to create a modal window in React, but for some reason, using position: fixed sets the position of the modal window relative to the page as opposed to the browser window. This is what it looks like (note: the black boxes were edited in for privacy). enter image description here

Here's the code for this page particularly, including the modal window component, which is at the top.

import React, { useState } from 'react';
import Head from 'next/head';
import utilStyles from '../styles/util.module.css';
import styles from '../styles/education.module.css';
import courseData from '../public/courses.json' assert {type: 'json'};
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCalendar } from '@fortawesome/free-regular-svg-icons';
import { faXmark } from '@fortawesome/free-solid-svg-icons';

function Modal({ isShow, handleClick, longDescription, children }) {
    return (isShow ? 
        <div className="modal-outer" onClick={handleClick}>
            <div className="modal-inner">
                {children}
                <button className="exit"><FontAwesomeIcon className="exit-icon" icon={faXmark}/></button>
                <p className="course-description-long">{longDescription}</p>
            </div>
        </div>
     : "");
}

function CourseContent({ courseName, shortDescription }) {
    return (
        <>
            <h3 className="course-name">{courseName}</h3>
            <p className="course-description-short">{shortDescription}</p>
        </>
    )
}

function CourseCard({ courseName, shortDescription, longDescription}){
  const [isShow, setIsShow] = useState(false);

    function handleClick () {
        setIsShow(!isShow);
    }

  return (
    <>
        <li key={courseName} className="course-card" onClick={handleClick}>
            <CourseContent courseName={courseName} shortDescription={shortDescription}/>
        </li>
        <Modal isShow={isShow} 
        longDescription="this is the long description"
        handleClick={handleClick}>
            <CourseContent courseName={courseName} shortDescription={shortDescription}/>
        </Modal>
        
     </>
  )
}

function DegreeInfo(props) {
  const { universityName, degreeType, degreeName, startYear, endYear, courses } = props;
  return (
    <li>
      <p>{universityName}</p>
      <p>{degreeType}.&nbsp;{degreeName}</p>
      <div className="date-container">
        <FontAwesomeIcon icon={faCalendar}/>
        <time dateTime={`${startYear}/${endYear}`}>{startYear}&ndash;{endYear}</time>
      </div>
      <ul className="course-cards-list">
        {courses.map(course => 
          <CourseCard key={course.courseName} courseName={course.courseName} shortDescription={course.shortDescription} />
        )}
      </ul>
    </li>
  )
}

export default function EducationPage() {
  const yearDecoder = {1: "First-year", 2: "Second-year", 3: "Third-year"};
  return (
    <>
      <Head>
        <title>Education | Alé Pouroullis</title>
      </Head>
      <div  className={`${utilStyles.container} ${utilStyles['float-in']}`}>
        
        <h1>Education</h1>
        <section className="university">
            <h2>Tertiary</h2>
            <ul className={`${styles['main-list']}`}>
                    {courseData.degrees.map(degree => {
                    const courses = degree.courses;
                    courses.sort(sortByYear);
                    return (<DegreeInfo key={degree.name} universityName={degree.universityName}
                                degreeType={degree.type} degreeName={degree.degreeName}
                                startYear={degree.startYear} endYear={degree.endYear}
                                courses={courses}/>)
                    })}
                </ul>
        </section>
        <section className="courses">
          <h2>Courses</h2>
          <ul className="main-list">
            <li className="main-list-item">
              <span className="main-list-text">Mathematics for Machine Learning Specialization</span>
              <ul className="sub-list">
                <li className="sub-list-item"><span className="sub-list-text">Linear Algebra</span></li>
                <li className="sub-list-item"><span className="sub-list-text">Multivariable Calculus</span></li>
              </ul>
            </li>
          </ul>
        </section>
      </div>
    </>
  );
}

function sortByYear(a, b) {
  if (a.year < b.year) {
    return -1;
  } else if (a.year > b.year) {
    return 1;
  } else {
    return 0;
  }
}

And here's the styling for the modal window:

.modal-outer {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, .5);
  display: flex;
  justify-content: center;
  align-items: center; 
}

I'm rather new to React, so excuse this if it's a complete rookie mistake.

Thanks for the help.

Upvotes: 0

Views: 1949

Answers (2)

Praveen
Praveen

Reputation: 11

Please use this css for .modal-outer.

.modal-outer {
  position: fixed;
  top: 50%;
  left: 50%; transform:translate(-50%, -50%);
  background-color: rgba(0, 0, 0, .5);
  display: flex;
  justify-content: center;
  align-items: center; 
}

Upvotes: 1

GiL Itzhaky
GiL Itzhaky

Reputation: 304

use this css for your modal component: top: 50%; left: 50%; transform: translateY(-50%); transform: translatex(-50%); this should center your modal in center of screen.

If you wish to try a cool nice way, you can try React.createPortal function, read about it here: https://reactjs.org/docs/portals.html

Upvotes: 1

Related Questions