News

Make pop-up modal boxes with pure CSS

Show new information in a modal box along with animation effects without loading a new page

popup01

Show new information in a modal box along with animation effects without loading a new page

popup01

Good design is always about presenting information in a way that is simple to understand.

And yet, sometimes the amount of information causes a conflict with the need to present information in a way that is easy to comprehend and where the information is still complete. One option would be to separate content onto different pages, but this causes scope for unnecessary page loading and poor usability, especially where users are accessing the webpage through a slow internet connection such as via mobile data with poor reception.

Modal boxes offer a perfect solution to the problem by enabling additional information to appear on the page when they are clicked without the need to load a new page. Furthermore, modal boxes can be closed again in order to return the user to the original content without the need to reload.
This tutorial looks at several options for how modal boxes can be developed with CSS to provide highly useable designs for websites and web apps that are easy to adapt for different types of content you may want to present. The functionality of these modal boxes will focus on easy access in a way that enhances the user experience of the webpage.

Get started

First, declare the main HTML page structure, including the head and body section within the HTML page. We will need a content container made from a div element with an ID called container to control page content flow.

Content overview

With the main layout elements in place, we can insert the main content inside the container element. The page will have a descriptive title and introduction text to provide the main overview of the information contained on the page. This will provide information needed by the reader to identify whether they want to read further.

Option navigation

Next insert the available options that will provide the user with access to additional information. These options will be regular <a> links contained inside a <nav> container. Unlike regular <a> tags that use their href to link to external pages, these <a> links will link to ID components on this page using a # symbol in their href attribute preceding the ID name being linked to.

<nav>
<a href="#alpha">Alpha</a>
<a href="#bravo">Bravo</a>
<a href="#charlie">Charlie</a>
<a href="#delta">Delta</a>
<a href="#echo">Echo</a>
</nav>

Add modal boxes

The modal boxes will all use <article> as their container element and will have an optional attribute of data-transition to specify the type of transition they will use to appear and disappear, providing a high degree of flexibility for individual sections.

<article id="alpha">
</article>
<article id="bravo" data-transition="left">
</article>
<article id="charlie" data-transition="right">
</article>
<article id="delta" data-transition="zoom">
</article>
<article id="echo" data-transition="fade">
</article>

Modal box content

Insert content into each of the <article> containers. Each modal box will need the ability to be closed, which will be triggered by an <a> tag linking to a blank ID using just # for its href. We also want to give this closing button a ‘data-button=”close’ attribute so we can style it later.

<article id="bravo" data-transition="left">
<a href="#" data-button="close">x</a>
<img src="img/photo1.jpg" alt="Coastline" />
<h2>Bravo</h2>
<p>Lorem ipsum dolor sit amet.</p>
</article>

Initiate CSS styling

The main HTML template content is now complete, but the additional CSS stylesheet resource file is still required to add the styling. Create a text file called ‘styles.css’, making sure that your text editor does not add .txt as a file extension. These also need attaching from the <head> section of HTML document.

Style HTML body

Don’t forget that the <html> and <body> elements on a webpage are set to a height of just one line by default, hence causing problems if we want to create a container that has a full webpage height. Solve this by setting the <html> and <body> elements to be full height in the CSS.

html,body{
display: block;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}

Style the container

The container needs to be styled in a way so that it will stand out. This can be done by changing the main page background colour and positioning the container in the centre of the page. To do this, we need to update the <head>, <body> and container sections.

html,body{
font-family: "Trebuchet MS", Helvetica, sans-serif;
background: rgb(21, 34, 47);
}
#container{
display: block;
width: 1000px;
height: 100%;
background: #ccc;
margin: 0 auto 0 auto;
padding: 1em;
}

Options container

We want the options to stand out from any standard content on the page. You can do by styling the options container that was created with the <nav> tag. This will be styled with a distinctive border and margin spacing to ensure it appears separate from surrounding content.

nav{
display: block;
padding: 1em;
border: 3px solid #000;
margin: 2em 0 2em 0;
}

Option styles

The option navigation elements need to appear like buttons, even though they are just <a> link tags. This can be done through CSS by making these elements display as an inline-block, which enables us to apply sizing and padding to make them appear like buttons.

