10

Im using react-modal which is pretty great. Is it possible to dynamically size it (perhaps with css media tag). For example,

  1. For large screen, the modal only takes up a small potion of the screen (lets say max width 200px;
  2. For medium screen, the modal takes up most of the screen (Lets say 80% of the screen width and height
  3. For mobile device, it takes takes up 100% of the width and height.
user172902
  • 3,541
  • 9
  • 32
  • 75

5 Answers5

5

Have a look at this code that prepare for you.

ReactModal.setAppElement('#main');

class ExampleApp extends React.Component {
  constructor () {
    super();
    this.state = {
      showModal: false
    };

    this.handleOpenModal = this.handleOpenModal.bind(this);
    this.handleCloseModal = this.handleCloseModal.bind(this);
  }

  handleOpenModal () {
    this.setState({ showModal: true });
  }

  handleCloseModal () {
    this.setState({ showModal: false });
  }

  render () {
    return (
      <div>
        <button onClick={this.handleOpenModal}>Trigger Modal</button>
        <ReactModal 
           isOpen={this.state.showModal}
           contentLabel="onRequestClose Example"
           onRequestClose={this.handleCloseModal}
           className="Modal"
           overlayClassName="Overlay"
        >
          <p>Modal text!</p>
          <button onClick={this.handleCloseModal}>Close Modal</button>
        </ReactModal>
      </div>
    );
  }
}

const props = {};

ReactDOM.render(<ExampleApp {...props} />, document.getElementById('main'))

Checkout in responsive view:

https://codepen.io/ene_salinas/full/yRGMpG/

Checkout full code:

https://codepen.io/ene_salinas/pen/yRGMpG

Yellow color = large screen
Green color = medium screen
Gray color = Mobile

Don't forget this meta:

"<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">"

Happy coding.

ene_salinas
  • 705
  • 4
  • 11
  • 5
    Can you put the relevant portion of your codepen in the answer? When codepen would stop working, this answer would not give a solution. – wensveen Sep 25 '20 at 12:47
2

It's better to not use calc because of IE support.

..ReactModal__Overlay {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    background-color: rgba(0,0,0,0.7);
    z-index: 999;
}

// this is better to use transform for center the modal and width 
.ReactModal__Content {
    position: absolute; // if it's inside your ReactModal__Overlay if not use Fixed and a higher z-index.
    width: 100%;
    height: 100%;
    left: 50%;
    top: 50%;
    overflow: auto;
    background-color: #fff;
    -webkit-transform: translate(-50,-50%);
    transform: translate(-50,-50%);
}

@media screen and (min-width: 992px) { // desktop
    .modal.modal-content {
        max-width: 200px;
        max-height: 80%;
    }
}

@media screen and (min-width: 426px) and (max-width: 991) { // tablet size
    .modal.modal-content {
        max-width: 80%;
        max-height: 80%;
    }
}

@media screen and (max-width: 425px) { // mobile size
    .modal.modal-content {
        max-width: 100%;
        max-height: 100%;
    }
}
Spleen
  • 2,656
  • 1
  • 10
  • 16
1

I'm also using the library in a project of mine where I came up with the following styling rules for the modal:

.ReactModal__Overlay {
    z-index: 99;
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    background-color: rgba(255,255,255,0.75);
}

.ReactModal__Content {
    position: absolute;
    left: 2.5rem;
    right: 2.5rem;
    top: 2.5rem;
    bottom: 2.5rem;
    background-color: #fff;
    box-shadow: 0 0 10px 0 rgba(0,0,97,0.5);
    overflow: auto;
    border-radius: 4px;
    outline: none;
}

To get your desirable results you would then need to adjust the absolute positioning, so:

1. large screen, modal max-width 200px
@media screen and (min-width: 900px) {
    max-width: 200px;
    left: calc(50% - 100px);
}

2. medium screen, modal about 80% screen width
@media screen and (min-width: 475px) and (max-width: 900px) {
    left: 10%;
    right: 10%;
    top: 10%;
    bottom: 10%;
}

3. mobile screen, modal full width
@media screen and (max-width: 475px) {
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
}
Niels de Bruin
  • 705
  • 5
  • 15
  • It seems like all I have to do is add your three media css styles and wrap them in .ReactModal__Content class. However I find myself needing to add !important to each of those elements for it to take affect. Do you know why? – user172902 Oct 23 '18 at 13:20
  • That would be because there is another selector which is more specific than your styling rules. Maybe you could make yours more specific by adding multiple classnames (also of the parent) or also specifying the element type (`div.ReactModal__Overlay div.ReactModal__Content`). If however the other styles are inline, you either have to move those to CSS or use `!important` on every CSS rule since inline styles have the highest priority. – Niels de Bruin Oct 23 '18 at 13:25
0

I couldn't find a solution how to make the React Modal <<"react-modal": "^3.14.4">> height dynamic, i.e. depending on the content, and forcedly used the global class to be set by default

.ReactModal__Content--after-open {
    width: 1000px !important;
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important;
    min-height: max-content !important;
    overflow: hidden !important;
}
Narek Grigoryan
  • 369
  • 3
  • 7
-1

class Modal extends React.Component {

  state = {
    showModal: false
  };

  handleOpenModal = () => {
    this.setState({ showModal: true });
  };

  handleCloseModal = () => {
    this.setState({ showModal: false });
  };
  
  componentDidMount() {
    ReactModal.setAppElement('#root');
  }

  render() {
    return (
      <div>
        <button onClick={this.handleOpenModal}>Trigger Modal</button>
        <ReactModal
          isOpen={this.state.showModal}
          className="Modal"
          overlayClassName="Overlay"
        >
          <p>Here goes your content!</p>
          <button onClick={this.handleCloseModal}>Close Modal</button>
        </ReactModal>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<Modal />, rootElement);
.Modal {
  height: 100%;
  width: 100%;

  background-color: #ffffff;
  overflow: auto;
}

.Overlay {
  position: fixed;

  top: 0;
  bottom: 0;
  right: 0;
  left: 0;

  display: flex;
  justify-content: center;
  align-items: center;

  background-color: rgba(0, 0, 0, 0.4);
}

@media (min-width: 768px) and (max-width: 1279px) {
  .Modal {
    width: 80%;
    height: 80%;
  }
}

@media (min-width: 1280px) {
  .Modal {
    height: auto;
    width: auto;

    max-width: 500px;
    max-height: 80%;
  }
}
<div id="root" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-modal/3.6.1/react-modal.min.js"></script>
Alex Sánchez
  • 930
  • 5
  • 10