CS 318: Lab 20 – Animations
Dear students,
Today we explore transitions to add a little life to our webpages using CSS transitions. As an example, we’ll create a list whose items pop out when hovered.
We start with a list:
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
</ul>
Let’s add some background color to each item:
li {
background-color: blue;
color: white;
}
Let’s remove the bullets, shrink the size a bit, and decrease the padding:
ul {
list-style: none;
width: 200px;
padding-left: 0;
}
Let’s space things out a bit:
li {
/* ... */
margin: 10px auto;
padding: 20px;
}
Now let’s accentuate hovered list items:
li:hover {
background-color: purple;
transform: translate(20px, 0);
}
This is where transitions come in. In their absence, we move from hovered to non-hovered styles instantaneously. We want to smoothly traverse between the two states. We need to specify a few CSS properties to enable that blending:
transition-property: the names of the CSS properties that we want to blendtransition-duration: the time it takes for the transition to finishtransition-timing-function: the “directness” of the blending
Let’s make the list items transition between their left and background-color properties over half a second. We’ll start and end the transition slowly:
li {
/* ... */
transition-property: transform, background-color;
transition-duration: 500ms;
transition-timing-function: ease-in-out;
}
We can also express this in shorthand notation:
li {
/* ... */
transition: transform 500ms ease-in-out, background-color 500ms ease-in-out;
}
Here’s your TODO list:
- Read CSS Transitions and Transforms for Beginners and chapter 11 in your textbook. On a quarter sheet, write down 2-3 questions, observations, or ideas for transitions you’d like to include in your client project.
- A week from today we have our first prototype due. It will be reviewed by your peers in class, and it should be functional and content-complete. Would you like to have a workday next class period to work through issues together?
See you next time!
Lab
Our goal today is to add some life to our web pages by adding in some animations via CSS transitions. We’ll animate a hand of playing cards and a flower garden.
First create a lab20 directory. Add a partners.html and include your first names and last initials.
Cards
Your first challenge is to create a selectable hand of cards interface that behaves as follows:
Follow these steps to produce your interface:
- Set all elements’
box-sizingproperty toborder-box. - Create a container
divto hold the hand of cards. Give it classhand. - Create five child
labels withinhand, each of classcard. - Within each
card, place a checkbox element followed by animgelement. Have the image show a playing card of your choosing. These card images are in the public domain. No classes or IDs are needed for these elements. - Shrink the cards. Set
cardto have a fixed width in pixels of your choosing. We’ll refer to that width as W. Set the images to be as wide as their parent element. But don’t use W—use a percentage. - Overlay the checkbox on the bottom-left corner of the card. Recall that we use absolute positioning to anchor elements relative to their parents. Let
cardserve as an anchorable parent by making it relatively positioned. Then absolutely positioninput[type="checkbox"]against the bottom left of its parent. Add some spacing for aesthetics. - You may or may not see the checkboxes disappear after you absolutely position them. Probably they are behind the images. The front-to-back order of stacked HTML elements is determined by the
z-indexproperty. The larger thez-indexnumber, the closer to the viewer the element is. The particular numbers are not important, only the relative order. Set thez-indexof both the images and the checkboxes so that the checkbox is frontmost. - Overlap the cards. We’ll use absolute positioning to achieve this. Each card will be a bit more inset from its parent than the previous card. Set the positioning of
handto be relative so it can serve as an anchoring parent. Switch the positioning ofcardtoabsolute. Then set theleftproperties of each of the individual cards. The first card should have no offset. Inset the second by half of a card—which is half of W. Inset the third by a full card, and so on. To apply rules to individual cards, don’t add IDs. Use thenth-childselector. - Center
hand. It’s a block element, so centering is done by constraining the width to something less than the full page and setting the left and right margin toauto. How wide shouldhandbe to contain its children? You can calculate this exactly based on W. - Animate the selected cards to slide down from the hand when they are clicked on. (Because an image is part of a checkbox’s
labelelement, we can click anywhere on the card to check it.) This will take a few steps to get right. First, write a transition rule for checked checkboxes that pushes the checkbox down. Use this pseudoselector:input[type="checkbox"]. Set thetransformproperty totranslate(0, OFFSET)—whereOFFSETis some number of pixels of your choosing. Set thetransitionproperty so it animates to this transform. - The previous step only animated the checkbox, but not the image. In a perfect world, we could write a rule that shifted the entire parent
cardthat surrounded a checked checkbox. Unfortunately, CSS does not currently support selecting the parent of some specified child element. However, we can select the immediate sibling with the+operator. To select abthat immediately followsa, we writea + b. Extend the rule you wrote in the previous step to apply both to the checkbox and to theimgthat follows the checked checkbox. Recall that we target a list of selectors by separating them with commas. We want something of this form:a, a + b. After this, both the checkbox and image should slide down. - When you unselect the card, it probably snaps immediately back into its default location. That’s a little too abrupt. Let’s also set the transition out. Write another rule nearly identical to the one you just wrote, but remove the
:checkedpseudoselector and zero out the offset. This rule will need to appear before the:checkedversion; otherwise it will override the checked version. When two rules have the same specificity—as these two do—whichever appears last wins.
Flowers
Create in flowers.html and flowers.css an interactive floral arrangement that uses CSS transforms and transitions to ensnare the viewer in a state of blissful bee-ness:
Observe these requirements:
- Set all elements’
box-sizingproperty toborder-box. - Create a
divwith IDflowerbed. - Download and unzip these flower icons, courtesy of Freepik. The license of these images require attribution, which we will attend to later.
- Add sixteen
imgelements toflowerbedfor each of these images. Not all the files have the same resolution, which will frustrate our perfect 4×4 grid. Use CSS to uniformly set each image to a 129×129 square. Add a 10-pixel margin all around to space them apart a bit. - To get the images to form a grid with no additional HTML markup, have them all float left. To break them up into rows, we need the images in the first column to clear the ones previous. However, don’t create special IDs or a special class for this. Use an
nth-childselector. Recall that one can match a numeric cycle using a form of this selector:...:nth-child(An+B) { /* ... */ }
Arepresents the length of the cycle’s period. For example,3nwould match every third child: 3, 6, 9, 12, and so on.Blets us tack on an offset.3n+2would match children 2, 5, 8, 11, 14, and so on. In our case, we want to match children 1, 5, 9, and 13 and have those clear their predecessor floats. (Child 1 will have nothing to clear.) What period and offset do we want to use here? - When an image is not hovered but another image is, reduce its opacity to 10%. It might be tempting to use the sibling selector (
~) for this. Go ahead and watch it fail:As you should see, the sibling selector only matches images after the hovered image. It’s really a subsequent sibling selector. What we can do instead is use a descendant selector. Select all images that are children of a hoveredimg:hover ~ img { /* ... */ }
flowerbedand reduce their opacity to 10%. - But we want the image that is hovered over to stay at its full opacity. Add a rule for this. If this new rule doesn’t seem to have any effect, it may not have a high enough specificity to beat out the 10% rule.
- Augment your hovered image rule to scale the image 1.5 times its normal size and rotate it 180 degrees. Consult MDN’s documentation on the
transformproperty. - Set the image to transition smoothly between its hover and non-hovered
opacityandtransformproperties. Ease the transition in and out over a span of 2 seconds. Since we’ve got multiple properties that we want to transition, the CSS is cleaner if you set thetransition-properties separately. If you use the shorthand notation, you have to repeat the durations and timing functions. That’s not fun. Instead, set the standalonetransition-durationandtransition-timing-functionproperties to the single value shared by each transition. Settransition-propertyto the list of properties to animate. - In your testing, you should find that sometimes the non-hovered flowers appear on top of the hovered one. If you don’t see this, increase the non-hovered opacity temporarily so that you can see it. This happens because the browser renders subsequent elements on top of previous elements. We can force a different ordering using the
z-indexproperty. Set thez-indexof your images in their hovered and non-hovered states so that hovered images appear on top of non-hovered images. Addz-indexto your list of transition properties. Forz-indexto have any effect, the element must not be statically positioned. Use relative positioning instead. - Center
flowerbedwithin the webpage, both vertically and horizontally. The width-margin technique doesn’t work for vertical centering, so don’t use it here. Instead, use absolute positioning onflowerbed. Anchor its top-left corner to 50% point of its parent. Then translate it up and left -50% to compensate. - The license of the icons requires attribution. Add the message “Icons courtesy of Freepik” and have it link to their website: http://www.freepik.com. Anchor the link to the bottom-right of the page.
Publish and Validate
Commit and push your work. Verify that all pages have been uploaded by visiting https://USERNAME.github.io/cs318/lab20 in your browser.
Validate your pages with the W3C Validator. Paste in the URLs to your pages, one at a time, and address all concerns raised by the validator. Fix your changes on the local machine, commit, and push until the validator reports no errors or warnings.