Challenge: Sizing and decorating a content panel
In this challenge you are provided with a lightly-styled page structure that renders a content panel containing text and images, with a heading at the top and a button bar at the bottom. We want you to follow the instructions to size and decorate it, producing an interesting layout as a result. Along the way, we'll test your knowledge of CSS values and units, sizing, overflow, and backgrounds and borders.
Starting point
We are going to get you to solve this challenge on your local development environment; ideally, you'll want to view the example in a full browser window to make sure you are going in the right direction.
-
Create a new folder on your computer called
size-decorate-content-panel
. -
Inside the folder, create an
index.html
file and paste the following content into it:html<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Challenge: Content pane with button bar</title> <link href="style.css" rel="stylesheet" /> </head> <body> <section class="pane"> <h1>Content pane</h1> <div class="content"> <h2>Some exciting content</h2> <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Proin tortor purus <a href="#">platea sit eu id</a> nisi litora libero. Neque vulputate consequat ac amet augue blandit maximus aliquet congue. Pharetra vestibulum posuere ornare <a href="#">faucibus fusce dictumst</a> orci aenean eu facilisis ut volutpat commodo senectus purus himenaeos fames primis convallis nisi. </p> <img src="https://mdn.github.io/shared-assets/images/examples/leopard.jpg" alt="Closeup of a large wild cat's eyes and nose" /> <p> Phasellus fermentum malesuada phasellus netus dictum aenean placerat egestas amet. <a href="#">Ornare taciti semper dolor tristique</a> morbi. Sem leo tincidunt aliquet semper eu lectus scelerisque quis. Sagittis vivamus mollis nisi mollis enim fermentum laoreet. </p> <h2>More exciting content</h2> <p> Curabitur semper venenatis lectus viverra ex dictumst nulla maximus. Primis iaculis elementum conubia feugiat venenatis dolor augue ac blandit nullam ac <a href="#">phasellus turpis</a> feugiat mollis. Duis lectus porta mattis imperdiet vivamus augue litora lectus arcu. Justo torquent pharetra volutpat ad blandit bibendum <a href="#">accumsan nec elit cras</a> luctus primis ipsum gravida class congue. </p> <img src="https://mdn.github.io/shared-assets/images/examples/balloons-landscape.jpg" alt="Three colorful hot air balloons floating across a blue, nearly cloudless sky" /> <p> Vehicula etiam elementum finibus enim duis feugiat commodo adipiscing tortor <a href="#">tempor elit</a>. Et mollis consectetur habitant turpis tortor consectetur adipiscing vulputate dolor lectus iaculis convallis adipiscing. Nam hendrerit <a href="#">dignissim condimentum ullamcorper diam</a> morbi eget consectetur odio in sagittis. </p> </div> <div class="controls"> <button>One</button> <button>Two</button> <button>Three</button> <button>Four</button> </div> </section> </body> </html>
-
Inside the folder, create a
style.css
file and paste the following content into it:css/* Type and text */ * { box-sizing: border-box; } html { height: 100%; } body { height: inherit; font: 1.2em / 1.5 system-ui; margin: 0 auto; } h1 { font-size: 2em; } h2 { font-size: 1.5em; } a { color: red; } a:hover, a:focus { text-decoration: none; } /* Styling the pane */ .pane { height: 100%; } h1, .controls { margin: 0; display: flex; justify-content: center; align-items: center; } .content { } .controls { justify-content: space-around; gap: 20px; padding: 20px; } button { flex: 1; }
-
Save your files and load
index.html
in a browser ready to test.
Project brief
Follow the steps below to complete the project, sizing the content pane appropriately and adding the required decorations.
Headings
- Use generated content to make a book emoji (📖) appear at the start of the top-level heading. Add
20px
of spacing in between the emoji and the heading text. - Currently, the headings are sized in
em
s. We'd like you to change the sizing so that it is responsive, changing based on the viewport width but also remaining zoomable. To achieve this, make each heading level's sizing equal to a suitable percentage of the viewport width plus a smallerem
value.
Container sizing
- Make the width of the
<section>
wrapper element with a class ofpane
equal to60%
, but give it a maximum width of1000px
and minimum width of480px
. See if you can find a CSS function that allows you to set this using a single declaration. - Center the
pane
<section>
horizontally on the page usingauto
margins. - Set the
<h1>
and the<div>
with a class ofcontrols
to both be100px
high. Set the<div>
with a class ofcontent
to be100%
of the<body>
height, minus the height of the<h1>
and the<div class="controls">
. This should give you a UI that always stretches to be the height of the viewport, with a flexible content container and a fixed height heading and button bar. - The buttons look a bit thin and hard to read. Give them a height of
100%
of their container, and a font size of1.2em
. - Give the
pane
<section>
and thecontent
<div>
top/bottom padding of0
on both sides and left/right padding of20px
on both sides.
Image placement
- The images currently overflow the content container. Set a maximum width of
90%
on them to stop this happening. - Center the images horizontally using
auto
margins.
Decoration
- Apply a linear gradient to the
pane
<section>
that changes smoothly from#9fb4c7
at the top to#7f7caf
at the bottom. - Give the images a
1px solid
border and thecontent
<div>
a2px solid
border. Give the borders a color of#28587b
. - Give the
content
<div>
a background color of#eeeeff
, and a background image ofhttps://mdn.github.io/shared-assets/images/examples/big-star.png
. The background image should not repeat, should be sized at40px
by40px
, and should be placed5px
from the top of the container and15px
from the right. - Give the buttons a text color of
white
and a background color ofrgb(40 88 123 / 0.8)
. On hover or focus, the buttons should change to have a fully opaque version of the same background color. - Set a
10px
border radius on thecontent
<div>
and the buttons.
Overflow
At this point, you should still notice a problem with the UI — the content contained in the content
<div>
overflows its container, and the whole page scrolls to allow you to access it all. We want the content
<div>
to scroll instead. How can you achieve this?
Hints and tips
- Use the W3C CSS Validator to catch unintended mistakes in your CSS — mistakes you might have otherwise missed — so that you can fix them.
- You don't need to alter the HTML in any way.
Example
The starting state of the project will render like this:
The finished project should look like this (we've rendered this at 90%
width, not 60%
, so it looks better in the narrow output pane):
Click here to show a possible solution
The finished CSS looks like so:
/* Type and text */
* {
box-sizing: border-box;
}
html {
height: 100%;
}
body {
height: inherit;
font: 1.2em / 1.5 system-ui;
margin: 0 auto;
}
h1 {
/* Solution: Responsive heading sizing, equal to vw value plus em value */
font-size: calc(2vw + 1em);
}
/* Solution: Add book emoji as generated content, with 20px spacing between
it and the heading content */
h1::before {
content: "📖";
margin-right: 20px;
}
h2 {
/* Solution: Responsive heading sizing, equal to vw value plus em value */
font-size: calc(1.5vw + 0.75em);
}
a {
color: red;
}
a:hover,
a:focus {
text-decoration: none;
}
.pane {
height: 100%;
/* Solution: Set container width percentage and min
and max width with one declaration, using the clamp()
function */
width: clamp(480px, 60%, 1000px);
/* Solution: Center container using auto margins */
margin: 0 auto;
/* Solution: Set container top/bottom padding of 0 on both sides
and left/right padding of 20px on both sides */
padding: 0 20px;
/* Solution: Apply linear gradient from top to bottom */
background: linear-gradient(to bottom, #9fb4c7, #7f7caf);
}
h1,
.controls {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
/* Solution: Set the h1 and controls div to each be 100px high */
height: 100px;
}
.content {
/* Solution: Set background color and image on the content div,
and size the image */
background: url("https://mdn.github.io/shared-assets/images/examples/big-star.png")
no-repeat top 5px right 15px / 40px #eeeeff;
/* Solution: Set content top/bottom padding of 0 on both sides and
left/right padding of 20px on both sides */
padding: 0 20px;
/* Solution: Set the content div to be 100% high minus the h1 and
controls div combined height (200px) */
height: calc(100% - 200px);
/* Solution: Set border on the content div */
border: 2px solid #28587b;
/* Solution: Stop the content from overflowing its container;
make it scroll instead */
overflow: auto;
}
img {
/* Solution: Set 90% maximum width on the images */
max-width: 90%;
/* Solution: Center using auto margins */
margin: 0 auto;
display: block;
/* Solution: Set border on the images */
border: 1px solid #28587b;
}
.controls {
justify-content: space-around;
gap: 20px;
padding: 20px;
}
button {
flex: 1;
/* Solution: Set button height to 100% and font size to 1.2em */
height: 100%;
font-size: 1.2em;
/* Solution: Set white text color on the buttons */
color: white;
/* Solution: Set background color on the buttons */
background-color: rgb(40 88 123 / 0.8);
}
/* Solution: Set fully-opaque background color on the
buttons on hover and focus */
button:hover,
button:focus {
background-color: rgb(40 88 123 / 1);
}
/* Solution: Set border radius on content div and buttons */
.content,
button {
border-radius: 10px;
}