nav    a {
display: inline-block;
padding: 1em;
margin-left: 1em;
font-size: 1.5em;
border: 3px solid #fff;
background: #333;
color: #fff;
}

Option hover

Good usability will make it easy for users to know which option they will select if they are to press on their trackpad or mouse button. We can apply the :hover property to the options so that they change colour when the user’s mouse pointer is placed over them, indicating which option is about to be selected.

nav    a:hover{
border-color: #333;
background: #fff;
color: #333;
}

Define modal boxes

The modal boxes all use <article> elements as their containers, hence we can use CSS to define their default styles for width, height and positing. We want these elements to appear at pixel-specific locations on the screen so we use absolute positioning to allow attributes for top, left and z-index.

article{
display: block;
position: fixed;
z-index: 9999;
left: 25%;
top: 100%;
width: 40%;
height: 50%;
padding: 2em 5% 0 5%;
border-radius: 1em;
background: #000;
color: #fff;
overflow: auto;
}

Set transitions

Modal boxes need to be able to show transition from one CSS property state to another for the animation to be visible. To keep our CSS simple, set ‘all’ properties to be eligible for transition animations. You can add other properties later to trigger their animation sequence.

article{
padding-bottom: 1em;
-webkit-transition: all 2s;
transition: all 2s;
}

Target selector

Now apply the ‘target’ selector to define the CSS states for elements that are selected via their ID. Elements will transition to this state when they are clicked on – ie this is the state that all modal boxes will appear as. The !important element ensures that these styles overwrite the previously defined styles for <article> elements.

:target {
visibility: visible !important;
left: 25% !important;
top: 25% !important;
width: 40% !important;
height: 50% !important;
opacity: 1 !important;
}

Transition: fade

Now that the modal boxes have the ability to transition from the default <article> settings to the :target settings, we can apply rules that will overwrite the default <article> settings through the data-transition attribute. Our first rule will let the modal box fade in and out of view.

[data-transition="fade"]{
left: 25%;
top: 25%;
opacity: 0;
visibility: hidden;
}

Transition: left

The next transition we want to use is to let the modal box slide in from the left by placing the default position of the modal box as fully off the screen to the left. This means that it will move from this position to the centred position set in the :target when this element is selected for display.

[data-transition="left"]{
left: -100%;
top: 25%;
}

Transition: right

We also want a transition effect to make the modal box slide in from the right by placing the default position of the modal box as fully off the screen to the right – ie 100 per cent of the screen width from the left.

[data-transition="right"]{
left: 100%;
top: 25%;
}

Transition: zoom

The final transition to add is the ability for a modal box to zoom in and out from the screen centre. This transition requires the default style to be of zero width and height. We’ll also add an opacity of zero so that the modal box will fade in and out of view as it sizes up or down.

[data-transition="zoom"]{
visibility: hidden;
left: 50%;
top: 50%;
width: 0;
height: 0;
opacity: 0;
}

Style close buttons

The modal boxes have an an element with an attribute of ‘data-button=”close”’ used to close the modal box. We will style this to appear in the top-right corner as a red circle – achieved by setting the border radius to be curved and for the element to float to the right.

article [data-button="close"]{
display: block;
float: right;
background: #c00;
color: #fff;
border: 3px solid #fff;
border-radius: 1em;
padding: 1em;
text-decoration: none;
}

Style images

Now we change the colour of the close button by applying styles through the :hover selector that will trigger the change when the user hovers their mouse pointer over the close button.

article [data-button="close"]:hover{
background: #fff;
color: #c00;
border: 3px solid #c00;
}

Image spacing

Our modal box design makes use of an image to be displayed at the left of the text content. This image should be the height of the modal box – we can use CSS to set the image as 100 per cent of the modal box article

img{
display: block;
float: left;
height: 100%;
}

Place a margin

Make sure that there is a margin of one text character to the right of the image so the text isn’t too close to the image. Place a margin to the right of the image, so that the positioning of all elements in the modal box will take this into account.

article img{
margin-right: 1em;
}
article img{
display: block;
float: left;
height: 100%;
}
×