Bí mật css: giải pháp tốt hơn cho các vấn đề thiết kế web hàng ngày tải xuống pdf

First, this work is intended for a very niche audience. It is for computer programmers who are web designers and who want to learn not just basic CSS [how webpages are currently styled] but advanced CSS. As becomes the O’Reilly book series, Verou is fortunately a master of CSS and of technical communication. Her wit makes learning how to make the most out of CSS entertaining, intriguing, and extensible to new situations

Verou, a member of the W3C CSS Working Group, provides 47 “secrets” that provide example code and results on topics ranging from color tinting and custom checkboxes to the frosted-glass effect and custom animations. More than just a simple “cookbook,” the book is filled with graphics as she helps the reader think through the solution

My personal favorite effect is #42 – Elastic Transitions. Apparently, the rate of timing for an animation is not linear by default. In fact, it can be specified by a Bezier curve. So CSS allows you to define the anchor points for a Bezier curve, and the animation will proceed according to the timing specified therein

While I don’t believe that one can ever say someone can completely “master” any art-form, Verou clearly displays a high degree of mastery of CSS. She provides copious links for further exploration. It’s well worth the time for those who want to make their webpages shine with nuance and grace

In this practical guide, CSS expert Lea Verou provides 47 undocumented techniques and tips to help intermediate-to advanced CSS developers devise elegant solutions to a wide range of everyday web design problems

Rather than focus on design, CSS Secrets shows you how to solve problems with code. You'll learn how to apply Lea's analytical approach to practically every CSS problem you face to attain DRY, maintainable, flexible, lightweight, and standards-compliant results

Inspired by her popular talks at over 60 international web development conferences, Lea Verou provides a wealth of information for topics including

In this practical guide, CSS expert Lea Verou provides 47 undocumented techniques and tips to help intermediate-to advanced CSS developers devise elegant solutions to a wide range of everyday web design problems

Rather than focus on design, CSS Secrets shows you how to solve problems with code. You'll learn how to apply Lea's analytical approach to practically every CSS problem you face to attain DRY, maintainable, flexible, lightweight, and standards-compliant results

Inspired by her popular talks at over 60 international web development conferences, Lea Verou provides a wealth of information for topics including

Simple Way to Read / Download CSS Secrets. Better Solutions to Everyday Web Design Problems by Lea Verou in PDF, EPub, Mobi, Kindle eBook and other supported formats. How to Read / Download CSS Secrets. Better Solutions to Everyday Web Design Problems. - Scroll down to comments - Click the link. - Get your file - Wish you have good luck and enjoy reading your book. Read CSS Secrets. Better Solutions to Everyday Web Design Problems by Lea Verou PDF Read CSS Secrets. Better Solutions to Everyday Web Design Problems by Lea Verou Kindle Read CSS Secrets. Better Solutions to Everyday Web Design Problems by Lea Verou ePub Read CSS Secrets. Better Solutions to Everyday Web Design Problems by Lea Verou Mobi Read CSS Secrets. Better Solutions to Everyday Web Design Problems by Lea Verou Daisy Download CSS Secrets. Better Solutions to Everyday Web Design Problems by Lea Verou PDF Download CSS Secrets. Better Solutions to Everyday Web Design Problems by Lea Verou Kindle Download CSS Secrets. Better Solutions to Everyday Web Design Problems by Lea Verou ePub Download CSS Secrets. Better Solutions to Everyday Web Design Problems by Lea Verou Mobi Download CSS Secrets. Better Solutions to Everyday Web Design Problems by Lea Verou Daisy This is working. [Access] CSS Secrets. Better Solutions to Everyday Web Design Problems by Lea Verou PDF EBOOK EPUB KINDLE

“This is a new generation of CSS books, for a new generation of CSS. Nobody is better at making sense of this new CSS th

Views 2,213 Downloads 1,358 File size 47MB

DOWNLOAD FILE

Recommend Stories

Citation preview

“This is a new generation of CSS books, for a new generation of CSS. Nobody is better at making sense of this new CSS than Lea Verou—among the handful of truly amazing coders I’ve known. ” —Jeffrey Zeldman, author, Designing With Web Standards

F O R EWO R D B Y E R I C A. M E Y E R

“This is a new generation of CSS books, for a new generation of CSS. Nobody is better at making sense of this new CSS than Lea Verou—among the handful of truly amazing coders I’ve known. ” —Jeffrey Zeldman, author, Designing With Web Standards

“Lea Verou’s encyclopaedic mind is one of a kind, but thanks to this generous book, you too can get an insight into what it’s like to wield CSS to do just about anything you can think of. Even if you think you know CSS inside-out, I guarantee that there are still secrets in this book waiting to be revealed. ”

In this practical guide, CSS expert Lea Verou provides 47 undocumented techniques and tips to help intermediate-toadvanced CSS developers devise elegant solutions to a wide range of everyday web design problems. Rather than focus on design, CSS Secrets shows you how to solve problems with code. You’ll learn how to apply Lea’s analytical approach to practically every CSS problem you face to attain DRY, maintainable, flexible, lightweight, and standards-compliant results. Inspired by her popular talks at over 60 international web development conferences, Lea Verou provides a wealth of information for topics including. Lea Verou is an Invited Expert in the W3C CSS Working Group, the committee that designs the CSS language, and previously worked as a Developer Advocate at the W3C, the Web’s main standards organization

Background & Borders n Shapes n Visual Effects n Typography n

Currently, Lea conducts research in HumanComputer Interaction at the Massachusetts

CSS/Web Development

speaks at international conferences, and

US $39. 99

codes popular open source projects to help

ISBN. 978-1-449-37263-7

fellow developers

CAN $45. 99

—Eric A. Meyer “CSS Secrets is an instant classic—so many wonderful tips and tricks you can use right away to enhance your UX designs. ” ­—Christopher Schmitt Author of CSS Cookbook

n

“Lea is an exceedingly clever coder. This book is absolutely packed with clever and useful ideas, even for people who know CSS well. Even better, you’ll feel more clever in your work as this book encourages pushing beyond the obvious. ” —Chris Coyier CodePen

oreilly. com

“Without fail, whenever I read something written by Lea Verou, I manage to learn something new. CSS Secrets is no different. The book is broken down into easy-todigest chunks filled with lots of juicy bits of knowledge. While some of the book is very forward looking, there is plenty that I’ve been able to take away and apply to my own projects right away. ” —Jonathan Snook Web Designer and Developer​ “Lea Verou’s CSS Secrets is useful not so much as a collection of CSS tips, but as a textbook on how to solve problems with CSS. Her in-depth explanation of the thought process behind each secret will teach you how to create your own solutions to CSS problems. And don’t miss the Introduction, which contains some mustread CSS Best Practices. ” —Elika J. Etemad aka fantasai W3C CSS Working Group Invited Expert

VEROU

Institute of Technology [MIT]. She also blogs,

User Experience n Structure & Layout n Transitions & Animations

“If you want the inside scoop on fascinating CSS techniques, smart best practices, and some flat-out brilliance, don’t hesitate—read this book. I loved it. ”

“There aren’t many books which provide as many practical techniques as Lea Verou’s CSS Secrets. Filled with dozens of solutions to common design problems, the book is a truly valuable collection of smart tips and tricks for getting things done well, and fast. Worth reading, even if you think that you know the ins and outs of CSS. ”  —Vitaly Friedman Co-founder and Editor-in-chief Smashing Magazine

BETTER SOLUTIONS TO EVERYDAY WEB DESIGN PROBLEMS

 —Jeremy Keith Shepherd of Unknown Futures, Clearleft

MORE PRAISE FOR CSS SECRETS

F O R EWO R D BY E R I C A. M E Y E R

Praise for CSS Secrets

This is a new generation of CSS books, for a new generation of CSS. No longer a simple language

tied to complicated browser hacks and workarounds, CSS is now a richly powerful and deeply complex ecosystem of over 80 W3C specifications. Nobody is better at making sense of this new CSS, and of

providing design principles that help you solve problems with it, than Lea Verou—among the handful of truly amazing coders I’ve known. ” — Jeffrey Zeldman author, Designing with Web Standards

Lea Verou’s encyclopaedic mind is one of a kind, but thanks to this generous book, you too can get

an insight into what it’s like to wield CSS to do just about anything you can think of. Even if you think

you know CSS inside-out, I guarantee that there are still secrets in this book waiting to be revealed. ” — Jeremy Keith Shepherd of Unknown Futures, Clearleft

If you want the inside scoop on fascinating CSS techniques, smart best practices, and some flat-out

brilliance, don’t hesitate—read this book. I loved it. ” — Eric A. Meyer

Lea is an exceedingly clever coder. This book is absolutely packed with clever and useful ideas, even

for people who know CSS well. Even better, you’ll feel more clever in your work as this book encour-

ages pushing beyond the obvious. ” — Chris Coyier CodePen

CSS Secrets is an instant classic—so many wonderful tips and tricks you can use right away to enhance

your UX designs. ” — Christopher Schmitt author of CSS Cookbook

There aren’t many books that provide as many practical techniques as Lea Verou’s CSS Secrets. Filled

with dozens of solutions to common design problems, the book is a truly valuable collection of smart

tips and tricks for getting things done well, and fast. Worth reading, even if you think that you know the ins and outs of CSS. ” — Vitaly Friedman cofounder and editor-in-chief of Smashing Magazine

Without fail, whenever I read something written by Lea Verou, I manage to learn something new. CSS Secrets is no different. The book is broken down into easy-to-digest chunks filled with lots of juicy bits of knowledge. While some of the book is very forward looking, there is plenty that I’ve been able to take away and apply to my own projects right away. ” — Jonathan Snook web designer and developer

Lea’s book is fantastic. She bends and contorts CSS to do things I’m pretty sure even the spec authors never imagined. You will learn multiple ways of accomplishing each graphic effect by trying out the techniques she walks through in each chapter. Later, in your work, you’ll find yourself saying, “hmm, that thing Lea did will work perfectly here. ” Before you know it, your site is almost image free because your graphics are all in easy to maintain CSS components. What’s more, her techniques are fun, walking the line between practical and improbable. ” — Nicole Sullivan Principal Software Engineer, creator of OOCSS

Lea Verou’s CSS Secrets is useful not so much as a collection of CSS tips, but as a textbook on how

to solve problems with CSS. Her in-depth explanation of the thought process behind each secret will teach you how to create your own solutions to CSS problems. And don’t miss the Introduction, which contains some must-read CSS best practices. ” — Elika J. Etemad [aka fantasai] W3C CSS Working Group Invited Expert

Lea’s presentations have long been must-see events at web development conferences around the world. A distillation of her years of experience, CSS Secrets provides elegant solutions for thorny web design issues, while also—and more importantly—showing how to solve problems in CSS. It’s an absolute must-read for every frontend designer and developer. ” — Dudley Storey designer, developer, writer, web education specialist

I thought I had a pretty advanced understanding of CSS, then I read Lea Verou’s book. If you want to take your CSS knowledge to the next level, this is a must-own. ” — Ryan Seddon Team Lead, Zendesk

CSS Secrets is by far the most technical book that I have ever read on the topic. Lea has managed to push the boundaries of a language as simple as CSS so far that you will not be able to distinguish this from magic. Definitely not a beginner’s read; it’s heavily recommended to anyone thinking they know CSS all too well. ” — Hugo Giraudel frontend developer, Edenspiekermann

I often think that CSS can seem a bit like magic. a few rules can transform your web pages from blah to beautiful. In CSS Secrets, Lea takes the magic to a whole new level. She is a master magician of CSS, and we get to explore that magical world along with her. I can’t count how many times I said out loud while reading this book, “That’s so cool. ” The only trouble with CSS Secrets is that after reading it, I want to stop everything else I’m doing and play with CSS all day. ” — Elisabeth Robson cofounder of WickedlySmart. com and coauthor of Head First JavaScript Programming

CSS Secrets is a book that all web developers should have in their library. Using the information it contains you’ll learn numerous hints and tips to make CSS perform tasks you never thought possible. I was astonished at how often the author came up with simple and elegant lateral thinking solutions to problems that had bugged me for years. ” — Robin Nixon web developer, online instructor, and author of several books on CSS

As a master designer and programmer, Lea Verou’s book is as beautiful and as well thought out as her code. Whether you’re fairly new to CSS, or well versed in the intricacies of CSS3, this book has something for everyone. ” — Estelle Weyl Open Web Evangelist and coauthor of CSS. The Definitive Guide

CSS Secrets by Lea Verou Copyright © 2015 Lea Verou. All rights reserved. Printed in Canada. Published by O’Reilly Media, Inc. , 1005 Gravenstein Highway North, Sebastopol, CA 95472. O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are also available for most titles [http. //safaribooksonline. com]. For more information, contact our corporate/institutional sales department. 800-998-9938 or [email protected] Editors. Mary Treseler and Meg Foley

Proofreader. Charles Roumeliotis

Production Editor. Kara Ebrahim

Interior Designer. Lea Verou

Copyeditor. Jasmine Kwityn

Cover Designer. Monica Kamsvaag

Indexer. WordCo Indexing Services

Illustrator. Lea Verou

See http. //www. oreilly. com/catalog/errata. csp?isbn=0636920031123 for release details. The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. The cover image and related trade dress are trademarks of O’Reilly Media, Inc. While the publisher and the author have used good faith efforts to ensure that the information and instructions contained in this work are accurate, the publisher and the author disclaim all responsibility for errors or omissions, including without limitation responsibility for damages resulting from the use of or reliance on this work. Use of the information and instructions contained in this work is at your own risk. If any code samples or other technology this work contains or describes is subject to open source licenses or the intellectual property rights of others, it is your responsibility to ensure that your use thereof complies with such licenses and/or rights

Print History. First Edition, June 2015 Revision History for the First Edition. 2015-06-03

First Release

2015-07-17

Second Release

ISBN. 978-1-4493-7263-7 [TI]

In loving memory of my mother & best friend, Maria Verou [–], who left this world way too early

Table of Contents Foreword Preface Words of thanks

xv xvii xix

Making of

xxii

About this book

xxiv

6 Complex background patterns

50

7 [Pseudo]random backgrounds

62

8 Continuous image borders

68

CHAPTER 3 Shapes

75

9 Flexible ellipses

76

CHAPTER 1 Introduction

1

10 Parallelograms

84

Web standards. friend or foe?

2

11 Diamond images

90

CSS coding tips

9

12 Cutout corners

96

13 Trapezoid tabs

108

14 Simple pie charts

114

CHAPTER 2 Backgrounds & Borders

23

1 Translucent borders

24

2 Multiple borders

28

3 Flexible background positioning

32

15 One-sided shadows

130

4 Inner rounding

36

16 Irregular drop shadows

134

5 Striped backgrounds

40

17 Color tinting

138

CHAPTER 4 Visual Effects

TABLE OF CONTENTS

129

ix

18 Frosted glass effect

146

38 Styling by sibling count

270

19 Folded corner effect

156

39 Fluid background, fixed content

276

40 Vertical centering

280

41 Sticky footers

288

CHAPTER 5 Typography

167

CHAPTER 8 Transitions & Animations

20 Hyphenation

168

21 Inserting line breaks

172

22 Zebra-striped text lines

178

42 Elastic transitions

294

23 Adjusting tab width

182

43 Frame-by-frame animations

308

24 Ligatures

184

44 Blinking

314

25 Fancy ampersands

188

45 Typing animation

320

26 Custom underlines

194

46 Smooth state animations

328

27 Realistic text effects

200

47 Animation along a circular path

334

28 Circular text

210

CHAPTER 6 User Experience

217

29 Picking the right cursor

218

30 Extending the clickable area

224

31 Custom checkboxes

228

32 De-emphasize by dimming

234

33 De-emphasize by blurring

240

34 Scrolling hints

244

35 Interactive image comparison

250

CHAPTER 7 Structure & Layout

261

36 Intrinsic sizing

262

37 Taming table column widths

266

x

TABLE OF CONTENTS

Index

293

347

Secrets by Specification CSS Animations w3. org/TR/css-animations 42 Elastic transitions

294

43 Frame-by-frame animations

308

44 Blinking

314

45 Typing animation

320

46 Smooth state animations

328

47 Animation along a circular path

334

CSS Backgrounds & Borders w3. org/TR/css-backgrounds 1 Translucent borders

24

2 Multiple borders

28

3 Flexible background positioning

32

4 Inner rounding

36

5 Striped backgrounds

40

6 Complex background patterns

50

7 [Pseudo]random backgrounds

62

8 Continuous image borders

68

9 Flexible ellipses

76

12 Cutout corners

96

14 Simple pie charts

114

15 One-sided shadows

130

19 Folded corner effect

156

22 Zebra-striped text lines

178

26 Custom underlines

194

30 Extending the clickable area

224

32 De-emphasize by dimming

234

34 Scrolling hints

244

35 Interactive image comparison

250

CSS Backgrounds & Borders Level 4 dev. w3. org/csswg/css-backgrounds-4 12 Cutout corners

SECRETS BY SPECIFICATION

96

xi

CSS Basic User Interface w3. org/TR/css3-ui 2 Multiple borders

28

4 Inner rounding

36

35 Interactive image comparison

250

CSS Box Alignment w3. org/TR/css-align 40 Vertical centering

280

CSS Flexible Box Layout

250

CSS Image Values Level 4 w3. org/TR/css4-images 5 Striped backgrounds

40

6 Complex background patterns

50 114

CSS Intrinsic & Extrinsic Sizing 36 Intrinsic sizing

280

41 Sticky footers

288

CSS Fonts w3. org/TR/css-fonts 24 Ligatures

184

25 Fancy ampersands

188

CSS Image Values w3. org/TR/css-images 5 Striped backgrounds

40

6 Complex background patterns

50

7 [Pseudo]random backgrounds

62

8 Continuous image borders

68 96

14 Simple pie charts

114

19 Folded corner effect

156

22 Zebra-striped text lines

178

26 Custom underlines

194

SECRETS BY SPECIFICATION

35 Interactive image comparison

w3. org/TR/css3-sizing

40 Vertical centering

xii

244

14 Simple pie charts

w3. org/TR/css-flexbox

12 Cutout corners

34 Scrolling hints

262

CSS Masking w3. org/TR/css-masking 11 Diamond images

90

12 Cutout corners

96

CSS Text w3. org/TR/css-text 20 Hyphenation

168

23 Adjusting tab width

182

CSS Text Level 4 dev. w3. org/csswg/css-text-4 20 Hyphenation

168

CSS Text Decoration w3. org/TR/css-text-decor 26 Custom underlines

194

27 Realistic text effects

200

CSS Transforms

Compositing and Blending

w3. org/TR/css-transforms

w3. org/TR/compositing

10 Parallelograms

84

17 Color tinting

138

11 Diamond images

90

35 Interactive image comparison

250

12 Cutout corners

96

13 Trapezoid tabs

108

w3. org/TR/filter-effects

14 Simple pie charts

114

16 Irregular drop shadows

134

19 Folded corner effect

156

17 Color tinting

138

35 Interactive image comparison

250

18 Frosted glass effect

146

40 Vertical centering

280

33 De-emphasize by blurring

240

47 Animation along a circular path

334

35 Interactive image comparison

250

Filter Effects

CSS Transitions

Fullscreen API

w3. org/TR/css-transitions

fullscreen. spec. whatwg. org

11 Diamond images

90

12 Cutout corners

96

17 Color tinting

138

33 De-emphasize by blurring

240

42 Elastic transitions

294

CSS Values & Units w3. org/TR/css-values 3 Flexible background positioning

32 De-emphasize by dimming

234

Scalable Vector Graphics w3. org/TR/SVG 6 Complex background patterns

50

14 Simple pie charts

114

28 Circular text

210

Selectors 32

w3. org/TR/selectors

32 De-emphasize by dimming

234

31 Custom checkboxes

228

40 Vertical centering

280

38 Styling by sibling count

270

41 Sticky footers

288

45 Typing animation

320

SECRETS BY SPECIFICATION

xiii

Foreword Ah, the good old days. Back in the previous millennium, we had just two CSS-capable browsers, and what they did was a fairly limited subset of a fairly limited specification, so you could fairly easily keep a complete map of what worked and what didn’t in your head. That map included the bugs in each implementation, as they had many errors and oversights, some of them verging on the comical. Heck, some bugs were so fundamental that they made the browsers’ layout behavior completely incompatible, forcing us to come up with a whole army of parser-bug-exploiting hacks just to work around the differences. Wait a minute. The old days were horrible. Glad we’re done with all that. Things really have gotten so much better in the last several years, CSSwise. Browsers have, for the most part, converged on compatibility, and where they are incompatible, it’s nearly always because one browser doesn’t support a feature that another does, as opposed to both of them trying to support the same thing differently, and usually badly. The specifications have pushed capabilities forward even as they’ve added features that recreate the convoluted tricks of old in much simpler, more compact ways. CSS has far more features and far more power than ever before—but, as we all know, with great power comes great complexity. It’s not even a case of intentional complexity. when you combine enough working parts, no

FOREWORD

xv

matter how simple each may be, interesting things can and do emerge. [For more on this topic, see The LEGO Movie. ] But it’s exactly that unintended complexity that gives CSS the ability to surprise us with emergent features we never expected, or even planned. There are secrets to be found in the intersections of properties and the bending of values. You can carve corners with gradients, animate elements, increase clickable areas, even create pie charts…and so much more. CSS has capabilities that we only dreamed of back when I was but a lad, possibilities beyond anything we imagined. It’s added abilities that I once thought could never be expressed in a compact, human-readable manner—animations, to pick one example. It’s advanced far enough that I’m confident there are many, many secrets yet to be discovered. Perhaps you’ll discover some of them. Until that day arrives, there are plenty of fascinating techniques that have already been unearthed, and few have done more than Lea Verou to find and share them with the world. From her blog posts to her open source contributions to her dynamic, interactive talks all over the world, Lea has amassed a formidable reserve of CSS knowledge. This book is a beautiful distillation of that knowledge. You now possess a guide to some of the most interesting, surprising, and useful techniques that CSS has yielded, a guide compiled by one of the brightest minds in the field. What Lea has prepared for you in these pages will enrich, delight, and—yes—even astonish. Go forth, learn well, and let these discoveries be secrets no more. — Eric A. Meyer

xvi

FOREWORD

Preface In the past few years, CSS has undergone a transformation, similar to the JavaScript revolution circa 2004. It went from being a dead-simple styling language with limited power, to a complex technology defined by over 80 W3C specifications [including drafts], with its own developer ecosystem, its own conferences, and its own frameworks and tooling. CSS has grown so much that it’s practically impossible for any single person to hold all of it in their brain. Even in the W3C CSS Working Group that defines the language, nobody is an expert on every single aspect of CSS— and few even come close. Instead, most WG members focus on certain CSS specifications and might know very little about others. Up until roughly 2009, CSS expertise was not defined by how well the language was known. This was more or less a given for any serious CSS work. Instead, CSS prowess was defined by the number of browser bugs and workarounds that had been committed to memory. Fast-forward to 2015, and browsers are now designed to support standards, and flimsy browser-specific hacks are frowned upon. There are still some unavoidable incompatibilities, but—especially because most browsers now auto-update —the pace of change is so fast, that attempting to document them in a book would be a waste of time and space. The challenge in modern CSS has little to do with working around transient browser bugs. The challenge now is using the CSS features we have in a creative way, in order to come up with DRY, maintainable,

PREFACE

xvii

DRY is an acronym that stands for “Don’t Repeat Yourself. ” It’s a popular programming mantra to promote an aspect of maintainable code. being able to change its parameters with as few edits as possible, ideally one. Emphasis on DRY

flexible, lightweight, and as much as possible, standards-compliant solutions. This is exactly what this book is all about. There are many books out there that document certain CSS features from A to Z. CSS Secrets, for better or for worse, is not one of them. Its purpose is to fill the knowledge gaps that are left after you’ve already fam-

CSS code is a recurring theme in this

iliarized yourself with the reference material—to open your mind to new

book. The opposite of DRY is WET,

ways to take advantage of the features you already know about, or to let

which stands for “We Enjoy Typing” or “Write Everything Twice. ”

you know about useful CSS features that aren’t as shiny and popular, and that deserve more love. However, above all, the main purpose of this book is to teach you how to solve problems with CSS. CSS Secrets is not a cookbook either. Each “secret” is not a canned recipe, with rigid steps you must follow to achieve a specific effect. Instead, I’ve tried to describe the thinking behind every technique in detail, as I believe that understanding the process of finding a solution is far more valuable than the solution itself. Even if you don’t think that a certain technique is relevant to your work, learning how to reach a solution might still prove valuable for tackling even completely different problems. Long story short, you will hopefully get many proverbial fish from this book, but its main goal is to “feed you for a lifetime,” by teaching you how to catch them

xviii

PREFACE

Words of thanks This book would not have been possible without the help and support of a number of fantastic people, to whom I’m deeply grateful. A big, heartfelt thank you goes to. ■ All those who supported my work over the years, otherwise I wouldn’t have found myself in the position of writing a book in the first place. To readers of my blog [lea. verou. me], Twitter [twitter. com/leaverou], and elsewhere, and even more to you, dear reader of my first book. To everyone who has used my open source work [github. com/leaverou] and even more to those who contributed. ■ All the conference organizers who have invited me for talks and workshops over the years, especially to Damian Wielgosik and Paweł Czerski who first believed in me and invited me to the inaugural Front-Trends conference in 2010. And to Vasilis Vassalos who trusted me to design a web development course for Athens University of Economics and Business back in 2010, as all these experiences taught me a great deal about teaching [and a technical book is basically teaching]. ■ Everyone in the CSS Working Group who voted to bring me on as an Invited Expert, which has transformed my perspective on web technologies in general and on CSS in particular

WORDS OF THANKS

xix

■ My editors, Mary Treseler and Meg Foley, who gave me control over the entire process and have been incredibly patient with me when I missed deadlines [which happened more often than I’d care to admit]. ■ My production editor, Kara Ebrahim, who spent copious amounts of time fixing layout issues and manually compensating for CSS rendering bugs and limitations in the PDF renderer used for this book. ■ My technical editors. Elika Etemad, Tab Atkins, Ryan Seddon, Elisabeth Robson, Ben Henick, Robin Nixon, and Hugo Giraudel. They not only helped me correct factual mistakes, but also provided invaluable feedback regarding the understandability of the prose. ■ Eric Meyer, who I still cannot believe agreed to write a Foreword for my book. ■ My research advisor, David Karger, who was extremely understanding when I arrived at MIT without having finished this book, which was supposed to be done long before then. Without his continued patience, the fate of this book would have been bleak. ■ My dad, Miltiades Komvoutis, who taught me art and aesthetics very early on. Without him, I would probably have zero interest in design and CSS, and this book would have been about something else, like C++ or kernel programming. ■ My uncle/second dad, Stratis Veros, and his lovely wife, Maria Brere, who put up with me when I was at my most cranky while writing this book. Also to their kids, Leonie and Phoebe, who are the cutest little girls in the world and without whom, this book would have finished around a month earlier. ■ My incredible late mother, Maria Verou, to whom this book is dedicated. For the 27 years our lives overlapped, she was my best friend and biggest supporter. Her own life was a huge inspiration. she moved to the other side of the world to do postgraduate research at MIT in the 1970s, a time when most women in Greece barely made it to college, and got her degree with distinction. She taught me ambition, kindness, integrity, independence, open-mindedness. But most importantly, she taught me to not take life too seriously. I miss her sorely

xx

PREFACE

Photo credits A big thanks to the lovely people who publish their photos with permissive Creative Commons licenses; otherwise, every example in this book would feature pictures of my cat [and many examples do, regardless]. Here is a list of the CC photos I used and where you can find them. “House Made Sausage from Prairie Grass Cafe, Northbrook,” Kurman Communications, Inc. flickr. com/kurmanphotos/7847424816 “Cats that Webchick Is Herding,” Kathleen Murtagh flickr. com/ceardach/4549876293

“Stone Art,” by Josef Stuefer flickr. com/josefstuefer/5982121

“A Field of Tulips,” Roman Boed flickr. com/romanboed/867231576

“Resting in the Sunshine,” Steve Wilson flickr. com/pokerbrit/10780890983

“Naxos Island, Greece,” Chris Hutchison flickr. com/employtheskinnyboy/3904743709

WORDS OF THANKS

xxi

Making of This is a book that eats its own dog food, proverbially speaking. It was written in clean HTML5, with a few data- attributes, defined by O’Reilly’s HTMLBook standard [oreillymedia. github. io/HTMLBook]. This means that everything you see in this book—the layout, the figures, the colors—is HTML styled with CSS. A lot of the figures are also generated with SVG or use SVG data URIs, generated via SCSS functions. The few math formulas were written in LaTeX and then converted to MathML behind the scenes. You may find it amusing that the page numbers, chapter numbers, and secret numbers are merely CSS counters. Many of the books O’Reilly publishes these days are made that way. They have built a system especially for this purpose, called Atlas [atlas. oreilly. com]. The best thing about Atlas is that it’s also available for the public, not just for official O’Reilly use. However, this book was not a typical Atlas use case. It pushed the limits of what is possible today with CSS for printing, in a way that—to my knowledge—no other book has. It helped us find many bugs in Atlas and Antenna House [the PDF renderer used by Atlas] and even many issues with the printrelated CSS specifications themselves, which I took to the CSS WG. “How much code does it take to make a book like this with web technologies?” you might ask. Let’s look at a few statistics [before production]. ■ This book is styled with 4,700 lines of SCSS, compiling to 3,800 lines of CSS. ■ A little over 10,000 lines of HTML. xxii

PREFACE

■ There are 322 figures in the entire book, but only 140 image files [including SVG images and screenshots], as most figures are just a series of divs styled with CSS. [Figure styling accounts for 65% of the book’s CSS and SCSS code. ] Here is a list of tools used in making this book, besides Atlas. ■ Git for version control ■ SCSS for CSS preprocessing ■ The entire book was written in the Espresso [macrabbit. com/espresso] text editor ■ CodeKit was used for compiling SCSS to CSS ■ Dabblet [dabblet. com] was used for the live demos and for the few figures that are screenshots of the demos ■ The SVG-based figures that were not hand coded were created in Adobe Illustrator ■ Adobe Photoshop was used to edit screenshots, when needed The fonts used were Rockwell for the headings, Frutiger for the body text, Consolas for the code, and Baskerville for the dedication and many figures. The book was written on a 13″ MacBook Air, in a variety of countries, including Greece, Kenya, Australia, New Zealand, the Philippines, Singapore, Chile, Brazil, the United States, France, Spain, the UK, Wales, Poland, Canada, and Austria

MAKING OF

xxiii

About this book Who this book is for The primary target audience for this book is intermediate to advanced CSS developers. By getting the introductory stuff out of the way, we can explore more advanced use cases of modern CSS features and combinations thereof. This, however, means that quite a few assumptions have been made about you, dear reader. ■ I assume you know CSS 2. 1 inside out, and have a few years of experience with it. You don’t struggle to understand how positioning works. You’ve used generated content to enhance your designs without extraneous markup or images. You don’t resort to plastering . important all over your code because you actually understand specificity, inheritance, and the cascade. You know what the different parts of the box model are, and you are not fazed by margin collapsing. You are familiar with the different length units and know when it’s best to use each one. ■ You’ve read quite a bit about the most popular CSS3 features, online and/or in books, and have tried them out, even if only in personal projects. Even if you haven’t studied them in depth, you know how to create rounded corners, add a box-shadow, or create a linear gradient. You’ve played with some basic 2D transforms, and have enhanced interactions with basic transitions and animations

xxiv

PREFACE

■ You have seen SVG and know what it’s used for, even if you don’t quite know how to write it yourself. ■ You can read and understand basic, vanilla JavaScript, such as creating elements, manipulating their attributes, and adding them to the document. ■ You’ve heard of CSS preprocessors and know what they can do, even if you choose not to use one. ■ You’re familiar with middle school level math, such as square roots, the Pythagorean theorem, sines, cosines, and logarithms. However, to enable readers that don’t meet all these assumptions to enjoy this book, there is a “Prerequisites” box in the beginning of some secrets, briefly listing any CSS knowledge or previous secrets that need to be known for the secret to make sense [excluding CSS 2. 1 features, otherwise the box would get really long]. It looks like this

Prerequisites box-shadow, basic CSS gradients, the “Flexible ellipses” secret on page 76 This way, even if certain things are not already known, one can read up about them and come back to the secret afterward. As long as their prerequisites are met, the secrets can actually be read in any order, though there is value in reading them in the book order, as a lot of thought has been put into what the optimal order is. Note that I mentioned “CSS developers” and that “design skills” are not in the list of assumptions above. It’s important to note that this is not a design book. While it unavoidably touches on certain design principles and describes a few UX improvements, CSS Secrets is first and foremost a book about solving problems with code. CSS might have a visual output, but it is still code, just like SVG, WebGL/OpenGL, or the JavaScript Canvas API is code, not design. Writing good, flexible CSS requires the same kind of analytical thinking that programming does. Nowadays, most people use preprocessors for their CSS, with variables, math, conditionals, and loops, so it’s almost starting to look like programming

ABOUT THIS BOOK

xxv

This is not to imply that designers are discouraged from reading this book. Anybody who has sufficient coding experience with CSS can benefit from it, and there are many talented designers who can also write excellent CSS code. However, it’s important to note that teaching you how to improve the visual design or usability of a website is not among the goals of this book, even if it happens as a side effect

Format & conventions used The book consists of 47 “secrets,” grouped by topic in seven chapters. These secrets are more or less independent and—as long as their prerequisites are met—can be read in any order. The demos in every secret are not complete websites, or even parts thereof. They are purposefully as small and simple as possible, in order to facilitate understanding. The assumption is that you already know what you want to implement. The purpose of this book is not to give design ideas, but implementation solutions

FIGURE P. 1 This is an example sidebar figure,

Every secret is split into two or more sections. The first section, titled “The problem,” introduces a common CSS challenge that we are going to

introducing the great Sir Adam

solve. Sometimes this introduction might describe widely popular solutions

Catlace

that are suboptimal [e. g. , solutions that require a lot of markup, hardcoded values, etc. ], and usually concludes with variations of the question “Is there a better way to achieve this?”

Notes, such as this one, provide additional information or explain a term mentioned in the text

!

This is a warning. Its purpose is

After introducing the problem, one or more solutions follow. This book was inspired by the CSS talks I have presented at various conferences so I tried to maintain the interactive presentation format as much as a book allows. Therefore, every solution is illustrated by a number of figures, dem-

to warn you [surprising, I

onstrating the visual output for every step of the solution that results in a

know. ] about possible false assump-

visual change. Because figures are not always directly next to the text that

tions and certain things that could

describes what they demonstrate, they are numbered and referenced in the

go wrong

text. You can see an example of a figure in Figure P. 1 and the current sentence was an example of a reference to it. Inline code is denoted by monospace text and colors often have a small preview next to them as well [e. g. , like this

xxvi

PREFACE

#f06]. Block-level code looks

background. url["adamcatlace. jpg"];

or this

HTML

Sir Adam Catlace

As you might have noticed, when the language of a code block is not CSS, it’s noted in the top-right corner. Also, when the example discussed only involves a single element, and no pseudo-classes or pseudo-elements are involved, there is usually no selector or braces [{}] included in the code blocks, for brevity. All JavaScript examples in the book are vanilla JavaScript, with no frameworks or libraries required. There is only one helper function used,

$$[], in order to make it easier to loop over a set of elements that match a certain CSS selector. The function’s definition is

function $$[selector, context] {

JS

context = context . document; var elements = context. querySelectorAll[selector]; return Array. prototype. slice. call[elements]; }

TRIVIA

Side trivia

Dark “Trivia” sections at the bottom of pages introduce tangentially related trivia, such as the historical or technical background behind a CSS feature. They are not necessary for using or understanding the main material, but readers might find them interesting nevertheless. ABOUT THIS BOOK xxvii

Every secret includes one or more live examples that can be accessed with short, memorable URLs in play. csssecrets. io. The references to them look like this. ▶ PLAY. play. csssecrets. io/polka It is strongly recommended that you check out the “Play. ” examples, especially if you are confused by the techniques described or if you get stuck while following along. Credit where it’s due. When a technique described was first documented by someone else in the community, credit will be given in a “Hat Tip” paragraph like this one, referencing the URL of the source as well. We all know HAT TIP

that having to find the “References” section at the end of a book is a hassle, so these essentially provide references in context

FUTURE

Future solutions

“Future” sections [positioned at the bottom of pages and set on a dark background] introduce techniques that are already in draft specifications, but at the time of writing have no implementations. Readers should always check if these techniques are supported, as they might have been implemented after the publication of this book. In cases where the feature is obscure enough that browser support websites might not include it, the section will include a test that the reader can load, in short memorable URLs, such as the one shown here in the “Test. ” example. These tests are usually designed so that shades of green appear when the feature is supported and shades of red otherwise. The exact instructions are mentioned in the code, as a comment. TEST. play. csssecrets. io/test-conic-gradient

xxviii PREFACE

At the end of almost every secret you’ll find a list of related specifications that looks like this

■ CSS Backgrounds & Borders w3. org/TR/css-backgrounds

RELATED

SPECS

■ Selectors w3. org/TR/selectors ■ Scalable Vector Graphics w3. org/TR/SVG

This includes references to all the specifications from which features were mentioned. However, just like the “Prerequisites” box, this does not apply to CSS 2. 1 [w3. org/TR/CSS21], otherwise it would be listed in the “Related Specs” section of every single secret. This means that the few secrets that only discuss CSS 2. 1 features have no “Related Specs” section at all

Browser support & fallbacks Possibly the biggest peculiarity of this book is the complete lack of browser compatibility tables. This was a conscious decision, as with today’s browser release cycles, such information is bound to get out of date before this book even hits the shelves. I believe that inaccurate browser support

LIMITED SUPPORT

information is misleading, and is actually worse than no information. However, most secrets described either currently have decent browser support and/or degrade gracefully. In cases where a technique described presently has particularly poor browser support, there is a “Limited Support” warning icon next to the relevant solution, like the one next to this paragraph. This should be enough to hint that you should not use the solution without looking up browser support for it and taking extra care for providing good fallbacks. There are plenty of excellent websites containing up-to-date browser support information. Here are some suggestions

ABOUT THIS BOOK

xxix

■ Can I Use…? [caniuse. com] ■ WebPlatform. org ■ Mozilla Developer Network [developer. mozilla. org] ■ Wikipedia’s “Comparison of Layout Engines [Cascading Style Sheets]” [en. wikipedia. org/wiki/ Comparison_of_layout_engines_[Cascading_Style_Sheets]] Sometimes you might find that a certain feature is supported, but slightly differently across browsers. For example, it might need a vendor prefix, or slightly different syntax. Only the standards-compliant, unprefixed syntax will be included in the examples. However, you can almost always use different syntaxes alongside and let the cascade take care of which one wins. For this reason, always place the standard version last. For example, to get a vertical linear gradient from

yellow to

red, the book would

only list the standard version

background. linear-gradient[90deg, yellow, red];

However, if you want to support very old browsers, you might end up having to write something like the following. You can read more on vendor prefixes, why they exist, and how to ab-

background. -moz-linear-gradient[0deg, yellow, red];

stract them away from your code in

background. -o-linear-gradient[0deg, yellow, red];

the “A story of ice, fire, and vendor prefixes” section on page 6

background. -webkit-linear-gradient[0deg, yellow, red]; background. linear-gradient[90deg, yellow, red];

Because the landscape of these differences is just as fluid as browser support, it is expected that things like this are part of your standard research before using a CSS feature and are not discussed further in the solutions presented. Similarly, most of the time it’s good practice to provide fallbacks, so that your website doesn’t break in older browsers, even if it doesn’t look as fancy in them. These are not discussed extensively when they are obvious, as the assumption is that you know how the cascade works. For example,

xxx

PREFACE

when specifying a gradient, such as the one just shown, you should also add a solid color version before all of them. A good idea for the solid color might be the average of the two gradient colors [in this case,

rgb[255, 128, 0]]. background. rgb[255, 128, 0]; background. -moz-linear-gradient[0deg, yellow, red]; background. -o-linear-gradient[0deg, yellow, red]; background. -webkit-linear-gradient[0deg, yellow, red]; background. linear-gradient[90deg, yellow, red];

However, sometimes it’s not possible to provide decent fallbacks through the cascade. As a last resort, you could use tools like Modernizr [modernizr. com], which adds classes like textshadow or no-

textshadow to the root element [], so you can use them to target elements only when certain features are [not] supported, like so

h1 { color. gray; } . textshadow h1 { color. transparent; text-shadow. 0 0 . 3em gray; }

If the feature you are trying to create a fallback for is sufficiently new, you could use the @supports rule, which is the “native” Modernizr. For example, the preceding code would become

h1 { color. gray; } @supports [text-shadow. 0 0 . 3em gray] { h1 { color. transparent;

ABOUT THIS BOOK

xxxi

text-shadow. 0 0 . 3em gray; } }

However, for now, be wary of using @supports. By using it here we just limited our effect not only to browsers that support text shadows, but also to browsers that support the @supports rule—a much more limited set. Last, but not least, there is always the option of using a few lines of home-baked JavaScript to perform feature detection and add classes to the root element in the same fashion as Modernizr. The main way to determine whether a property is supported is to check its existence on the

element. style object of any element. var root = document. documentElement; //

JS

if ['textShadow' in root. style] { root. classList. add['textshadow']; } else { root. classList. add['no-textshadow']; }

If we need to test for multiple properties, we can easily turn this into a function

function testProperty[property] { var root = document. documentElement; if [property in root. style] { root. classList. add[property. toLowerCase[]]; return true; }

xxxii PREFACE

JS

root. classList. add['no-' + property. toLowerCase[]]; return false; }

If we want to test a value, we need to assign it to the property and check if the browser retains it. Because we are modifying styles here and not just testing for their existence, it makes sense to use a dummy element

var dummy = document. createElement['p'];

JS

dummy. style. backgroundImage = 'linear-gradient[red,tan]'; if [dummy. style. backgroundImage] { root. classList. add['lineargradients']; } else { root. classList. add['no-lineargradients']; }

This can easily be converted to a function as well

function testValue[id, value, property] {

JS

var dummy = document. createElement['p']; dummy. style[property] = value; if [dummy. style[property]] { root. classList. add[id]; return true; } root. classList. add['no-' + id]; return false; }

ABOUT THIS BOOK xxxiii

Testing selectors and @rules is a bit more complex, but follows the same principle. when it comes to CSS, browsers drop anything they don’t understand, so we can check if a feature is recognized by dynamically applying it and checking if it was retained. Of course, keep in mind that a browser being able to parse a CSS feature offers no guarantee that the feature is correctly implemented, or even that it’s implemented at all

xxxiv PREFACE

Introduction

1

Web standards. friend or foe? The standards process Contrary to popular belief, the W3C [World Wide Web Consortium] does not “make” standards. Instead, it acts as a forum for interested parties to get together and do so, in its W3C Working Groups. Of course, the W3C is not a mere observer. it sets the ground rules and it oversees the process. But it’s not [primarily] W3C staff that actually write the specifications. CSS specifications, in particular, are written by the members of the CSS

FIGURE 1. 1 “Standards are like sausages. it’s better not to see them being made” — Anonymous W3C WG member

Working Group, often abbreviated as CSS WG. At the time of writing, the CSS WG includes 98 members, and its composition is as follows. ■ 86 members from W3C member companies [88%] ■ 7 Invited Experts, including yours truly [7%] ■ 5 W3C staff members [5%] As you might notice, the vast majority of WG members [88%] come from W3C member companies. These are companies—such as browser vendors, popular websites, research institutes, general technology companies, etc. — that have a vested interest in seeing web standards flourish. Their yearly membership dues represent the majority of the W3C’s funding, enabling

2

CHAPTER 1. INTRODUCTION

the Consortium to distribute its specifications freely and openly, unlike other standards bodies that have to charge for them. Invited Experts are web developers who have been asked to participate in the standards process, after demonstrating a continuous commitment to helping out, and a sufficient technical background to participate in the discussions. Last, but not least, W3C staff members are people who actually work at the Consortium and facilitate communication between the WG and

FIGURE 1. 2

the W3C. A widespread misconception among web developers is that the W3C creates standards from up high that the poor browsers then have to follow, whether they like them or not. However, this couldn’t be further from the

The composition of the CSS WG. Member companies Invited Experts W3C staff members

truth. browser vendors have much more of a say than the W3C in what goes into standards, as evidenced by the numbers listed before. Also contrary to popular belief, standards are not created in a vacuum, behind closed doors. The CSS WG is committed to transparency and all its communications are open to the public, inviting review and participation. ■ Most discussions happen in its mailing list, www-style [lists. w3. org/ Archives/Public/www-style]. www-style is publicly archived, and is open to participation from anyone. ■ There is a weekly telcon, with a duration of one hour. This is not open to participation by non-WG members, but is minuted in real time in the #css channel on the W3C’s IRC server [irc. w3. org/]. These minutes are then cleaned up and posted to the mailing list a few days later. ■ There are also quarterly face-to-face meetings, which are also minuted in the same fashion as telcons. They are also often open to observation [auditing], after requesting permission from the WG chairs. All this is part of the W3C process and has to do with decision making. However, the ones that are actually responsible for putting these decisions to writing [i. e. , authoring the specifications] are the Spec Editors. Spec Editors might be W3C staff members, browser developers, interested Invited Experts, or member company employees who are doing it as a full-time job, paid by their companies to advance standards for the common good

WEB STANDARDS. FRIEND OR FOE?

3

Each specification goes through multiple stages as it evolves from initial inception to maturity. Interested in learning more? Elika Etemad [fantasai] has written a

1. Editor’s Draft [ED]. The first stage of a spec could be as messy as being

series of amazing articles on

just a collection of ideas by the spec editor. There are no requirements for

how the CSS WG operates

this stage and no guarantee that it’s approved by the WG. However, this is

[fantasai. inkedblade. net/ weblog/2011/inside-csswg]

also the first stage of every revision. all changes are first made in an ED, then

Very highly recommended

published. 2. First Public Working Draft [FPWD]. The first published version of a spec, after it’s deemed ready for public feedback by the WG. 3. Working Draft [WD]. There are many WDs after the first one, each slightly better, incorporating feedback from the WG and the broader community. First implementations often start at this stage, but it’s not unheard of to have experimental implementations of earlier stage specs. 4. Candidate Recommendation [CR]. This is considered a relatively stable version. Now it’s time for implementations and tests. A spec cannot advance past this stage without a full test suite and at least two independent implementations. 5. Proposed Recommendation [PR]. Last chance for W3C member companies to express disagreement with the specification. This rarely happens, so it’s usually just a matter of time for every PR spec to move to the next, final stage. 6. Recommendation [REC]. The final stage of a W3C specification. One or two WG members have the role of being chairs. Chairs are responsible for organizing meetings, coordinating calls, timekeeping, and generally moderating the whole thing. Being chair is a very time-consuming and energy-draining role, and is frequently compared to herding cats. Of course, everyone involved in standards knows that such a comparison is

FIGURE 1. 3

moot. herding cats is actually considerably easier

Chairing a W3C Working Group is frequently compared to herding cats

4

CHAPTER 1. INTRODUCTION

CSS3, CSS4, and other mythical creatures CSS 1 was a very short and relatively simple specification, published in 1996 by Håkon Wium Lie and Bert Bos. It was so small that it was all included in a single HTML page, which required around 68 sheets of A4 paper to print. CSS 2, published in 1998, was more strictly defined, and included much more power and two more spec editors. Chris Lilley and Ian Jacobs. At this point, the length of the specification had grown to 480 [. ] printed pages and was already getting too big to be held in human memory in its entirety. After CSS Level 2, the CSS WG realized that the language was getting too big to be contained in a single specification. Not only was it extremely unwieldy to read and edit, but it was also holding CSS back. Remember that for a specification to advance to the final stages, every single feature in it needs at least two independent implementations and exhaustive tests. This was no longer practical. Therefore, it was decided that going forward, CSS was going to be broken into multiple specifications [modules], each with its own versioning. Those that expand on features that were already present in CSS 2. 1 would have a level number of 3. For example, some of these modules are. ■ CSS Syntax [w3. org/TR/css-syntax-3] ■ CSS Cascading and Inheritance [w3. org/TR/css-cascade-3] ■ CSS Color [w3. org/TR/css3-color] ■ Selectors [w3. org/TR/selectors] ■ CSS Backgrounds & Borders [w3. org/TR/css3-background] ■ CSS Values and Units [w3. org/TR/css-values-3] ■ CSS Text [w3. org/TR/css-text-3] ■ CSS Text Decoration [w3. org/TR/css-text-decor-3] ■ CSS Fonts [w3. org/TR/css3-fonts] ■ CSS Basic User Interface [w3. org/TR/css3-ui] However, modules that introduce entirely new concepts start from Level 1. Here are a few examples

WEB STANDARDS. FRIEND OR FOE?

5

■ CSS Transforms [w3. org/TR/css-transforms-1] ■ Compositing and Blending [w3. org/TR/compositing-1] ■ Filter Effects [w3. org/TR/filter-effects-1] ■ CSS Masking [w3. org/TR/css-masking-1] ■ CSS Flexible Box Layout [w3. org/TR/css-flexbox-1] ■ CSS Grid Layout [w3. org/TR/css-grid-1] Despite the popularity of the “CSS3” buzzword, there is actually no specification defining such a thing, like there was for CSS 2. 1 or its predecessors. Instead, what most authors are referring to is an arbitrary set of Level 3 specs, plus some Level 1 specs. Although there is some good degree of consensus among authors on which specs are included in “CSS3,” as CSS modules evolve at different rates over the years, it will become more and more difficult to refer to things like CSS3, CSS4, and so on and be universally understood

A story of ice, fire, and vendor prefixes In standards development, there is always a big catch-22. standards groups need input from developers to create specifications that address real development needs. However, developers are generally not interested in trying out things they can’t use in production. When experimental technologies get widely used in production, the WG is forced to stick with the early, experimental version of the technology, to avoid breaking several existing websites if they change it. Obviously, this completely negates the benefits of getting developers to try out early standards. Over the years, many solutions have been proposed to address this conundrum, none of them perfect. The universally despised vendor prefixes were one of them. The idea was that every browser would be able to implement experimental [or even proprietary] features with their own prefix prepended to its name. The most common prefixes are -moz- for Firefox,

-ms- for IE, -o- for Opera, and -webkit- for Safari and Chrome. Developers would be able to freely experiment with these prefixed features and provide feedback to the WG, which would then incorporate this feedback into the specs and slowly perfect the design of the feature. Because 6

CHAPTER 1. INTRODUCTION

the final, standardized version would have a different name [no prefix], it wouldn’t collide with the existing uses of its prefixed counterparts. Sounds great, right? Of course, as you probably know, the reality was quite different from the vision. When developers realized that these experimental, vendor-prefixed properties could make it so much easier to create effects that previously required messy workarounds, they started using them everywhere. Vendor-prefixed properties quickly became the CSS trend of the time. Tutorials were written, StackOverflow replies were given, and soon almost every self-respecting CSS developer was using them all over the place. Eventually, authors realized that using only existing vendor prefixes meant they would have to go back to previous work and add new declarations every time another browser implemented their favorite cool new CSS feature. Not to mention how hard it became to keep up with which prefixes were needed for what feature. The solution? Add all possible vendor prefixes preemptively, including the unprefixed version at the end, to futureproof it. We ended up with code like the following

-moz-border-radius. 10px; -ms-border-radius. 10px; -o-border-radius. 10px; -webkit-border-radius. 10px; border-radius. 10px;

Two of the declarations here are completely redundant. -ms-border-

radius and -o-border-radius never existed in any browser, as IE and Opera implemented border-radius unprefixed from the get-go. Obviously, repeating every declaration up to five times was tedious and unmaintainable. It was only a matter of time until tools were built to automate this. ■ Websites like CSS3, Please. [css3please. com] or pleeease [pleeease. io/playground. html] allow you to paste your unprefixed CSS code and get back CSS with all necessary prefixes added. Such apps were among the first ideas devised to automate vendor prefix addition, but

WEB STANDARDS. FRIEND OR FOE?

7

are not very popular anymore, as using them incurs quite a lot of overhead compared to other solutions. ■ Autoprefixer [github. com/ai/autoprefixer] uses the database from Can I Use… [caniuse. com] to determine which prefixes to add to unprefixed code and compiles it locally, like a preprocessor. ■ My own -prefix-free [leaverou. github. io/prefixfree] performs feature testing in the browser to determine which prefixes are needed. The benefit is that it rarely needs updating, as it gets everything from the browser environment, including the list of properties. ■ Preprocessors like LESS [lesscss. org] or Sass [sass-lang. com] don’t offer any means of prefixing out of the box, but many authors create mixins for the features they prefix most often, and there are several libraries of such mixins in circulation. Because authors were using the unprefixed version of features as a means to future-proof their code, it became impossible to change them. We were basically stuck with half-baked early specs that we could change in very limited ways. It didn’t take long for everyone involved to realize that vendor prefixes were an epic failure. These days, vendor prefixes are rarely used for new experimental implementations. Instead, experimental features require config flags to be turned on, effectively preventing developers from using them in production, as you can’t really tell users to change their settings in order to view your website properly. Of course, this has the consequence that fewer authors get to play with experimental features, but we still get enough feedback, and arguably, better quality feedback, without the drawbacks of vendor prefixes. However, it will be a long time before the ripple effects of vendor prefixes stop haunting us all

8

CHAPTER 1. INTRODUCTION

CSS coding tips Minimize code duplication Keeping code DRY and maintainable is one of the biggest challenges in software development, and that applies to CSS as well. In practice, one big component of maintainable code is minimizing the amount of edits necessary to make a change. For example, if to enlarge a button you need to make 10 edits in many different rules, chances are you will miss a few of them, especially if you are not the one who wrote the original code. Even if the edits are obvious, or you eventually find them, you have just wasted time that could be put to better use. Furthermore, this is not just about future changes. Flexible CSS makes

Yes

it easier to write CSS once, and then create variations with very little code, as there are only a few values you need to override. Let’s look at an example. Take a look at the following CSS, which styles the button shown in Figure 1. 4

FIGURE 1. 4 The button we are going to use in our example

padding. 6px 16px; border. 1px solid #446d88; background. #58a linear-gradient[#77a0bb, #58a]; border-radius. 4px; box-shadow. 0 1px 5px gray; color. white;

CSS CODING TIPS

9

text-shadow. 0 -1px 1px #335166; font-size. 20px; line-height. 30px;

There are several issues with the maintainability of this code that we can fix. The low-hanging fruit is the font metrics. If we decide to change the font size [perhaps to create a variation that will be used for important, bigger buttons], we also need to adjust the line spacing, as they are both absolute values. Furthermore, the line spacing doesn’t reflect what its relationship is to the font size, so we would even need to perform calculations to figure out what it should be for a different font size. When values depend on each other, try to reflect their relationship in the code. In this case, the line spacing is 150% the line height. Therefore, it would be much more maintainable to show this in the code

font-size. 20px; line-height. 1. 5;

While we’re at it, why did we specify the font size as an absolute length? Sure, absolute lengths are easy to work with, but they come back

Yes. FIGURE 1. 5

to bite you every single time you make changes. Now, if we decide to make the parent font size bigger, we would have to change every single rule in the stylesheet that uses absolute font measurements. It’s much better to use percentages or ems

Enlarging the font size breaks other effects in our button [corner

font-size. 125%; /* Assuming a 16px parent font size */

rounding being the most

line-height. 1. 5;

noticeable], as they are specified using absolute lengths

Now if I change the parent font size, the button will instantly become bigger. However, it will look quite different [Figure 1. 5], because all other effects were designed for a smaller button and did not scale. We can make all the other effects scalable as well, by specifying any lengths in ems, so that

10

CHAPTER 1. INTRODUCTION

they all depend on the font size. This way, we can control the size of the button in one place. Here we wanted our font size and measurements to be relative to the

padding. . 3em . 8em;

parent font size, so we used ems. In

border. 1px solid #446d88;

some cases, you want them to be

background. #58a linear-gradient[#77a0bb, #58a];

relative to the root font size [i. e. ,

border-radius. . 2em;

the font size of ], and ems result in complex calculations. In that

box-shadow. 0 . 05em . 25em gray;

case, you can use the rem unit. Rel-

color. white;

ativity is an important feature in CSS,

text-shadow. 0 -. 05em . 05em #335166;

but you do have to think about what things should be relative to

font-size. 125%; line-height. 1. 5;

Now our larger button looks much more like a scaled version of the original [Figure 1. 6]. Notice that we still left some lengths as absolute values. It’s a judgment call which effects should scale with the button and which ones should stay the same. In this case, we wanted our border thickness to stay 1px regardless of the button dimensions. However, making the button smaller or larger is not the only thing we

Yes

might want to change. Colors are another big one. For example, what if we want to create a red Cancel button, or a green OK button? Currently, we

FIGURE 1. 6

would need to override four declarations [border-color, background,

Now we can make our button larger,

box-shadow, text-shadow], not to mention the hassle of recalculating all the different darker/lighter variants of our main color, #58a, and fig-

and all its effects scale too

uring out how much lighter or darker each color is. Also, what if we want to place our button on a non-white background? Using

gray for its

shadow will only look as intended on a white background. We could easily eliminate this hassle by using semi-transparent white and black for lighter/darker variants, respectively, overlaid on our main color

TIP

padding. . 3em . 8em;

Use HSLA instead of RGBA for semi-

transparent white, as it has slightly

border. 1px solid rgba[0,0,0,. 1]; background. #58a linear-gradient[hsla[0,0%,100%,. 2],

fewer characters and is quicker to type, due to the lack of repetition

transparent];

CSS CODING TIPS

11

border-radius. . 2em; box-shadow. 0 . 05em . 25em rgba[0,0,0,. 5]; color. white; text-shadow. 0 -. 05em . 05em rgba[0,0,0,. 5]; font-size. 125%; line-height. 1. 5;

Now all it takes to create variations with different colors is to override

background-color [Figure 1. 7]

OK

Cancel

button. cancel { background-color. #c00;

FIGURE 1. 7

}

All it took to create these color variations was changing the background color

button. ok { background-color. #6b0; }

Our button is already much more flexible. However, this example doesn’t demonstrate every opportunity to make your code more DRY. You will find a few more tips in the following sections

Maintainability versus brevity Sometimes, maintainability and brevity can be mutually exclusive. Even in the previous example, our final code is a bit longer than our original. Consider the following snippet to create a 10px thick border on every side of an element, except the left one

border-width. 10px 10px 10px 0;

It’s only one declaration, but to change the border thickness we would need to make three edits. It would be much easier to edit as two declarations, and it’s arguably easier to read that way too. 12

CHAPTER 1. INTRODUCTION

border-width. 10px; border-left-width. 0;

currentColor In CSS Color Level 3 [w3. org/TR/css3-color], we got many new color keywords like

lightgoldenrodyellow, which aren’t that useful

However, we also got a special new color keyword, borrowed from SVG

currentColor. This does not correspond to a static color value. Instead, it always resolves to the value of the color property, effectively making it

Some would argue that the em unit was actually the first variable in CSS, as it referred to the value of fontsize. Most percentages play a similar role, though in less exciting ways

the first ever variable in CSS. A very limited variable, but a variable nevertheless. For example, let’s assume we want all of the horizontal separators [all

elements] to automatically have the same color as the text. With currentColor, we could do this. hr { height. . 5em; background. currentColor; }

You might have noticed similar behavior with many existing properties. For example, if you specify a border with no color, it automatically gets the text color. This is because currentColor is also the initial value of many CSS color properties. border-color, the text-shadow and box-shadow colors, outline-color, and others. In the future, when we get functions to manipulate colors in native CSS, currentColor will become even more useful, as we will be able to use variations of it

Inheritance While most authors are aware of the inherit keyword, it is often forgotten. The inherit keyword can be used in any CSS property and it always

CSS CODING TIPS

13

corresponds to the computed value of the parent element [in pseudoelements that is the element they are generated on]. For example, to give form elements the same font as the rest of the page, you don’t need to respecify it, just use inherit

input, select, button { font. inherit; }

Similarly, to give hyperlinks the same color as the rest of the text, use

inherit. a { color. inherit; }

The inherit keyword can often be useful for backgrounds as well. For example, to create speech bubbles where the pointer automatically inherits the background and border [Figure 1. 8]

callout { position. relative; } . callout. before { content. "";

FIGURE 1. 8

position. absolute;

A speech bubble where the pointer

top. -. 4em; left. 1em;

gets the background color and

padding. . 35em;

border from the parent

background. inherit; border. inherit; border-right. 0; border-bottom. 0; transform. rotate[45deg]; }

14

CHAPTER 1. INTRODUCTION

Trust your eyes, not numbers The human eye is far from being a perfect input device. Sometimes accurate measurements result in looking inaccurate and designs need to account for that. For example, it’s well known in visual design literature that our eyes don’t perceive something as being vertically centered when it is. Instead, it needs to be slightly above the geometrical middle to be perceived as such. See that phenomenon for yourself, in Figure 1. 9. Similarly, in type design, it is well known that round glyphs such as “O” need to be slightly larger than more rectangular glyphs, as we tend to perceive round shapes as smaller than they actually are. Check that out for yourself in Figure 1. 10. Such optical illusions are very common in any form of visual design, and need to be accounted for. An extremely common example is padding in containers with text. The issue is present regardless of the amount

FIGURE 1. 9 In the first rectangle, the brown square is mathematically vertically centered, but doesn’t look so; in the second one, it is actually placed slightly above the geometrical

of text—it could be a word or several paragraphs. If we specify the same

center, but it looks more centered to

amount of padding on all four sides of a box, it actually ends up looking

the human eye

uneven, as Figure 1. 11 demonstrates. The reason is that letterforms are much more straight on the sides than their top and bottom, so our eyes perceive that extra space as extra padding. Therefore, we need to specify less padding for the top and bottom sides if we want it to be perceived as being the same. You can see the difference this makes in Figure 1. 12

FIGURE 1. 10 The circle looks smaller, but its bounding box is exactly the same as

On Responsive Web Design

the square

RWD [Responsive Web Design] has been all the rage over the past few years. However, the emphasis is often placed on how important it is for websites to be “responsive,” leaving a lot unsaid about what good RWD entails. The common practice is testing a website in multiple resolutions and adding more and more media queries to fix the issues that arise. However, every media query adds overhead to future CSS changes, and they should not be added lightly. Every future edit to the CSS code requires

CSS CODING TIPS

15

checking whether any media queries apply, and potentially editing those

yolo

too. This is often forgotten, resulting in breakage. The more media queries you add, the more fragile your CSS code becomes. That is not to say that media queries are a bad practice. Used right,

FIGURE 1. 11

they can be indispensable. However, they should be a last resort, after

Specifying the same padding [. 5em

every other attempt to make a website design flexible has failed, or when

here] on all four sides of a container

we want to completely change an aspect of the design in smaller/larger

with text makes it look larger on the top and bottom sides

viewports [e. g. , making the sidebar horizontal]. The reason is that media queries do not fix issues in a continuous manner. They are all about specific thresholds [a. k. a. “breakpoints”], and unless the rest of the code is written

yolo

to be flexible, media queries will only fix specific resolutions, essentially sweeping issues under the rug. Of course, it goes without saying that media query thresholds

FIGURE 1. 12

should not be dictated by specific devices, but by the design itself. Not

Specifying larger padding

only because there are so many different devices [especially if we take future

[here. . 3em . 7em] on the left and right side makes it look much more

devices into account] that a website should look good at any possible res-

uniform

olution, but also because a website on the desktop might be viewed in a window of any size. If you are confident that your design works well in every

TIP

Consider using ems in

possible viewport size, who cares about what resolution specific devices

your media queries in-

have?

stead of pixels. This allows text zoom to trigger layout changes as necessary

Following the principles described in the “Minimize code duplication” section on page 9 will also help with this, as you won’t have to override as many declarations in your media queries, essentially minimizing the overhead they cause. Here are a few more tips to avoid needless media queries. ■ Use percentages instead of fixed widths. When that’s not possible, use viewport-relative units [vw, vh, vmin, vmax], which resolve to a fraction of the viewport width or height. ■ When you want a fixed width for larger resolutions, use max-width, not

width, so it can still adapt to smaller ones without media queries. ■ Don’t forget to set a max-width of 100% for replaced elements such as

img, object, video, and iframe. ■ In cases when a background image needs to cover an entire container,

background-size. cover can help maintain that regardless of said container’s size. However, bear in mind that bandwidth is not unlimited, and 16

CHAPTER 1. INTRODUCTION

it’s not always wise to include large images that are going to be scaled down via CSS in mobile designs. ■ When laying out images [or other elements] in a grid of rows and columns, let the number of columns be dictated by the viewport width. Flexible Box Layout [a. k. a. Flexbox] or display. inline-block and regular text wrapping can help with that. ■ When using multi-column text, specify column-width instead of

column-count, so that you get one column only in small resolutions. In general, the idea is to strive for liquid layouts and relative sizing between media query breakpoints. When a design is sufficiently flexible, making it responsive shouldn’t take more than a few short media queries. The designers of Basecamp wrote about this very matter in late 2010. “As it turned out, making the layout work on a variety of devices was just a matter of adding a few CSS media queries to the finished product. The key to making it easy was that the layout was already liquid, so optimizing it for small screens meant collapsing a few margins to maximize space and tweaking the sidebar layout in the cases where the screen is too narrow to show two columns. ” — Experimenting with responsive design in Iterations [signalvnoise. com/posts/2661experimenting-with-responsive-design-in-iterations]

If you find yourself needing a boatload of media queries to make your design adapt to smaller [or larger] screens, take a step back and reexamine your code structure, because in all likelihood, responsiveness is not the only issue there

Use shorthands wisely As you probably know, the following two lines of CSS are not equivalent

background. rebeccapurple;

background-color. rebeccapurple;

CSS CODING TIPS

17

rebeccapurple background, whereas the element with the longhand [backgroundcolor] could end up with a pink gradient, a picture of a cat, or anything really, as there might also be a background-image declaration in effect. The former is a shorthand and will always give you a

This is the problem when you mainly use longhands. you are not resetting all the other properties that could be affecting what you’re trying to accomplish. You could of course try to set all the longhands and call it a day, but then you might forget some. Or the CSS WG might introduce more longhands in the future, and your code will have failed to reset those. Don’t be afraid of shorthands. It is good defensive coding and future-proofing to use them, unless we intentionally want to use cascaded properties for everything else, like we did for the colored button variants in the “Minimize code duplication” section on page 9. Longhands are also very useful in combination with shorthands, to make code DRY-er in properties whose values are a comma-separated list, such as the background properties. This is best explained with an example

background. url[tr. png] no-repeat top right / 2em 2em, url[br. png] no-repeat bottom right / 2em 2em, url[bl. png] no-repeat bottom left / 2em 2em;

Notice how the background-size and background-repeat values are repeated three times, despite being the same for every image. We can take advantage of CSS list expansion rules which say that if only one value is provided, it is expanded to apply to every item in the list, and move these repeated values to longhands

background. url[tr. png] top right, url[br. png] bottom right, url[bl. png] bottom left; background-size. 2em 2em; background-repeat. no-repeat;

18

CHAPTER 1. INTRODUCTION

Now we can change the background-size and background-repeat with only one edit instead of three. You will see this technique used throughout the book

Should I use a preprocessor? You’ve probably heard of CSS preprocessors such as LESS [lesscss. org], Sass [sass-lang. com], or Stylus [learnboost. github. io/stylus]. They offer several conveniences for authoring CSS, such as variables, mixins, functions, rule nesting, color manipulation, and more. Used properly, they can help keep code more flexible in a large project, when CSS itself proves too limited to let us do so. As much as we strive to code robust, flexible, DRY CSS, sometimes we just stumble on the limitations of the language. However, preprocessors also come with a few issues of their own. ■ You lose track of your CSS’ filesize and complexity. Concise, small code might compile to a CSS behemoth that is sent down the wires

TRIVIA

Weird shorthand syntax

You might have noticed in the shorthand and longhand example that specifying background-size in the

background shorthand requires also providing a background-position [even if it’s the same as the initial one] and using a slash [/] to separate them. Why do some shorthands have such weird rules? This is almost always done for disambiguation purposes. Sure, in the example here, it’s obvious that

top right is a background-position and 2em 2em a background-size regardless of their ordering. However, think of values like 50% 50%. Is it a background-size or a background-position? When you are using the longhands, the CSS parser knows what you mean. However, in the shorthand, the parser needs to figure out what that 50% 50% refers to without any help from the property name. This is why the slash is needed. For most shorthands, there is no such disambiguation issue and their values can be specified in any order. However, it’s always good practice to look up the exact syntax, to avoid nasty surprises. If you are familiar with regexes and grammars, you could also check the grammar for the property in the relevant specification, which is probably the quickest way to see if there is a specific ordering. CSS CODING TIPS

19

■ Debugging becomes harder, as the CSS you see in the developer tools is not the CSS you wrote. This is becoming less of an issue, as SourceMaps get more debugger support. SourceMaps are a cool new technology that aims to mitigate this issue by telling the browser what preprocessor CSS corresponds to what generated CSS, down to the line number. ■ They introduce some degree of latency in our development process. Even though they are generally fast, it still takes a second or so to compile your code to CSS, which you have to wait for before previewing its result. ■ With every abstraction, comes more effort required by someone to start working on our codebase. We either have to only collaborate with people fluent in the preprocessor dialect of our choice, or teach it to them. So we are either restricted in our choice of collaborators or need to spend extra time for training, both of which are suboptimal. ■ Let’s not forget the Law of Leaky Abstractions. “All non-trivial abstractions, to some degree, are leaky. ” Preprocessors are written by humans, and like every non-trivial program humans have ever written, they have their own bugs, which can be very insidious as we rarely suspect that a preprocessor bug might be the culprit behind our CSS issues. In addition to the issues listed here, preprocessors also pose the risk of making authors dependent on them, perpetuating their use even when unnecessary, such as in smaller projects or in the future, after their most popular features have been added to native CSS. Surprised? Yes, many preprocessor-inspired features have been making their way into pure CSS. ■ There is already a draft about variable-like custom properties, under the title of CSS Custom Properties for Cascading Variables [w3. org/TR/cssvariables-1]. ■ The function calc[] from CSS Values & Units Level 3 not only is very powerful for performing calculations, but also very well supported, even today. ■ The color[] function in CSS Color Level 4 [dev. w3. org/csswg/csscolor] will provide means to manipulate colors. ■ There are several serious discussions in the CSS WG about nesting, and even a draft spec [ED] existed about it in the past

20

CHAPTER 1. INTRODUCTION

Note that native features like these are generally much more powerful than the ones provided by preprocessors, as they are dynamic. For example, a preprocessor has no clue how to perform a calculation like 100%

- 50px, because the value percentages resolve to is not known until the page is actually rendered. However, native CSS calc[] has no trouble

Don’t forget that native CSS features like these can be manipulated through scripting too. For example, you could use JS to change the value of a variable

evaluating such expressions. Similarly, variable use like the following is not possible with preprocessor variables

ul { --accent-color. purple; } ol { --accent-color. rebeccapurple; } li { background. var[--accent-color]; }

Can you see what we did there? The background of list items in ordered

rebeccapurple, whereas the background of list items in unordered lists will be purple. Try doing that with a preprocessor. Of lists will be

course, in this case, we could have just used descendant selectors, but the point of the example was to show how dynamic these variables will be

FIGURE 1. 13 Myth [myth. io] is an experimental preprocessor that emulates these native CSS features, instead of introducing proprietary syntax, essentially acting like a CSS polyfill

CSS CODING TIPS

21

Because most of the aforementioned native CSS features are not well supported today, in many cases using preprocessors is unavoidable if maintainability matters [and it should]. My advice would be to start off every project with pure CSS, and when it starts being impossible to keep it DRY, switch to using a preprocessor then. To avoid becoming completely dependent on preprocessors or using them when they are not actually needed, their use needs to be a conscious decision, not a mindless first step performed by default in every new project. In case you were wondering [and haven’t read the first chapter, tsktsk], the style of this book was authored in SCSS, although it started as pure CSS and only switched when the code grew too complex to be maintainable. Who said CSS and its preprocessors are only for the Web?

22

CHAPTER 1. INTRODUCTION

Backgrounds & Borders

2

1

Translucent borders Prerequisites RGBA/HSLA colors

The problem By now, you’ve probably dabbled quite a bit with semi-transparent colors in CSS, such as rgba[] and hsla[]. They were a huge revolution back in 2009, when we were finally able to use them in our designs, despite the required fallbacks, shims, and even ugly IE filter hacks for the daring. However, their uses in the wild were mostly centered around backgrounds. There were a few reasons for this. ■ Some early adopters hadn’t quite realized that these new color formats were actually colors just like

#ff0066 or

orange, and treated them like

images, using them only in backgrounds. ■ It was much easier to provide fallbacks for backgrounds than for other properties. For example, the fallback for a semi-transparent background

24

CHAPTER 2. BACKGROUNDS & BORDERS

could be a single pixel semi-transparent image. For other properties, the only possible fallback was a solid color. ■ Using them in other properties, such as borders, wasn’t always as straightforward. We’ll see why next

FIGURE 2. 1 24ways. org was one of the first websites to really utilize semitransparent colors in its design, as early as 2008, although they were also mostly backgrounds [design by Tim Van Damme]

Suppose we want to style a container with a white background and a semi-transparent white border, through which our body background shows. Our first attempt would probably look like this

Can I haz semitransparent borders? Pretty please?

border. 10px solid hsla[0,0%,100%,. 5];

FIGURE 2. 2

background. white;

Our initial attempt to achieve semitransparent borders

Unless you have a good understanding of how backgrounds and borders work, the result [shown in Figure 2. 2] can be quite baffling. Where did our border go? And if we cannot achieve semi-transparent borders by using a semi-transparent color for the border, then how can we do it?

SECRET #1. TRANSLUCENT BORDERS

25

The solution Although it might not look like it, our border is still there. By default, backgrounds extend underneath the border area, which you can easily check by applying a good ol’ dashed border to an element with a background [Figure 2. 3]. This doesn’t make much of a difference when you’re using solid opaque borders, but in this case, it completely changes our design. Instead of having a semi-transparent white border through which our nice

FIGURE 2. 3

body background shows, we ended up having semi-transparent white bor-

By default, backgrounds extend

ders on opaque white, which are indistinguishable from plain white borders

underneath the border area

In CSS 2. 1, this was just how backgrounds worked. We just had to accept it and move on. Thankfully, since Backgrounds & Borders Level 3 [w3. org/TR/css3-background], we are able to adjust this behavior when it’s not convenient, through the background-clip property. Its initial value is border-box, which means that backgrounds are clipped at the outer edge of the element’s border box. If we want our background to not extend underneath the border, all we have to do is to give it the value

padding-box, which tells the browser to clip the background at the padding edge

Can I haz semitransparent borders? Pretty please?

FIGURE 2. 4

border. 10px solid hsla[0,0%,100%,. 5]; background. white; background-clip. padding-box;

The much nicer result can be seen in Figure 2. 4

Fixing the issue with background-

clip

▶ PLAY. play. csssecrets. io/translucent-borders

■ CSS Backgrounds & Borders w3. org/TR/css-backgrounds

26

CHAPTER 2. BACKGROUNDS & BORDERS

RELATED

SPECS

2

Multiple borders Prerequisites Basic box-shadow use

The problem Back in the day, when Backgrounds & Borders Level 3 [w3. org/TR/ css3-background] was still a draft, there was a lot of discussion in the CSS WG about whether multiple borders should be allowed, just like multiple background images. Unfortunately, the consensus at the time was that there weren’t enough use cases, and authors could always use border-

image to achieve the same effect. However, what the Working Group missed is that we usually want the flexibility of being able to adjust borders in CSS code, so developers ended up resorting to ugly hacks such as using multiple elements to emulate multiple borders. However, there are better ways to solve this without polluting our markup with useless extra elements

28

CHAPTER 2. BACKGROUNDS & BORDERS

box-shadow solution By now, most of us have probably [over]used box-shadow to create shadows. However, it is little known that it accepts a fourth parameter [called “spread radius”], which makes the shadow larger [positive lengths] or smaller [negative lengths] by the amount you specify. A positive spread radius combined with zero offsets and zero blur creates a “shadow” that looks more like a solid border [Figure 2. 5]

background. yellowgreen; box-shadow. 0 0 0 10px #655;

This is not particularly impressive, as you can create the same kind of border by using the border property. However, the good thing about box-

FIGURE 2. 5

shadow is that we can have as many of them as we want, comma deeppink “border” separated. So, we can pretty easily add a second

Emulating an outline with box-

shadow

to the previous example

background. yellowgreen; box-shadow. 0 0 0 10px #655, 0 0 0 15px deeppink;

The only thing to keep in mind is that box-shadows are overlaid one on top of the other, with the first one being the topmost. Therefore, you need to adjust the spread radius accordingly. For example, in the preceding code, we wanted a 5px outer border, so we specified a spread radius of 15px

FIGURE 2. 6 Emulating two outlines with box-

shadow

[10px + 5px]. You can even specify a regular shadow after all the “outlines,” if you want

background. yellowgreen; box-shadow. 0 0 0 10px #655, 0 0 0 15px deeppink, 0 2px 5px 15px rgba[0,0,0,. 6];

SECRET #2. MULTIPLE BORDERS

29

The shadow solution works quite well in most cases, but has a few caveats. ■ Shadows don’t work exactly like borders, as they don’t affect layout and are oblivious to the box-sizing property. However, you can emulate the extra space a border would occupy via padding or margins [depending on whether the shadow is inset or not]

FIGURE 2. 7 Including an actual shadow after the “outlines”

■ The method we demonstrated creates fake “borders” on the outside of elements. These do not capture mouse events such as hovering or clicking. If this is important, you can add the inset keyword to make the shadows be drawn on the inside of your element. Note that you will need to add extra padding to produce sufficient spacing. ▶ PLAY. play. csssecrets. io/multiple-borders

outline solution In some cases, if we only need two borders, we can use a regular border and the outline property for the outer one. This also gives us flexibility regarding the border style [what if we want a dashed second border?], whereas with the box-shadow method, we can only emulate solid borders. Here is how the code for Figure 2. 6 would look with this method

background. yellowgreen; border. 10px solid #655; outline. 15px solid deeppink;

FIGURE 2. 8

Another good thing about outlines is that you can control their distance

Using negative outline-offset

from the boundaries of the element, via outline-offset, which even

with a dashed outline, for a basic stitching effect

accepts negative values. This can be useful for a number of effects. For example, check out Figure 2. 8 for a basic stitching effect. However, this method has a few limitations. ■ As mentioned, it only works for two “borders,” as outline does not accept a comma-separated list of outlines. If we need more, the previous technique is our only option

30

CHAPTER 2. BACKGROUNDS & BORDERS

■ Outlines do not have to follow rounding [through border-radius], so even if your corners are round, the outline may have straight corners [Figure 2. 9]. Note this behavior is considered a bug by the CSS WG, and is likely to be changed to match the border-radius in the future. ■ Per the CSS User Interface Level 3 specification [w3. org/TR/css3-ui], “Outlines may be non-rectangular. ” Although in most cases they tend to be

FIGURE 2. 9

rectangular, if you use this method, make a mental note to test the result

Outlines created through the

thoroughly in different browsers

outline property do not follow the element’s rounding, although that could change in the future

■ CSS Backgrounds & Borders w3. org/TR/css-backgrounds

RELATED

SPECS

■ CSS Basic User Interface w3. org/TR/css3-ui

SECRET #2. MULTIPLE BORDERS

31

3

Flexible background positioning The problem

Code Pirate

Fairly often, we want to position a background image with offsets from a different corner than the top-left one, such as the bottom right. In CSS 2. 1, we could only specify offsets from the top-left corner or keywords for the other three corners. However, we often want to leave some space [akin to padding] between the background image and the corner it’s on, to avoid

FIGURE 2. 10 background-position. bottom right; doesn’t usually

things that look like Figure 2. 10. For containers with fixed dimensions, this is possible with CSS 2. 1, but

yield very aesthetically pleasing

it’s messy. we can calculate what offset your background image would have

results, as the image has no spacing

from the top-left corner based on its dimensions and the offset we want

from the sides

from the bottom-right corner, and apply that. However, on elements with variable dimensions [due to variable contents], this is not possible. Developers often end up approximating it by setting the background position to some percentage that is slightly smaller than 100%, such as 95%. Surely, with modern CSS, there must be a better way

32

CHAPTER 2. BACKGROUNDS & BORDERS

Extended background-position solution The background-position property was extended to allow specifying offsets from any corner in CSS Backgrounds & Borders Level 3

Code Pirate

[w3. org/TR/css3-background], by providing keywords before the offsets. For example, if we want our background image to have a 20px offset from the right side and a 10px offset from the bottom side, we can do this

FIGURE 2. 11 background. url[code-pirate. svg] no-repeat #58a; background-position. right 20px bottom 10px;

Specifying offsets from different sides; the background image is shown here with a dashed outline, to make it clearer how the offsets work

You can see the result in Figure 2. 11. The last step is to provide a decent fallback. As it currently stands, on browsers that don’t support the extended

background-position syntax, the background image will be stuck on the top-left corner [the default position] and will look awful, not to mention it will render the text unreadable [Figure 2. 12]. Providing a fallback is as easy as including a good ol’ bottom right position in the background

Code Pirate

shorthand

background. url[code-pirate. svg] no-repeat bottom right #58a; background-position. right 20px bottom 10px;

FIGURE 2. 12 We need to specify a fallback, if we don’t want users of older browsers to see this

▶ PLAY. play. csssecrets. io/extended-bg-position

background-origin solution One of the most common cases for wanting to apply offsets from a corner is to make the background image follow padding. With the extended background position we just described, the code would look like this

SECRET #3. FLEXIBLE BACKGROUND POSITIONING

33

Code Pirate

padding. 10px; background. url[code-pirate. svg] no-repeat #58a; background-position. right 10px bottom 10px;

FIGURE 2. 13

You can see the result in Figure 2. 13. As you can see, it works, but it’s not

Applying offsets to the background

very DRY. every time we change the padding value, we need to update it in

image that are equal to the padding value

three different places. Thankfully, there is a simpler way to do this, which automatically follows the padding we specify, without the need to redeclare the offsets

Border Box Padding Box

Content Box

You’ve probably written things like background-position. top

left; quite a few times over the course of your web development career. Have you ever wondered. which top-left corner? As you may know, there are four boxes in every element [Figure 2. 14]. the margin box, the border box, the padding box, and the content box. Which box’s top left corner does background-position refer to?

FIGURE 2. 14 The box model

By default, background-position refers to the padding box, so that borders don’t end up obscuring background images. Therefore, top

left is by default the top-left outer corner of the padding box. In Backgrounds & Borders Level 3 [w3. org/TR/css3-background], however, we got a new property that we can use to change this behavior

background-origin. By default, its value is [quite predictably] padding-box. If we change it to content-box, as in the following code, the side and corner keywords we use in background-position will refer to the edge of the content box [effectively, this means that any background images will be offset from the sides/corners as much as our padding is]

padding. 10px; background. url["code-pirate. svg"] no-repeat #58a bottom right; /* or 100% 100% */ background-origin. content-box;

The visual result is exactly the same as in Figure 2. 13, just with more DRY code. Keep in mind that you can also combine the two techniques we showed if needed. If you want offsets that generally vary with the padding,

34

CHAPTER 2. BACKGROUNDS & BORDERS

but are inset/outset a little more than that, you can use background-

origin. content-box together with additional offsets via the extended background-position. ▶ PLAY. play. csssecrets. io/background-origin

calc[] solution Let’s revisit our original challenge. we want to position our background image 10px from the bottom and 20px from the right side. However, if we think of it in terms of offsets from the top-left corner, we basically want an offset of 100% - 20px horizontally and 100% - 10px vertically. Thankfully, the calc[] function allows us to do exactly that sort of calculation and it works perfectly with background-position

!

Don’t forget to include whitespace around any - and + oper-

ators in calc[], otherwise it’s a parsing error. The reason for this weird rule is forward compatibility. in the future, keywords might be allowed inside calc[], and they can contain hyphens

background. url["code-pirate. svg"] no-repeat; background-position. calc[100% - 20px] calc[100% - 10px];

▶ PLAY. play. csssecrets. io/background-position-calc

■ CSS Backgrounds & Borders w3. org/TR/css-backgrounds

RELATED

SPECS

■ CSS Values & Units w3. org/TR/css-values

SECRET #3. FLEXIBLE BACKGROUND POSITIONING

35

4

Inner rounding Prerequisites box-shadow, outline, the “Multiple borders” secret on page 28

The problem Sometimes we want a container that is only rounded on the inside, but the outer corners of its border/outline are sharp, such as the one in Figure 2. 15. It’s an interesting effect that’s not overdone yet. It’s trivial to achieve this effect with two elements

I have a nice subtle inner rounding, don’t I look pretty?

FIGURE 2. 15 A container with an outline and

I have a nice subtle inner rounding, don’t I look pretty?

rounding only on the inside

36

CHAPTER 2. BACKGROUNDS & BORDERS

HTML

something-meaningful { background. #655; padding. . 8em; } . something-meaningful > div { background. tan; border-radius. . 8em; padding. 1em; }

This works fine, but it forces us to use two elements when we only need one. Is there a way to achieve the same effect with only one element?

The solution The previous solution is more flexible, as it allows us to use the full power of backgrounds. For example, if we want our “border” to not just be a solid color, but have a noise texture as well, it’s pretty easy to do. However, when we’re dealing with good ol’ solid colors, there is a way to do this, with just one element [granted it is a bit hacky]. Take a look at the following CSS

I’m a sad element, because my outline doesn’t get along with my round corners . -[

FIGURE 2. 16 Using the outline property on a rounded element

background. tan; border-radius. . 8em;

I’m a happy element, because

padding. 1em;

my fake outline gets along

box-shadow. 0 0 0 . 6em #655;

with my round corners . -]

outline. . 6em solid #655;

FIGURE 2. 17 Using the box-shadow property

Can you guess what the visual result is? It produces the effect in Figure 2. 15

with no offsets and no blur on an

We basically took advantage of the fact that outlines do not follow the

element with rounded corners

element’s rounding [and thus, have sharp corners] but box-shadows do. Therefore, if we overlay one on top of the other, the box-shadow covers the gaps that the outline leaves on the corners [Figure 2. 17], so their

SECRET #4. INNER ROUNDING

37

I have a nice subtle inner rounding, don’t I look pretty?

combination gives us the desired effect. Figure 2. 18 displays the shadow and outline with different colors, to provide a clearer visual explanation. Note that we didn’t really need to specify a box-shadow spread that

FIGURE 2. 18

is equal to the outline, we only need to specify a large enough spread to

Here the outline is shown in black

cover those “gaps. ” In fact, specifying a spread equal to our outline width

and the shadow in magenta, to make it clearer what is going on;

can cause rendering artifacts in some browsers, so I would recommend

notice that the outline is the one

something a bit smaller. This begs the question. what is the smallest

drawn on top

spread we could specify that covers these gaps? To answer this question, we need to remember the Pythagorean the-

!

Why is this hacky? Because it depends on the fact that

outlines do not follow corner

orem we learned at school about calculating the lengths of the sides of right triangles. The theorem states that the hypotenuse [the longest, diagonal

rounding, but there is no guarantee

side of the triangle] is equal to a2 + b2 where a and b are the lengths of

this will stay that way. The spec cur-

its legs. When both legs are of equal length, the formula becomes

rently gives browsers a lot of leeway in outline drawing, but in the future it will explicitly recommend following rounding, per a recent CSS WG decision. Whether brows-

2a2 = a 2. You might be wondering how on Earth middle school geometry is relevant to our inner rounding effect. Check out Figure 2. 19 for a visual ex-

ers will honor that decision remains

planation of how it can be used to calculate the minimum spread we need

to be seen

In our case, border-radius is . 8em, so the minimum spread is . 8 2 − 1 ≈ . 33137085em. All we need is to round it up a little and specify a spread radius of . 34em. To avoid having to make the calculation every time, you can just use half of your corner radius, which is guaranteed to be

r 2 r

large enough, because 2 − 1 < 0 . 5. Note that these calculations uncover another constraint of this method. for this effect to work, our spread radius needs to be smaller than 2 − 1 r, where r is

FIGURE 2. 19

our outline width, but it also needs to be larger than

When our border radius is r, the

our border-radius. This means that if our outline width is smaller than

length from the center of the

border-radius circle to the

2 − 1 r, this is not possible and we cannot apply this effect

corner of the outline rectangle is

r 2, which means the minimum possible spread is

r 2−r =

▶ PLAY. play. csssecrets. io/inner-rounding

2−1r

■ CSS Backgrounds & Borders w3. org/TR/css-backgrounds ■ CSS Basic User Interface w3. org/TR/css3-ui

38

CHAPTER 2. BACKGROUNDS & BORDERS

RELATED

SPECS

5

Striped backgrounds Prerequisites CSS linear gradients, background-size

The problem Stripes of all sizes, colors, and angles are at least as ubiquitous on the Web as in any other medium of visual design, from magazines to wallpaper. However, the workflow of implementing them is far from ideal. Usually, we would create a separate bitmap image and need an image editor every time we needed to make changes. Some might use SVG instead, but it’s still a separate file and the syntax is far from friendly. Wouldn’t it be awesome if we could create stripes directly in our CSS? You might be surprised to find that we actually can

40

CHAPTER 2. BACKGROUNDS & BORDERS

The solution Assume we have a basic vertical linear gradient, from

#fb3 to

#58a

[Figure 2. 20]

background. linear-gradient[#fb3, #58a];

FIGURE 2. 20 Now let’s try to bring the color stops a little closer together [Figure 2. 21]

Our starting point

background. linear-gradient[#fb3 20%, #58a 80%];

Now the top 20% of our container is filled with solid

#fb3 and the bot-

#58a. The actual gradient only occupies 60% of our container height. If we bring the color stops even closer together [40% and 60% respectively, seen in Figure 2. 22], the actual gradient becomes even tom 20% with solid

FIGURE 2. 21 Gradient now occupies 60% of total

smaller. One starts to wonder, what happens if the color stops meet at the

height, the rest being solid colors;

exact same position?

color stop positions are shown with dashed lines

background. linear-gradient[#fb3 50%, #58a 50%];

“If multiple color stops have the same position, they produce an infinitesimal transition from the one specified first in the rule to the one specified last. In effect, the color suddenly changes at that position rather than

FIGURE 2. 22

smoothly transitioning. ” — CSS Image Values Level 3 [w3. org/TR/css3-images]

As you can see in Figure 2. 23, there is no longer any gradient, just two solid colors, each occupying half of our background-image. Essentially,

Gradient now occupies 20% of total height, the rest being solid colors; color stop positions are shown with dashed lines

we have already created two big horizontal stripes. Because gradients are just generated background images, we can treat them the same as any other background image and adjust their size with

kích thước nền

SECRET #5. STRIPED BACKGROUNDS

41

background. linear-gradient[#fb3 50%, #58a 50%]; background-size. 100% 30px;

As you can see in Figure 2. 24, we shrunk the size of our two stripes

FIGURE 2. 23

to 15px height each. Because our background is repeated, we now have

Both stops are now at 50%

our whole container filled with horizontal stripes [Figure 2. 25]. We can similarly create stripes with unequal widths, by adjusting the color stop positions [Figure 2. 26]

background. linear-gradient[#fb3 30%, #58a 30%]; background-size. 100% 30px;

FIGURE 2. 24 Our generated background without

To avoid having to adjust two numbers every time we want to change the

the repetition

stripe width, we can take advantage of the specification. “If a color stop has a position that is less than the specified position of any color stop before it in the list, set its position to be equal to the largest specified position of any color stop before it. ” — CSS Images Level 3 [w3. org/TR/css3-images]

This means that if we set the second color’s position at 0, its position

FIGURE 2. 25

will be adjusted by the browser to be equal to the position of the previous

The final horizontal stripes

color stop, which is what we wanted anyway. Therefore, the following code also creates the exact same gradient we saw in Figure 2. 26, but is a little more DRY

background. linear-gradient[#fb3 30%, #58a 0]; background-size. 100% 30px;

FIGURE 2. 26 Stripes with unequal widths

It’s just as easy to create stripes with more than two colors. For example, the following snippet will produce horizontal stripes of three colors [Figure 2. 27]

42

CHAPTER 2. BACKGROUNDS & BORDERS

background. linear-gradient[#fb3 33. 3%, #58a 0, #58a 66. 6%, yellowgreen 0]; background-size. 100% 45px;

▶ PLAY. play. csssecrets. io/horizontal-stripes

FIGURE 2. 27 Stripes with three colors

Vertical stripes Horizontal stripes are the easiest to code, but not all striped backgrounds we see on the Web are horizontal. Just as many are vertical stripes [Figure 2. 28], and probably the most popular and visually interesting are some form of diagonal stripes. Thankfully, CSS gradients can help us recreate those too, with varying degrees of difficulty. The code for vertical stripes is almost the same, with one main difference. an extra first argument that specifies the gradient direction. We could have specified it for horizontal stripes too, but the default [to bottom] was exactly what we needed for them. We also need to set a different

background-size, for obvious reasons. FIGURE 2. 28 background. linear-gradient[to right, /* or 90deg */ #fb3 50%, #58a 0];

Our vertical stripes Top. Our background tile without the repetition Bottom. The repeated stripes

background-size. 30px 100%;

▶ PLAY. play. csssecrets. io/vertical-stripes

Diagonal stripes After creating horizontal and vertical stripes, we might attempt to create diagonal stripes [45°] by just changing the background-size and direction of the gradient again, like so

FIGURE 2. 29 Our first failed attempt for diagonal stripes

SECRET #5. STRIPED BACKGROUNDS

43

background. linear-gradient[45deg, #fb3 50%, #58a 0]; background-size. 30px 30px;

However, as you can see in Figure 2. 29, this doesn’t work. The reason is that we just rotated the gradient inside each tile by 45 degrees, not the repeated background as a whole. Try to remember the bitmap images we usually use to create diagonal stripes, such as the one in Figure 2. 30. They include four stripes instead of two, so that they tile seamlessly. This is the

FIGURE 2. 30

kind of tile we need to recreate in CSS, so we will need quite a few more

The kind of image that tiles

color stops

seamlessly to create diagonal stripes; does it look familiar?

background. linear-gradient[45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0]; background-size. 30px 30px;

FIGURE 2. 31 Our 45° stripes; the dashed lines indicate the repeating tile

You can see the result in Figure 2. 31. As you can see, we were successful at creating diagonal stripes, but they look thinner than our horizontal and vertical ones. To understand why this happened, we need to remember the Pythagorean theorem we learned at school about calculating the lengths of the sides of right triangles. The theorem states that the hypotenuse [the longest, diagonal side of the triangle] is equal to a2 + b2 where a and b are the lengths of its legs. On a 45° right triangle, both its legs are of the same length, so the formula becomes 2a2 = a 2. In our diagonal stripes, the background size specifies the length of the hypotenuse, but the stripe width is actually the length of the leg. Check out Figure 2. 32 for a visual

15px

explanation

2

This means that to get our original stripe width of 15px, we need to specify a background size of 2 × 15 2 ≈ 42 . 426406871 pixels

15px

FIGURE 2. 32 A background size of 20px results in a stripe width of

background. linear-gradient[45deg,

15 ≈ 10 . 606601718 pixels 2

44

CHAPTER 2. BACKGROUNDS & BORDERS

#fb3 25%, #58a 0, #58a 50%,

#fb3 0, #fb3 75%, #58a 0]; background-size. 42. 426406871px 42. 426406871px;

You can see the final result in Figure 2. 33. However, unless somebody is pointing a gun at your head threatening to kill you unless you are able to produce diagonal stripes that are exactly 15 pixels wide [in which case, you would die anyway, because 2 is not a rational number, so even this is an approximation—though a very high-precision one], I would strongly recommend rounding this unwieldy number, to something like 42. 4px or

FIGURE 2. 33 Our final 45° stripes; note that now

even 42px

the stripe width is the same as our other examples

▶ PLAY. play. csssecrets. io/diagonal-stripes

Better diagonal stripes The method shown in the previous section is not very flexible. What if we want stripes that are 60° instead of 45°? Or 30°? Or 3. 1415926535°? If we just try to change the angle of the gradient, the result looks awful [check out Figure 2. 34 for a failed attempt at 60° stripes]. Thankfully, there is a better way to create diagonal stripes. A littleknown fact is that linear-gradient[] and radial-gradient[] also

FIGURE 2. 34

repeating-linear-gradient[] and repeating-radial-gradient[]. These work exactly the same way,

Our failed naïve attempt at 60°

have

repeating

versions

stripes

with one difference. the color stops are repeated indefinitely, until they fill up the whole image. So, for example, this repeating gradient [shown in Figure 2. 35]

background. repeating-linear-gradient[45deg, #fb3, #58a 30px];

would be equivalent to this simple linear gradient

FIGURE 2. 35 A repeating linear gradient

SECRET #5. STRIPED BACKGROUNDS

45

background. linear-gradient[45deg, #fb3, #58a 30px, #fb3 30px, #58a 60px, #fb3 60px, #58a 90px, #fb3 90px, #58a 120px, #fb3 120px, #58a 150px, . ];

Repeating linear gradients are perfect for — you guessed it — stripes. Due to their repeating nature, it means our whole background can be in the generated gradient image. Therefore, we don’t need to worry about creating seamless tiles that can be repeated. For comparison, the background we created in Figure 2. 33 could have been produced by this repeating gradient

background. repeating-linear-gradient[45deg, #fb3, #fb3 15px, #58a 0, #58a 30px];

The first obvious benefit is reduced repetition. we can change any of the colors with two edits instead of three. Also note that our measurements are now in the gradient color stops instead of background-size. The background size is the initial one, which for gradients is the size of the element. This means that the lengths are also more straightforward, as they are measured on the gradient line, which is perpendicular to our stripes. No more clunky 2 calculations. However, the biggest benefit is that now we can just change the angle to whatever we want, and it just works without having to think hard and long about how to make a seamless tile. For example, here are our 60° stripes [Figure 2. 36]

background. repeating-linear-gradient[60deg,

FIGURE 2. 36 Our actual 60° stripes

46

CHAPTER 2. BACKGROUNDS & BORDERS

#fb3, #fb3 15px, #58a 0, #58a 30px];

It was as easy as just changing the angle. Note that with this method we need four color stops for two stripe colors, regardless of the stripe angle. This means it’s usually better to use the first method for horizontal and vertical stripes and this one for diagonal stripes. If we’re dealing with 45° stripes, we could even combine the two methods, by essentially using repeating linear gradients to simplify the code that creates our repeating tile

background. repeating-linear-gradient[45deg, #fb3 0, #fb3 25%, #58a 0, #58a 50%]; background-size. 42. 426406871px 42. 426406871px;

▶ PLAY. play. csssecrets. io/diagonal-stripes-60deg

FUTURE

Color stops with two positions

Soon, we will be able to specify two positions on the same color stop, as one of the simpler planned additions in CSS Image Values Level 4 [w3. org/TR/css4-images]. This will work as a shortcut to two consecutive color stops with the same color and different positions, something very commonly needed to create gradient-based patterns. For example, the code for the diagonal stripes in Figure 2. 36 would become

background. repeating-linear-gradient[60deg, #fb3 0 15px, #58a 0 30px];

Not only is this significantly more concise, but also considerably more DRY. the colors are no longer duplicated, so we can change them with only one edit. Unfortunately, at the time of writing, this is not yet supported in any browser. TEST. play. csssecrets. io/test-color-stop-2positions

SECRET #5. STRIPED BACKGROUNDS

47

Flexible subtle stripes More often than not, our stripes are not completely different colors but subtle brightness variations of the same color. For example, take a look at these stripes

background. repeating-linear-gradient[30deg, #79b, #79b 15px, #58a 0, #58a 30px];

You can see in Figure 2. 37 that they are stripes of one color [

#58a] and a lighter variant of that. However, that relationship between

the colors is not easy to tell by reading the code. Moreover, if we wanted to change the base color, we would have to make four [. ] edits. Thankfully, there is a better way. instead of specifying separate colors

FIGURE 2. 37

for every stripe, we can specify our darkest color as the background color,

Stripes with subtle lightness

which will show through stripes with semi-transparent white

variation

background. #58a; background-image. repeating-linear-gradient[30deg, hsla[0,0%,100%,. 1], hsla[0,0%,100%,. 1] 15px, transparent 0, transparent 30px];

The result looks exactly the same as Figure 2. 37, but we can now change the color in only one place. We also get the added benefit of our base color functioning as a fallback color for browsers that don’t support CSS gradients. Furthermore, as we will see in the next secret, gradient patterns with transparent regions allow us to create very complex patterns by superimposing multiple different ones. ▶ PLAY. play. csssecrets. io/subtle-stripes

48

CHAPTER 2. BACKGROUNDS & BORDERS

■ CSS Image Values w3. org/TR/css-images

RELATED

SPECS

■ CSS Backgrounds & Borders w3. org/TR/css-backgrounds ■ CSS Image Values Level 4 w3. org/TR/css4-images

SECRET #5. STRIPED BACKGROUNDS

49

6

Complex background patterns Prerequisites CSS gradients, the “Striped backgrounds” secret on page 40

The problem In the previous section, we learned how to use CSS gradients to create all sorts of stripes. However, stripes are not the be-all and end-all of background patterns or even just geometric patterns. We quite often need many other different types, such as grids, polka dots, checkerboards, and many others. Thankfully, CSS gradients can help with many of these too. It’s possible to create almost any kind of geometric pattern with CSS gradients, although it’s not always practical. If we’re not careful, we might end up with an insane amount of unmaintainable code. CSS patterns are also one case where it really pays off to use a CSS preprocessor, such as

50

CHAPTER 2. BACKGROUNDS & BORDERS

Sass [sass-lang. com] to reduce repetition, as the more complex they get, the less DRY they become

FIGURE 2. 38 My CSS3 Patterns Gallery [found at lea. verou. me/css3patterns] showed what is possible with CSS gradients as early as 2011. It was included in almost every article, book, and conference talk that mentioned CSS gradients between 2011 and 2012 and was used by several browser vendors to fine-tune their CSS gradients implementations. However, not every pattern showcased in it would be a good use case for a production website. Some of them are included only to show what is possible, but their code is extremely long and repetitive. For those cases, SVG is a better choice. For some examples of SVG patterns, visit philbit. com/svgpatterns, which was created as the SVG answer to the CSS Patterns Gallery

SECRET #6. COMPLEX BACKGROUND PATTERNS

51

In this secret, we will focus on creating some of the easiest and commonly needed patterns

Grids When using only one gradient, there aren’t that many patterns we can create. The magic starts to unfold when we combine multiple gradients, having them show through each other’s transparent regions. Perhaps the easiest such pattern is overlaying horizontal and vertical stripes to create various types of grids. For example, the following code creates the tablecloth-reminiscent [gingham] pattern shown in Figure 2. 39

background. white; background-image. linear-gradient[90deg, rgba[200,0,0,. 5] 50%, transparent 0], linear-gradient[ rgba[200,0,0,. 5] 50%, transparent 0]; background-size. 30px 30px;

FIGURE 2. 39

In some cases, we want to be able to adjust the cell size of the grid,

Our tablecloth [gingham] pattern, as

and have the width of its lines remain constant—for example, to create

well as the two gradients that

grid lines that serve as guides. This is a great use case for using lengths

comprise it [transparency shown here as the conventional gray

instead of percentages as gradient color stops

checkerboard]

background. #58a; background-image. linear-gradient[white 1px, transparent 0], linear-gradient[90deg, white 1px, transparent 0]; background-size. 30px 30px;

FIGURE 2. 40 A basic blueprint grid CSS pattern

The result [seen on Figure 2. 40] is a grid of 1px white lines with a grid cell

whose lines remain 1px regardless

size of 30px. Just like in the “Flexible subtle stripes” section on page

of the size of the grid

48, the base color is also functioning as a fallback color

52

CHAPTER 2. BACKGROUNDS & BORDERS

This grid is a good example of a pattern that can be made with reasonably maintainable [though not completely DRY] CSS code. ■ It’s quite easy to figure out what to edit if we need to change the grid size, line thickness, or any of the colors

TIP

To calculate the file size of your CSS pattern, paste

the code in

■ We don’t have to make tons of edits to change any of this; we only need

bytesizematters. com

to edit one or two values. ■ It’s also quite short, at only four lines of code and 170 bytes. An SVG would not have been shorter. We can even overlay two grids with different line widths and colors to create a more realistic blueprint grid [Figure 2. 41]

background. #58a; background-image. linear-gradient[white 2px, transparent 0], linear-gradient[90deg, white 2px, transparent 0], linear-gradient[hsla[0,0%,100%,. 3] 1px, transparent 0],

FIGURE 2. 41 A more complex blueprint grid,

linear-gradient[90deg, hsla[0,0%,100%,. 3] 1px, transparent 0];

comprised of two grids with different parameters

background-size. 75px 75px, 75px 75px, 15px 15px, 15px 15px;

▶ PLAY. play. csssecrets. io/blueprint

Polka dot So far, we have only used linear gradients to make patterns. However, radial gradients can be very useful as well, as they allow us to create circles, ellipses, or parts thereof. The simplest pattern we can create with a radial gradient is an array of dots [Figure 2. 42]

SECRET #6. COMPLEX BACKGROUND PATTERNS

53

background. #655; background-image. radial-gradient[tan 30%, transparent 0]; background-size. 30px 30px;

FIGURE 2. 42

Admittedly, this is not very useful on its own. However, we can combine

An array of dots; the repeating tile is

two of those gradients and give them different background positions, to

shown with dashed lines

create a polka dot pattern [Figure 2. 43]

background. #655; background-image. radial-gradient[tan 30%, transparent 0], radial-gradient[tan 30%, transparent 0]; background-size. 30px 30px;

FIGURE 2. 43

background-position. 0 0, 15px 15px;

Polka dot pattern; both repeating tiles are shown with dashed lines

▶ PLAY. play. csssecrets. io/polka Note that for the effect to work, the second background position must be half of the tile size. Unfortunately, this means that to change the tile size, we need to make four edits. This is on the brink of being unmaintainable, although whether it has crossed the line is debatable. If you are using a preprocessor, you may want to convert it into a mixin

@mixin polka[$size, $dot, $base, $accent] {

SCSS

background. $base; background-image. radial-gradient[$accent $dot, transparent 0], radial-gradient[$accent $dot, transparent 0]; background-size. $size $size; background-position. 0 0, $size/2 $size/2; }

54

CHAPTER 2. BACKGROUNDS & BORDERS

Then, to create the polka dot pattern, we would call it like this

@include polka[30px, 30%, #655, tan];

SCSS

Checkerboards Checkerboard patterns are used in a number of cases. For instance, subtle checkerboards can be an interesting alternative to a bland solid color background. Also, a gray checkerboard pattern is the de facto standard way to depict transparency, which is required in a number of different UIs. Making a checkerboard pattern in CSS is possible, but considerably trickier than one

FIGURE 2. 44

might expect. The typical tile that generates a checkerboard when repeated consists of two squares from each color, like the one indicated in Figure 2. 44. It

A gray checkerboard pattern to indicate transparency; if this was created by repeating an image, the

looks like it should be easy to recreate with CSS. we would just create two

tile would be the one denoted by the

squares with different background positions, right? Not exactly. Yes, we can

dashed line

technically create squares with CSS gradients, but with no spacing around them, the result will look like a solid color. However, there is no way to create squares with space around them with one CSS gradient. If you’re having doubts, try to find a gradient that, when repeated, produces the image in Figure 2. 45. The trick is to compose the square from two right triangles. We already know how to create right triangles [remember our failed attempt at diagonal stripes in Figure 2. 29?]. To refresh your memory, the code looked like this [here with different colors and transparency]

background. #eee; background-image. linear-gradient[45deg, #bbb 50%, transparent 0]; background-size. 30px 30px;

FIGURE 2. 45 Repeating a square with space around it; the tile is shown with dashed lines

You might be wondering how this helps with anything. Sure, if we tried to compose squares from two triangles like the ones in Figure 2. 29, we would

SECRET #6. COMPLEX BACKGROUND PATTERNS

55

end up with a solid color. However, what if we reduce the legs of these 1

triangles to half their original size, so that they occupy 8 of the tile, instead 1 of the current 2 ? We can easily do that by changing the color stop position to 25% instead of 50%. Then we would end up with something

FIGURE 2. 46 Right triangles with a lot of spacing around them

FUTURE

như hình 2. 46. Tương tự, ta có thể tạo các tam giác ngược hướng nếu lật các điểm dừng màu [hình 2. 47]

Độ dốc hình nón

Trong tương lai, chúng ta sẽ không phải dùng đến các hình tam giác chồng lên nhau một cách tỉ mỉ để tạo ra các bàn cờ. Giá trị hình ảnh CSS cấp 4 [w3. org/TR/css4images] xác định một tập hợp mới các hàm chuyển màu để tạo ra các chuyển màu hình nón [a. k. a. “độ dốc góc”]. Những chuyển màu này thường trông giống như một hình nón được quan sát từ phía trên, do đó có tên “hình nón. ” Chúng được tạo ra bởi một đường đổi màu dần dần khi nó quay quanh một điểm cố định. Ví dụ: bánh xe màu sắc được hiển thị ở đây sẽ được tạo với độ dốc sau

lai lịch. conic-gradient [đỏ, vàng, vôi, thủy, lam, fuchsia, đỏ];

Độ dốc hình nón hữu ích cho nhiều thứ hơn bánh xe màu sắc. hiệu ứng tỏa sáng dạng sao, hiệu ứng kim loại chải và nhiều loại hình nền khác, bao gồm [bạn đoán xem. ] bàn cờ. Chúng sẽ cho phép chúng ta tạo ô lặp lại của Hình 2. 44 chỉ trong một gradient

lai lịch. repeat-conic-gradient[#bbb 0, #bbb 25%, #eee 0, #eee 50%]; . 30px 30px;

Thật không may, không có hỗ trợ trình duyệt cho độ dốc hình nón tại thời điểm viết. KIỂM TRA. chơi. bí mật css. io/test-conic-gradient

56

CHAPTER 2. BACKGROUNDS & BORDERS

lai lịch. #eee; . độ dốc tuyến tính [45deg, trong suốt 75%, #bbb

0];

kích thước nền. 30px 30px;

HÌNH 2. 47 Bạn đoán xem điều gì sẽ xảy ra nếu chúng ta kết hợp cả hai?

Nếu chúng ta lật các điểm dừng màu, chúng ta sẽ có các hình tam giác theo hướng ngược lại

lai lịch. #eee; . độ dốc tuyến tính [45deg, #bbb 25%, trong suốt 0], độ dốc tuyến tính [45deg, trong suốt 75%, #bbb 0]; . 30px 30px;

Lúc đầu, kết quả trong Hình 2. 48 không có vẻ như chúng ta đang đi đến đâu. Tuy nhiên, chúng ta chỉ cần di chuyển gradient thứ hai bằng một nửa kích thước ô, để kết hợp chúng thành một hình vuông

lai lịch. #eee; . độ dốc tuyến tính [45deg, #bbb 25%, trong suốt 0], độ dốc tuyến tính [45deg, trong suốt 75%, #bbb 0]; . 0 0, 15px 15px; . 30px 30px;

HÌNH 2. 48 Gộp hai tam giác

Bạn có đoán được kết quả trông như thế nào không? . 49. Lưu ý rằng đây thực chất là một nửa bàn cờ. Tất cả những gì chúng ta cần để biến cái này thành một bàn cờ hoàn chỉnh là lặp lại hai chuyển màu để tạo ra một tập hợp các ô vuông khác và bù lại vị trí của chúng, giống như áp dụng kỹ thuật chấm bi hai lần

lai lịch. #eee;

SECRET #6. COMPLEX BACKGROUND PATTERNS

57

hình nền. độ dốc tuyến tính[45deg, #bbb 25%, trong suốt 0], độ dốc tuyến tính[45deg, trong suốt 75%, #bbb 0], độ dốc tuyến tính[45deg, #bbb 25%, trong suốt 0],

HÌNH 2. 49 Tam giác kết hợp của chúng tôi bây giờ hình thành

độ dốc tuyến tính [45deg, trong suốt 75%, #bbb 0]; . 0 0, 15px 15px, 15px 15px, 30px 30px;

hình vuông với không gian xung quanh chúng;

kích thước nền. 30px 30px;

hiển thị hơi tối hơn

Kết quả là một bàn cờ, giống như trong Hình 2. 44. Chúng ta có thể cải thiện mã một chút bằng cách kết hợp các hình tam giác đối diện [i. e. , cái đầu tiên với cái thứ hai và cái thứ ba với cái thứ tư] và làm cho màu xám đậm hơn bán trong suốt thành màu đen, để chúng ta có thể thay đổi màu cơ bản mà không phải luôn điều chỉnh màu trên cùng cho phù hợp

HÌNH 2. 50 Đây là một mẫu phức tạp và thường rất khó để nắm bắt được cách thức hoạt động của nó, đặc biệt là sau khi giảm nó thành hai độ dốc. Nó thường hỗ trợ sự hiểu biết về cách thức hoạt động của một mẫu để tạo màu ngẫu nhiên cho một trong các dải màu hoặc điểm dừng màu. Ví dụ, ở đây gradient đầu tiên được hiển thị với

rebeccapurple thay vì

lai lịch. #eee; . độ dốc tuyến tính [45deg, rgba [0,0,0,. 25] 25%, trong suốt 0, trong suốt 75%, rgba[0,0,0,. 25] 0], độ dốc tuyến tính [45deg, rgba [0,0,0,. 25] 25%, trong suốt 0, trong suốt 75%, rgba[0,0,0,. 25] 0];

màu đen bán trong suốt và hai

background-position. 0 0, 15px 15px;

gạch được phác thảo với các đường đứt nét

kích thước nền. 30px 30px;

WET là viết tắt của “We Enjoy Typing” và ngược lại với mã DRY [i. e. , nó đề cập đến mã lặp đi lặp lại, không thể duy trì]

Bây giờ chúng tôi có hai độ dốc thay vì bốn, nhưng mã gần như ƯỚT như trước. Để thay đổi màu nhấn hoặc kích thước ô, chúng ta cần thực hiện bốn lần chỉnh sửa. Tại thời điểm này, có thể nên sử dụng mixin tiền xử lý để giảm trùng lặp. Ví dụ, trong Sass nó sẽ như thế này

@mixin checkerboard[$size, $base, $accent. rgba[0,0,0,. 25] {

58

CHAPTER 2. BACKGROUNDS & BORDERS

SCSS

lai lịch. cơ sở $; . độ dốc tuyến tính[45deg, $accent 25%, trong suốt 0, trong suốt 75%, $accent 0], linear-gradient[45deg, $accent 25%, trong suốt 0, trong suốt 75%, $accent 0]; . 0 0, $size $size, kích thước nền. 2*$size 2*$size;

Trong mọi trường hợp, đây là quá nhiều mã nên thực sự có thể tốt hơn nếu đi theo lộ trình SVG. Một ô SVG cho Hình 2. 44 sẽ nhỏ và đơn giản như

Người ta có thể trả lời, “Nhưng độ dốc CSS tiết kiệm cho chúng tôi các yêu cầu HTTP. ” Tuy nhiên, với các trình duyệt hiện đại, chúng tôi có thể nhúng tệp SVG vào biểu định kiểu của mình dưới dạng URI dữ liệu và chúng tôi thậm chí không cần mã hóa base64 hoặc URL cho hầu hết tệp đó

lai lịch. #eee url['dữ liệu. hình ảnh/svg+xml,\ \ \

SECRET #6. COMPLEX BACKGROUND PATTERNS

59

\']; . 30px 30px;

TIP

Lưu ý cách bạn có thể chia chuỗi CSS thành nhiều chuỗi

để dễ đọc, bằng cách thoát khỏi ngắt dòng bằng dấu gạch chéo ngược [\]

Phiên bản SVG không chỉ ngắn hơn 40 ký tự mà còn ít lặp lại hơn đáng kể. Ví dụ: chúng tôi có thể thay đổi màu sắc chỉ ở một nơi và kích thước bằng hai lần chỉnh sửa. CHƠI. chơi. bí mật css. io/bàn cờ-svg

■ Giá trị hình ảnh CSS w3. org/TR/css-images ■ Hình nền và đường viền CSS w3. org/TR/css-backgrounds ■ Đồ họa Vector có thể mở rộng w3. org/TR/SVG ■ Giá trị hình ảnh CSS cấp 4 w3. hình ảnh org/TR/css4

60

CHAPTER 2. BACKGROUNDS & BORDERS

RELATED

SPECS

HÌNH 2. 51 Kết hợp các kỹ thuật này với các chế độ hòa trộn [w3. org/TR/compositing-1], bằng cách sử dụng

chế độ hòa trộn nền với các giá trị khác với giá trị bình thường đối với một số [hoặc thậm chí tất cả] các lớp mà mẫu nền được tạo có thể mang lại kết quả rất thú vị, vì bộ sưu tập mẫu này của Bennett Feely [bennettfeely. com/gradient] thể hiện. Hầu hết các mẫu này chỉ sử dụng

nhiều chế độ hòa trộn, nhưng các giá trị khác như lớp phủ, màn hình hoặc sự khác biệt cũng có thể rất hữu ích

7

[Giả] nền ngẫu nhiên Điều kiện tiên quyết Độ dốc CSS, bí mật “Nền sọc” ở trang 40, bí mật “Các mẫu nền phức tạp” ở trang 50

Vấn đề Lặp lại các mẫu hình học rất hay, nhưng có thể hơi nhàm chán. Hầu như không có gì trong tự nhiên từng lặp lại trong các ô giống hệt nhau. Ngay cả trong sự lặp lại, luôn có sự thay đổi và ngẫu nhiên. Nhìn cánh đồng hoa. trong khi nó đủ đồng bộ để đẹp, nó cũng đủ ngẫu nhiên để thú vị. Không có hai bông hoa nào giống hệt nhau. Đây là lý do tại sao khi chúng tôi cố gắng làm cho các mẫu nền trông tự nhiên nhất có thể, chúng tôi

HÌNH 2. 52

cũng cố gắng có càng ít và càng khó để nhận ra các “đường nối” giữa các

Tự nhiên không lặp lại chính nó trong

gạch than bùn càng tốt, điều này mâu thuẫn trực tiếp với mong muốn của chúng tôi là giữ

gạch "liền mạch"

62

kích thước tệp thấp

CHAPTER 2. BACKGROUNDS & BORDERS

“[W]khi bạn nhận thấy một đặc điểm riêng biệt—chẳng hạn như một nút thắt trên một số thớ gỗ—lặp đi lặp lại đều đặn, nó thực sự phá vỡ ảo tưởng về sự ngẫu nhiên hữu cơ. ” — Alex Walker, Nguyên tắc ve sầu và tại sao nó lại quan trọng đối với các nhà thiết kế web [sitepoint. com/the-cicada-principle-and-why-it-matters-to-web-designers]

Tái tạo tính ngẫu nhiên có thể là một thách thức vì CSS không cung cấp bất kỳ khả năng ngẫu nhiên vốn có nào. Hãy lấy ví dụ về sọc. Giả sử chúng ta muốn các sọc dọc có nhiều màu sắc và chiều rộng khác nhau [hãy giữ cho nó đơn giản và nói bốn màu], không có "đường nối" có thể nhìn thấy của các ô lặp lại. Suy nghĩ đầu tiên của chúng tôi có thể là tạo một dải màu có cả bốn sọc, như vậy

lai lịch. linear-gradient[90deg, #fb3 15%, #655 0, #655 40%, #ab4 0, #ab4 65%, hsl[20, 40%, 90%] 0]; . 80px 100%;

HÌNH 2. 53 Nỗ lực ban đầu của chúng tôi về các sọc giả ngẫu nhiên, với tất cả các màu được tạo bởi cùng một gradient tuyến tính

Như bạn có thể thấy trong Hình 2. 53, sự lặp lại là rõ ràng, vì mẫu lặp lại chính nó sau mỗi 80px [kích thước nền của chúng tôi]. Chúng ta có thể làm tốt hơn không?

Giải pháp Một ý tưởng đầu tiên có thể là nâng cao ảo giác về tính ngẫu nhiên bằng cách chia ô sọc phẳng thành các lớp. một màu cơ bản và ba lớp sọc, lặp lại trong các khoảng thời gian khác nhau. Chúng ta có thể dễ dàng đạt được điều này bằng cách mã hóa cứng độ rộng của sọc trong các điểm dừng màu và sử dụng kích thước nền để kiểm soát khoảng cách của chúng. Mã có thể trông như thế này

BÍ MẬT #7. [PSEUDO]NỀN TẢNG NGẪU NHIÊN

63

lai lịch. hsl[20, 40%, 90%]; . độ dốc tuyến tính [90deg, #fb3 10px, trong suốt 0], độ dốc tuyến tính [90deg, #ab4 20px, trong suốt 0], độ dốc tuyến tính [90deg, #655 20px, trong suốt 0]; . 80px 100%, 60px 100%, 40px 100%;

HÌNH 2. 54 Nỗ lực thứ hai của chúng tôi, liên quan đến việc phủ các dải màu khác nhau với các kích thước nền khác nhau;

Bởi vì sự lặp lại trong ô trên cùng sẽ dễ nhận thấy nhất [vì nó không bị che phủ bởi bất kỳ thứ gì], nên chúng tôi muốn đặt ô có khoảng lặp lại lớn nhất lên trên cùng [trong trường hợp này là các sọc màu cam]. Lưu ý rằng ở đây "gạch" được sử dụng một chút tự do. nó không đề cập đến hình ảnh lặp đi lặp lại của bất kỳ độ dốc riêng lẻ nào,

Như bạn có thể thấy trong Hình 2. 54, những thứ này trông ngẫu nhiên hơn đáng kể, nhưng nếu nhìn kỹ, chúng ta vẫn có thể thấy ô lặp lại cứ sau 240px. Các

nhưng gạch lặp lại nhận thức của

phần cuối của ô lặp lại đầu tiên của bố cục như vậy là phần bù tại đó

thành phần của chúng [tôi. e. , nếu chúng ta

tất cả các hình nền riêng lẻ của chúng tôi đã lặp lại một số nguyên

không sử dụng nhiều nền, kích thước lặp đi lặp lại của chúng tôi sẽ như thế nào-

số lần. Như bạn có thể nhớ từ trường học, nếu chúng ta có một vài

hình ảnh mặt đất phải đạt được

số, số tối thiểu có thể chứa bất kỳ số nào trong số chúng là số nguyên

cùng một kết quả?]

số lần là bội số chung nhỏ nhất của chúng [thường được viết tắt là LCM]. Do đó, ở đây kích thước của ô là LCM của các kích thước nền và LCM của 40, 60 và 80 là 240. Theo logic, để tăng tính ngẫu nhiên được nhận thức, chúng ta cần tối đa hóa kích thước của ô lặp lại. Nhờ có toán học, chúng ta không phải suy nghĩ nhiều và vất vả về cách đạt được điều này, bởi vì chúng ta đã biết câu trả lời. Để đạt được LCM tối đa, các con số cần được

64

CHAPTER 2. BACKGROUNDS & BORDERS

HÌNH 2. 55 Sọc cuối cùng của chúng tôi, sử dụng các số nguyên tố để tăng tính ngẫu nhiên được nhận thức

tương đối nguyên tố. * Trong trường hợp đó, LCM của họ là sản phẩm của họ. Ví dụ: 3, 4 và 5 là nguyên tố cùng nhau, vì vậy LCM của chúng là 3 × 4 × 5 = 60. Một cách dễ dàng để đạt được điều này là chọn các số nguyên tố, bởi vì chúng luôn nguyên tố tương đối với bất kỳ số nào khác. Danh sách các số nguyên tố lên đến số rất lớn được phổ biến rộng rãi trên Web. Để tối đa hóa tính ngẫu nhiên hơn nữa, chúng ta thậm chí có thể sử dụng các số nguyên tố cho độ rộng của sọc. Đây là những gì mã của chúng tôi sẽ trông như thế nào

lai lịch. hsl[20, 40%, 90%]; . độ dốc tuyến tính [90deg, #fb3 11px, trong suốt 0], độ dốc tuyến tính [90deg, #ab4 23px, trong suốt 0], độ dốc tuyến tính [90deg, #655 41px, trong suốt 0]; . 41px 100%, 61px 100%, 83px 100%;

Vâng, mã không đẹp, nhưng chúc may mắn khi cố gắng tìm bất kỳ đường nối nào trong Hình 2. 55. Kích thước của ô lặp lại của chúng tôi hiện là 41 × 61 × 83 = 207, 583 pixel, lớn hơn bất kỳ độ phân giải màn hình nào mà người ta có thể tưởng tượng. Kỹ thuật này được đặt tên là "Nguyên tắc ve sầu" của Alex Walker, người đầu tiên có ý tưởng sử dụng các số nguyên tố để tăng tính ngẫu nhiên của nền. Lưu ý rằng điều này không chỉ hữu ích cho nền mà còn cho bất kỳ thứ gì liên quan đến sự lặp lại. Các ứng dụng khác bao gồm

* Số nguyên tố là số nguyên không chia hết cho số nào khác ngoài 1 và chính nó. Ví dụ: 10 số nguyên tố đầu tiên là 2, 3, 5, 7, 11, 13, 17, 19, 23, 29. Mặt khác, số nguyên tố tương đối là mối quan hệ giữa các số, không phải là thuộc tính của một số. Các số nguyên tố tương đối không có ước chung nhưng có thể có nhiều ước chung [e. g. , 10 và 27 là nguyên tố tương đối, nhưng không phải là nguyên tố]. Tất nhiên, một số nguyên tố là một số nguyên tố tương đối với bất kỳ số nào khác

BÍ MẬT #7. [PSEUDO]NỀN TẢNG NGẪU NHIÊN

65

■ Áp dụng các phép quay giả ngẫu nhiên nhỏ trên ảnh trong thư viện ảnh, với nhiều. bộ chọn nth-con[an] trong đó a là số nguyên tố. ■ Tạo hoạt ảnh dường như không bao giờ lặp lại chính xác theo cùng một cách, bằng cách áp dụng nhiều hoạt ảnh với thời lượng chính. [Kiểm tra chơi. bí mật css. ví dụ về io/cicanimation. ] CHƠI. chơi. bí mật css. io/cicada-stripes Xin cảm ơn Alex Walker vì đã đưa ra một ý tưởng truyền cảm hứng cho kỹ thuật này trong “Nguyên tắc ve sầu và tại sao nó lại quan trọng đối với các nhà thiết kế web” [sitepoint. com/the-cicada-principle-and-why-it-matters-toHAT TIP

những người thiết kế web]. Eric Meyer [meyerweb. com] sau này có ý tưởng tạo ra thứ gọi là “Cicadients” [meyerweb. com/eric/ Thoughts/ 2012/06/22/cicadients], liên quan đến việc áp dụng kỹ thuật này trên ảnh nền được tạo thông qua CSS gradients. Dudley Storey cũng đã viết một bài viết rất bổ ích về khái niệm này [demosthenes. thông tin/ blog/840/Brood-X-Visualizing-The-Cicada-Principle-In-CSS]

■ Giá trị hình ảnh CSS w3. org/TR/css-images ■ Hình nền và đường viền CSS w3. org/TR/css-nền

66

CHAPTER 2. BACKGROUNDS & BORDERS

RELATED

SPECS

8

Đường viền hình ảnh liên tục Điều kiện tiên quyết Độ dốc CSS, hình ảnh đường viền cơ bản, bí mật “Nền sọc” ở trang 40, hoạt hình CSS cơ bản

Sự cố Đôi khi chúng tôi muốn áp dụng một mẫu hoặc hình ảnh không phải làm nền mà làm đường viền. Ví dụ: xem Hình 2. 57 cho phần tử có đường viền trang trí về cơ bản là hình ảnh được cắt bớt vào khu vực đường viền. Ngoài ra, chúng tôi muốn hình ảnh thay đổi kích thước để bao phủ toàn bộ khu vực đường viền bất kể kích thước của phần tử của chúng tôi. Chúng tôi sẽ cố gắng làm điều gì đó như thế này bằng CSS như thế nào?

HÌNH 2. 56 Hình ảnh nghệ thuật bằng đá của chúng tôi, được sử dụng trong suốt bí mật này

Tại thời điểm này, có thể có một giọng nói rất lớn vang lên trong đầu bạn, “hình ảnh đường viền, hình ảnh đường viền, chúng ta có thể sử dụng hình ảnh đường viền, đó không phải là vấn đề nữa. 11. ” Không nhanh như vậy, padawan trẻ. Nhớ lại cách

hình ảnh đường viền thực sự hoạt động. về cơ bản nó là chia tỷ lệ 9 lát. Bạn cắt lát

68

CHAPTER 2. BACKGROUNDS & BORDERS

hình ảnh vào chín hộp và áp dụng chúng vào các góc và các bên cho phù hợp. Hình 2. 58 cung cấp một lời nhắc trực quan về cách thức hoạt động của nó. Làm thế nào chúng ta có thể cắt hình ảnh của mình thông qua hình ảnh đường viền để tạo ví dụ trong Hình 2. 57? . Vấn đề là không có phần cụ thể nào của hình ảnh mà chúng tôi muốn trở thành

Tôi có một tác phẩm nghệ thuật bằng đá đẹp

ở các góc;

biên giới, tôi không đẹp sao?

với kích thước của phần tử và chiều rộng đường viền. Nếu bạn thử một chút, có thể bạn cũng sẽ kết luận rằng điều này là không thể với hình ảnh đường viền. Tôi có một tác phẩm nghệ thuật bằng đá đẹp

Nhưng sau đó chúng ta có thể làm gì? . một sử dụng nền với hình ảnh nghệ thuật bằng đá của chúng tôi và một có nền trắng bao phủ nó

biên giới, tôi không đẹp sao?

khu vực nội dung của chúng tôi

thịt lợn viên leberkas tri-

HTML

đầu sườn phụ xúc xích Ý thịt thăn bò viên

Tôi có một viền đá nghệ thuật đẹp,

HÌNH 2. 57

trông tôi không đẹp sao?

Hình ảnh của chúng tôi được sử dụng làm đường viền với

độ cao khác nhau

một cái gì đó có ý nghĩa { nền. url[đá-nghệ thuật. jpg]; . che; . 1em; . một cái gì đó có ý nghĩa > div { nền. trắng; . 1em;

Điều này hoạt động tốt để tạo “đường viền” như trong Hình 2. 57, nhưng nó yêu cầu một phần tử HTML bổ sung. Điều này là tối ưu. nó không chỉ trộn lẫn cách trình bày và kiểu dáng, mà việc sửa đổi HTML đơn giản không phải là một tùy chọn trong một số trường hợp nhất định. Chúng ta có thể làm điều này chỉ với một phần tử không?

BÍ MẬT #8. VIỀN HÌNH LIÊN TỤC

69

Giải pháp Nhờ vào độ dốc CSS và phần mở rộng nền được giới thiệu trong Hình nền và Đường viền Cấp 3 [w3. org/TR/css3-background], chúng ta có thể đạt được hiệu ứng chính xác tương tự chỉ với một phần tử. Ý tưởng chủ đạo là sử dụng phông nền thứ hai màu trắng tinh, bao phủ lên bức tượng đá nghệ thuật. Tuy nhiên, để hình ảnh thứ hai hiển thị qua vùng viền, chúng ta nên áp dụng các giá trị khác nhau của background-clip cho chúng. Một điều cuối cùng là chúng ta chỉ có thể có màu nền trên lớp cuối cùng, vì vậy chúng ta cần giả mạo màu trắng thông qua CSS gradient từ trắng sang trắng. Đây là cách nỗ lực đầu tiên của chúng tôi để áp dụng ý tưởng này có thể trông như thế nào

đệm. 1em; . 1em rắn bạch; . linear-gradient[white, white], url[stone-art. jpg];

HÌNH 2. 58 Sơ lược nhanh về ảnh viền

kích thước nền. che; . hộp đệm, hộp viền;

Hàng đầu. Hình ảnh cắt lát của chúng tôi; . hình ảnh đường viền

Như chúng ta có thể thấy trong Hình 2. 59, kết quả rất gần với những gì chúng tôi mong muốn,

33. kéo dài 34% url[…]; . hình ảnh đường viền. 33. 34% url[…] tròn;

nhưng có một số sự lặp lại kỳ lạ. Lý do là mặc định

nguồn gốc nền là hộp đệm và do đó, hình ảnh có kích thước

Chơi với mã tại

dựa trên hộp đệm và được đặt trên điểm 0,0 trên hộp đệm

chơi. bí mật css. io/biên giới-

Phần còn lại chỉ là sự lặp lại của ô nền đầu tiên đó. Để khắc phục điều này, chúng tôi

hình ảnh

chỉ cần đặt nguồn gốc nền thành hộp viền

đệm. 1em; . 1em rắn bạch; . linear-gradient[white, white], url[stone-art. jpg]; . che; . hộp đệm, hộp viền;

70

CHAPTER 2. BACKGROUNDS & BORDERS

nguồn gốc nền. hộp viền;

Các thuộc tính mới này cũng có sẵn trên nền tốc ký, có thể giúp chúng tôi giảm đáng kể mã của mình tại đây

padding. 1em;

Tôi có một tác phẩm nghệ thuật bằng đá đẹp

ranh giới. 1em rắn bạch;

biên giới, tôi không đẹp sao?

lai lịch. hộp đệm tuyến tính-gradient[trắng, trắng], url[stone-art. jpg] hộp viền 0 / bìa;

HÌNH 2. 59 Nỗ lực đầu tiên của chúng tôi rất gần với những gì chúng tôi muốn

CHƠI. chơi. bí mật css. io/continuity-image-borders Tất nhiên, chúng ta có thể sử dụng kỹ thuật tương tự với các mẫu dựa trên độ dốc. Ví dụ: hãy xem đoạn mã sau, mã này tạo đường viền theo chủ đề phong bì cổ điển

đệm. 1em; . 1em rắn bạch; . hộp đệm có độ dốc tuyến tính [trắng, trắng], độ dốc tuyến tính lặp lại [-45deg, đỏ 0, đỏ 12. 5%, trong suốt 0, trong suốt 25%, #58a 0, #58a 37. 5%, trong suốt 0, trong suốt 50%]

HÌNH 2. 60 Một phong bì cổ điển thực tế

0/5em 5em;

Để xem những vấn đề này trong ac-

Bạn có thể xem kết quả trong Hình 2. 61. Bạn có thể dễ dàng thay đổi chiều rộng của

TIP

các sọc thông qua kích thước nền và độ dày của đường viền thông qua

chơi. bí mật css. io/cổ điển-

tuyên bố biên giới. Không giống như ví dụ về đường viền nghệ thuật bằng đá của chúng tôi, hiệu ứng này là

phong bì-đường viền-hình ảnh và ex-

cũng có thể thực hiện được với hình ảnh đường viền

tham quan

thời kỳ có giá trị thay đổi

BÍ MẬT #8. VIỀN HÌNH LIÊN TỤC

71

đệm. 1em; . 16px trong suốt; . 16 độ dốc tuyến tính lặp lại[-45deg, đỏ 0, đỏ 1em, trong suốt 0, trong suốt 2em, #58a 0, #58a 3em, trong suốt 0, trong suốt 4em];

Tuy nhiên, cách tiếp cận hình ảnh đường viền có một số vấn đề. Đường viền của tôi gợi nhớ đến những chiếc phong bì cổ điển, thật tuyệt phải không?

■ Chúng ta cần cập nhật border-image-slice mỗi khi chúng ta thay đổi

chiều rộng đường viền và làm cho chúng khớp với nhau. ■ Vì chúng ta không thể sử dụng ems trong border-image-slice nên chúng ta bị hạn chế

HÌNH 2. 61 Đường viền “phong bì cổ điển” của chúng tôi

chỉ pixel cho độ dày đường viền. ■ Độ dày của sọc cần được mã hóa ở các vị trí dừng màu, vì vậy chúng tôi cần thực hiện bốn lần chỉnh sửa để thay đổi nó. CHƠI. chơi. bí mật css. io/vintage-envelope Một ứng dụng thú vị khác của kỹ thuật này là sử dụng nó để tạo đường viền cho đàn kiến. Đường viền của kiến ​​​​diễu hành là các đường viền có nét đứt trông giống như những con kiến ​​​​đang diễu hành [nếu bạn tưởng tượng rằng các nét đứt là kiến]. Đây là những điều cực kỳ phổ biến trong GUI; . 62]. Để tạo ra những con kiến ​​​​diễu hành, chúng ta sẽ sử dụng một biến thể của hiệu ứng “phong bì cổ điển”. Chúng tôi sẽ chuyển đổi các sọc thành màu đen và trắng, giảm

HÌNH 2. 62

chiều rộng của đường viền thành 1px [chú ý cách các sọc bây giờ chuyển thành nét đứt

Kiến diễu hành cũng được sử dụng trong

viền?], và thay đổi kích thước nền thành thứ gì đó phù hợp

Adobe Photoshop để chỉ vùng lựa chọn

Sau đó, chúng tôi tạo hoạt ảnh cho vị trí nền thành 100% để làm cho nó cuộn

@keyframes kiến ​​{ đến { vị trí nền. 100% } }. hành-kiến { đệm. 1em;

72

CHAPTER 2. BACKGROUNDS & BORDERS

ranh giới. 1px trong suốt; . hộp đệm có độ dốc tuyến tính [trắng, trắng], độ dốc tuyến tính lặp lại [-45deg, đen 0, đen 25%, trắng 0, trắng 50%] 0 /. 6 em. 6em; . kiến 12s tuyến tính vô tận;

Bạn có thể xem ảnh tĩnh của kết quả trong Hình 2. 63. Rõ ràng, điều này không chỉ hữu ích cho việc diễu hành kiến, mà còn để tạo tất cả các loại đường viền nét đứt tùy chỉnh, với các nét gạch ngang màu khác nhau và độ rộng của khoảng cách gạch ngang tùy chỉnh. Hiện tại, cách duy nhất để đạt được hiệu ứng tương tự thông qua hình ảnh đường viền là sử dụng GIF động cho nguồn hình ảnh đường viền, như được hiển thị trong

HÌNH 2. 63

chrisdanford. com/blog/2014/04/28/diễu hành-kiến-hoạt hình-

Nó không thực sự có thể hiển thị

lựa chọn-hình chữ nhật-trong-css. Khi các trình duyệt bắt đầu hỗ trợ phép nội suy độ dốc, chúng tôi cũng sẽ có thể thực hiện điều đó với độ dốc, mặc dù trong một

những con kiến ​​​​diễu hành trong một cuốn sách [một vẫn chỉ trông giống như những đường viền đứt nét];

đường lộn xộn, ƯỚT. CHƠI. chơi. bí mật css. io/diễu hành-kiến

HÌNH 2. 64

1

Cắt viền trên cùng, để bắt chước

Đây là một chú thích

chú thích truyền thống

Tuy nhiên, hình ảnh đường viền cũng có thể khá mạnh mẽ và thậm chí còn hơn thế nữa khi được sử dụng với độ dốc. Ví dụ: giả sử chúng ta muốn có đường viền trên cùng được cắt bớt, giống như đường viền thường được sử dụng trong chú thích cuối trang. Tất cả những gì cần là hình ảnh đường viền và độ dốc dọc, với độ dài cắt được mã hóa cứng. Độ rộng đường viền được kiểm soát bởi …border-width. Mã sẽ trông như thế này

BÍ MẬT #8. VIỀN HÌNH LIÊN TỤC

73

đường viền trên cùng. . 2em rắn trong suốt; . 100% 0 0 linear-gradient[90deg, currentColor 4em, transparent 0]; . 1em;

Kết quả giống như Hình 2. 64. Ngoài ra, vì chúng tôi đã chỉ định mọi thứ trong ems, nên hiệu ứng sẽ điều chỉnh theo các thay đổi về kích thước phông chữ và vì chúng tôi đã sử dụng màu hiện tại, nó cũng sẽ thích ứng với các thay đổi về màu sắc [giả sử chúng tôi muốn đường viền có cùng màu với văn bản]. CHƠI. chơi. bí mật css. io/chú thích cuối trang

■ Hình nền và đường viền CSS w3. org/TR/css-backgrounds ■ Giá trị hình ảnh CSS w3. org/TR/css-hình ảnh

74

CHAPTER 2. BACKGROUNDS & BORDERS

RELATED

SPECS

Hình dạng

3

9

Hình elip linh hoạt Điều kiện tiên quyết Cách sử dụng cơ bản của thuộc tính bán kính đường viền

Vấn đề Bạn có thể đã nhận thấy tại một số điểm rằng bất kỳ phần tử hình vuông nào có bán kính đường viền đủ lớn đều có thể biến thành hình tròn, với mã CSS giống như sau

lai lịch. #fb3; . 200px; . 200px;

HÌNH 3. 1

bán kính đường viền. 100px;

Một hình tròn, được tạo bởi các kích thước cố định và bán kính đường viền bằng một nửa

Bạn cũng có thể nhận thấy rằng bạn có thể chỉ định bất kỳ bán kính nào lớn hơn

100px và nó vẫn sẽ dẫn đến hình tròn. Lý do được nêu trong đặc điểm kỹ thuật. 76

CHƯƠNG 3. HÌNH DẠNG

“Khi tổng của hai bán kính đường viền liền kề bất kỳ vượt quá kích thước của hộp đường viền, tác nhân người dùng phải giảm tỷ lệ các giá trị được sử dụng của tất cả các bán kính đường viền cho đến khi không có bán kính nào trùng nhau. ” — Nền và đường viền CSS Cấp 3 [w3. org/TR/css3-background/#corneroverlap]

Tuy nhiên, chúng tôi thường không thể cung cấp chiều rộng và chiều cao cụ thể cho một phần tử, vì chúng tôi muốn nó điều chỉnh theo nội dung của nó, điều này có thể không được biết trước. Ngay cả khi chúng tôi đang thiết kế một trang web tĩnh và nội dung chính xác của nó đã được xác định trước, chúng tôi có thể muốn sửa đổi nó tại một số điểm hoặc nó có thể được hiển thị bằng phông chữ dự phòng với các số liệu khác nhau. Trong trường hợp đó, chúng ta thường muốn nó là hình elip khi chiều rộng và chiều cao không chính xác

HÌNH 3. 2

bằng nhau và một đường tròn khi chúng. Tuy nhiên, với mã trước đây của chúng tôi, điều đó

Ví dụ vòng kết nối trước đây của chúng tôi, khi

không phải là trường hợp. Hình dạng kết quả khi chiều rộng lớn hơn chiều cao được hiển thị trong Hình 3. 2. Chúng ta thậm chí có thể sử dụng bán kính đường viền để tạo

chiều cao nhỏ hơn chiều rộng;

hình elip, chứ đừng nói đến một hình linh hoạt?

Giải pháp Một thực tế ít được biết đến là bán kính đường viền chấp nhận các bán kính ngang và dọc khác nhau, nếu bạn sử dụng dấu gạch chéo [/] để phân tách hai. Điều này cho phép chúng ta tạo hình elip bo tròn ở các góc [Hình 3. 3]. Vì vậy, nếu chúng ta có một phần tử có kích thước 200px × 150px, chẳng hạn, chúng ta có thể biến nó thành một hình elip có bán kính bằng một nửa chiều rộng và chiều cao của nó,

HÌNH 3. 3

tương ứng

Một hộp có bán kính đường viền ngang và dọc không bằng nhau;

bán kính đường viền. 100px/75px;

góc cong bây giờ theo một hình elip có bán kính ngang và dọc bằng bán kính đường viền mà chúng tôi đã chỉ định, được hiển thị ở đây với nét đứt

Bạn có thể xem kết quả trong Hình 3. 4. Tuy nhiên, điều này có một lỗ hổng lớn. nếu kích thước thay đổi, các

dòng

giá trị bán kính đường viền cũng cần phải thay đổi. Bạn có thể xem trong hình 3. 5 bán kính đường viền trông như thế nào khi bạn có phần tử 200px × 300px thay vào đó. Khi kích thước của chúng tôi thay đổi tùy thuộc vào nội dung, chúng tôi gặp sự cố

BÍ MẬT #9. DẤU ẤN LINH HOẠT

77

Hay, phải không? . Tỷ lệ phần trăm phân giải thành kích thước, chiều rộng tương ứng cho bán kính ngang và chiều cao cho chiều dọc. Điều này có nghĩa là cùng một tỷ lệ phần trăm có thể tính theo các bán kính ngang và dọc khác nhau. Do đó, để tạo một hình elip linh hoạt, chúng ta có thể thay thế cả hai bán kính bằng 50%

HÌNH 3. 4 Đường cong có bán kính đường viền không đều dùng để tạo hình elip

bán kính đường viền. 50%/50%;

Và bởi vì các phần trước và sau dấu gạch chéo bây giờ giống nhau [mặc dù chúng không tính toán với cùng một giá trị], chúng ta có thể đơn giản hóa hơn nữa thành

bán kính đường viền. 50%;

Kết quả là một hình elip linh hoạt chỉ với một dòng CSS, bất kể chiều rộng và chiều cao. CHƠI. chơi. bí mật css. io/hình elip

HÌNH 3. 5 Hình elip của chúng ta bị vỡ khi kích thước thay đổi;

Nửa hình elip Bây giờ chúng ta đã biết cách tạo một hình elip linh hoạt bằng CSS, tự nhiên chúng ta sẽ tự hỏi liệu chúng ta có thể tạo các hình dạng phổ biến khác không, chẳng hạn như các phân số của

TRIVIA

Tại sao "bán kính biên giới"?

Nhiều người thắc mắc tại sao bán kính đường viền lại được đặt tên như vậy, vì nó không yêu cầu đường viền hoạt động. Có vẻ như bán kính góc sẽ phù hợp hơn nhiều. Lý do cho cái tên này [phải thừa nhận là khó hiểu] là do bán kính đường viền làm tròn cạnh của hộp viền của phần tử. Khi phần tử không có đường viền, điều này không có gì khác biệt, nhưng khi có, góc ngoài của đường viền sẽ được làm tròn. Độ tròn của góc bên trong nhỏ hơn [chính xác là tối đa [0, bán kính đường viền - chiều rộng đường viền]]. 78

CHƯƠNG 3. HÌNH DẠNG

một hình elip. Hãy dành một chút thời gian để suy nghĩ về một nửa hình elip [e. g. , một trong Hình 3. 6]. Nó đối xứng qua trục tung, nhưng không đối xứng qua trục ngang. Ngay cả khi chúng ta không thể biết chính xác các giá trị bán kính đường viền [hoặc nếu nó ở

Một nửa hình elip có thể trở thành hình bán nguyệt khi chiều rộng gấp đôi chiều cao [hoặc khi chiều cao gấp đôi chiều rộng, đối với hình elip cắt trục tung]

tất cả đều có thể] nhưng rõ ràng là chúng ta sẽ cần các bán kính khác nhau cho mỗi góc. Tuy nhiên, các giá trị chúng tôi đã kiểm tra cho đến nay chỉ cho phép một giá trị cho cả bốn góc. May mắn thay, cú pháp bán kính đường viền linh hoạt hơn thế. Bạn có thể ngạc nhiên khi thấy rằng bán kính đường viền thực sự là một cách viết tắt. Chúng tôi có thể cung cấp các giá trị khác nhau cho mỗi góc và có hai cách khác nhau để làm điều đó. Một cách là sử dụng các thuộc tính thủ công mà nó bao gồm

HÌNH 3. 6 Nửa hình elip

■ bán kính đường viền trên cùng bên trái ■ bán kính đường viền trên cùng bên phải ■ bán kính đường viền dưới cùng bên phải ■ bán kính đường viền dưới cùng bên trái Tuy nhiên, cách ngắn gọn hơn là sử dụng tốc ký bán kính đường viền và cung cấp nhiều . Nếu chúng tôi cung cấp bốn giá trị, thì mỗi giá trị sẽ áp dụng cho một góc, theo thứ tự theo chiều kim đồng hồ, bắt đầu từ trên cùng bên trái. Nếu chúng tôi cung cấp ít hơn bốn giá trị, chúng sẽ được nhân lên theo cách CSS thông thường, giống như các thuộc tính như độ rộng đường viền. Ba giá trị có nghĩa là giá trị thứ tư giống như giá trị thứ hai. Hai giá trị có nghĩa là giá trị thứ ba giống như giá trị thứ nhất. Hình 3. 7 cung cấp một lời giải thích trực quan về cách thức hoạt động của nó. Chúng tôi thậm chí có thể cung cấp các bán kính ngang và dọc khác nhau cho cả bốn góc, bằng cách chỉ định 1–4 giá trị trước dấu gạch chéo và 1–4 giá trị khác nhau sau dấu gạch chéo. Lưu ý rằng chúng được mở rộng thành bốn giá trị riêng lẻ. Ví dụ: giá trị bán kính đường viền là 10px / 5px 20px tương đương với

10px 10px 10px 10px / 5px 20px 5px 20px

BÍ MẬT #9. DẤU ẤN LINH HOẠT

79

HÌNH 3. 7 Làm tròn góc nào

bán kính đường viền

;

được chỉ định với bán kính đường viền là 4, 3, 2 hoặc 1 giá trị được phân tách bằng khoảng trắng [lưu ý rằng đối với bán kính hình elip, có thể có tối đa bốn đối số trước và sau dấu gạch chéo và chúng đề cập đến các góc giống nhau, liên quan đến chiều ngang

bán kính đường viền

;

bán kính đường viền

;

bán kính trước dấu gạch chéo và bán kính dọc sau dấu gạch chéo]

bán kính đường viền

;

Bây giờ chúng ta hãy kiểm tra lại vấn đề nửa hình elip với kiến ​​thức mới tìm thấy này. Có thể chỉ định các giá trị bán kính đường viền như vậy sẽ tạo ra hình dạng như thế này không? . Hãy bắt đầu bằng cách thực hiện một vài quan sát. ■ Hình dạng đối xứng theo chiều ngang, có nghĩa là cả bán kính trên cùng bên trái và trên cùng bên phải phải giống nhau; . ■ Không có cạnh ngang thẳng ở trên cùng [i. e. , toàn bộ cạnh trên cùng bị cong], nghĩa là bán kính trên cùng bên trái và trên cùng bên phải cộng lại phải có tổng bằng 100% chiều rộng của hình. ■ Từ hai quan sát trước, chúng ta có thể suy ra rằng bán kính ngang trái và phải là 50%. ■ Theo chiều dọc, có vẻ như bo tròn cho hai góc trên cùng chiếm toàn bộ chiều cao của phần tử và không có bo tròn ở các góc dưới cùng. Do đó, có vẻ như giá trị hợp lý cho phần dọc của bán kính đường viền sẽ là 100% 100% 0 0. ■ Vì góc làm tròn theo chiều dọc của các góc dưới cùng bằng 0, nên việc làm tròn theo chiều ngang của chúng không quan trọng, vì dù sao thì điều đó sẽ luôn tính bằng 0. [Bạn có thể tưởng tượng một góc không được làm tròn theo chiều dọc và làm tròn theo chiều ngang dương không? Phải, những người viết thông số kỹ thuật cũng không thể. ] Kết hợp tất cả những thứ này lại với nhau, chúng ta có thể tạo ra mã CSS cho nửa hình elip linh hoạt trong Hình 3. 6 khá dễ dàng

80

CHƯƠNG 3. HÌNH DẠNG

bán kính đường viền. 50%/100% 100% 0 0;

Thay vào đó, cũng đơn giản không kém để đưa ra các giá trị tạo ra nửa hình elip cắt trục tung, giống như giá trị được hiển thị trong Hình 3. 8

bán kính đường viền. 100% 0 0 100%/50%;

HÌNH 3. 8 Để làm bài tập, hãy thử viết mã CSS cho nửa còn lại của hình elip

Một nửa hình elip cắt trục tung

CHƠI. chơi. bí mật css. io/nửa hình elip

Hình elip một phần tư Sau khi tạo toàn bộ hình elip và một nửa hình elip, câu hỏi tự nhiên tiếp theo là liệu chúng ta có thể tạo một phần tư hình elip, giống như hình minh họa trong Hình 3. 9. Theo một quá trình suy nghĩ tương tự như trước đây, chúng ta có thể nhận thấy rằng để tạo ra

Tương tự như ví dụ về nửa hình elip, khi chiều rộng và chiều cao bằng nhau, đây sẽ là một phần tư hình tròn

một phần tư hình elip, một trong các góc cần phải có bán kính 100% theo cả chiều ngang và chiều dọc và bốn góc còn lại sẽ không được làm tròn. Bởi vì tỷ lệ phần trăm sẽ giống nhau cho cả bán kính ngang và dọc của cả bốn góc nên không cần ký hiệu gạch chéo. Mã sẽ trông như thế này

HÌNH 3. 9

bán kính đường viền. 100% 0 0 0;

Một phần tư hình elip

Thật không may, trong trường hợp bạn đang tự hỏi những phân số nào khác của el1

môi có thể với bán kính đường viền [e. g. , là thứ 8 của một hình elip có thể?

BÍ MẬT #9. DẤU ẤN LINH HOẠT

81

HÌNH 3. 10 Simurai sử dụng thành thạo biên giới-

bán kính hết cỡ để tạo đủ loại hình dạng cho các nút BonBon của mình [simurai. com/lưu trữ/nút]

CHƠI. chơi. bí mật css. io/phần tư hình elip

■ CSS Backgrounds & Borders w3. org/TR/css-backgrounds

82

CHƯƠNG 3. HÌNH DẠNG

RELATED

SPECS

10

Hình bình hành Điều kiện tiên quyết Chuyển đổi CSS cơ bản

Bài toán Hình bình hành là tập hợp nhiều hình chữ nhật. các cạnh của chúng song song nhưng các góc của chúng không nhất thiết phải thẳng [xem Hình 3. 11]. Trong thiết kế trực quan, chúng thường hữu ích để làm cho thiết kế có vẻ năng động hơn và mang lại cảm giác chuyển động [Hình 3. 12]. Hãy thử tạo một liên kết kiểu nút với kiểu đó trong CSS. bắt đầu của chúng tôi

HÌNH 3. 11

điểm sẽ là một nút phẳng đơn giản, với một số kiểu dáng đơn giản, giống như nút trong

một hình bình hành

Hình 3. 13. Sau đó, chúng ta có thể tạo hình chữ nhật lệch với một

skew[] biến đổi, như vậy. biến đổi. xiênX[-45deg];

84

CHƯƠNG 3. HÌNH DẠNG

HÌNH 3. 12 Hình bình hành trong thiết kế web [thiết kế bởi Martina Pitakova]

Tuy nhiên, điều này cũng dẫn đến việc nội dung bị lệch, xấu và không đọc được [Hình 3. 14]. Có cách nào để chỉ làm lệch hình dạng vùng chứa mà không làm lệch nội dung không?

BẤM VÀO TÔI HÌNH 3. 13 Nút của chúng tôi, trước khi bất kỳ biến đổi nào được áp dụng

Giải pháp các phần tử lồng nhau Chúng ta có thể áp dụng một biến đổi skew[] ngược lại cho nội dung, biến đổi này sẽ hủy bỏ biến đổi bên ngoài, mang lại cho chúng ta kết quả mong muốn một cách hiệu quả. Thật không may, điều đó có nghĩa là chúng tôi sẽ phải sử dụng một phần tử HTML bổ sung để bao quanh nội dung, chẳng hạn như div

Nhấp vào đây

BẤM VÀO TÔI HÌNH 3. 14 Nút bị lệch khiến văn bản khó đọc

HTML

BẤM VÀO TÔI HÌNH 3. 15 Kết quả cuối cùng

BÍ MẬT #10. HÌNH HỌC

85

!

Nếu bạn đang áp dụng hiệu ứng này cho một phần tử nằm trong dòng bằng cách khử

lỗi, đừng quên đặt thuộc tính hiển thị của nó thành thứ khác, chẳng hạn như

nút { biến đổi. xiênX[-45deg]; . nút > div { biến đổi. xiênX[45 độ];

khối hoặc khối nội tuyến, nếu không thì các phép biến đổi sẽ không được áp dụng. Tương tự với phần tử bên trong

Như bạn có thể thấy trong Hình 3. 15 nó hoạt động khá tốt, nhưng điều đó có nghĩa là chúng ta phải sử dụng thêm một phần tử HTML. Nếu các thay đổi đánh dấu không phải là một tùy chọn hoặc bạn thực sự muốn độ tinh khiết của đánh dấu, đừng lo, vì cũng có một giải pháp CSS thuần túy. CHƠI. chơi. bí mật css. io/hình bình hành

Giải pháp phần tử giả Một ý tưởng khác là sử dụng phần tử giả để áp dụng tất cả kiểu dáng cho [nền, đường viền, v.v. ], rồi biến đổi nó. Bởi vì nội dung của chúng tôi không chứa trong phần tử giả, nên nó không bị ảnh hưởng bởi quá trình chuyển đổi. Hãy thử sử dụng kỹ thuật này để tạo kiểu cho một liên kết giống như trong phần trước. Chúng tôi cần hộp phần tử giả của mình để duy trì tính linh hoạt và tự động kế thừa các kích thước của phần tử gốc, ngay cả khi chúng được xác định bởi nội dung của nó. Một cách dễ dàng để làm điều đó là áp dụng vị trí. so với cha mẹ, vị trí. tuyệt đối cho nội dung được tạo và đặt tất cả các độ lệch thành 0 để nó trải dài theo chiều ngang và chiều dọc theo kích thước của nội dung gốc. Đây là cách mã này sẽ trông

nút { vị trí. liên quan đến; . */ }. cái nút. trước { nội dung. ''; . tuyệt đối; . 0; . 0; . 0; . 0;

86

CHƯƠNG 3. HÌNH DẠNG

Tại thời điểm này, hộp được tạo ở trên nội dung và khi chúng tôi áp dụng

NHẤP VÀO ĐÂY

một số nền cho nó, nó sẽ che khuất nội dung [Hình 3. 16]. Để khắc phục điều này, chúng ta có thể áp dụng z-index. -1 cho phần tử giả, để phần tử này di chuyển bên dưới phần tử gốc của nó

HÌNH 3. 16 Phần tử giả của chúng ta hiện tại

Bây giờ đã đến lúc áp dụng các biến đổi cho nội dung trái tim của chúng tôi trên đó và tận hưởng kết quả. Mã hoàn thành sẽ trông như thế này và tạo ra chính xác

ở trên các nội dung, vì vậy áp dụng

lai lịch. #58a để nó che khuất chúng

kết quả hình ảnh tương tự như kỹ thuật trước đó

nút { vị trí. liên quan đến; . */ }. cái nút. trước { nội dung. ''; . tuyệt đối; . 0; . 0; . 0; . 0; . -1; . #58a; . nghiêng [45 độ];

Những kỹ thuật này không chỉ hữu ích cho các phép biến đổi skew[]. Chúng cũng có thể được sử dụng với bất kỳ phép biến đổi nào khác, để biến đổi hình dạng của phần tử mà không biến đổi nội dung của nó. Ví dụ: sử dụng một biến thể của kỹ thuật này với phép biến đổi rotate[] trên phần tử hình vuông sẽ dễ dàng cho chúng ta hình thoi [hình thoi]. Ngoài ra, ý tưởng sử dụng phần tử giả và định vị để tạo hộp sau đó được tạo kiểu và đặt bên dưới phần tử gốc của nó có thể được sử dụng trong một số trường hợp, cho các loại hiệu ứng rất khác nhau, chẳng hạn như. ■ Đó là một cách giải quyết chung cho nhiều nền trong IE8, được phát hiện bởi Nicolas Gallagher [nicolasgallagher. com/multiplebackgrounds-and-borders-with-css2]. ■ Đó có thể là một giải pháp khác cho các hiệu ứng như bí quyết “Làm tròn bên trong” ở trang 36. Bạn có thể đoán làm thế nào?

BÍ MẬT #10. HÌNH HỌC

87

■ Nó có thể được sử dụng để áp dụng độc lập các thuộc tính như độ mờ cho một “nền”, được tiên phong bởi Nicolas Gallagher [nicolasgallagher. com/ css-background-image-hacks]. ■ Nó có thể được sử dụng để mô phỏng nhiều đường viền một cách linh hoạt hơn, trong trường hợp chúng ta không thể sử dụng các kỹ thuật trong bí quyết “Nhiều đường viền” ở trang 28. Ví dụ: khi chúng ta cần nhiều đường viền nét đứt hoặc nhiều đường viền có khoảng cách và độ trong suốt giữa chúng. CHƠI. chơi. bí mật css. io/hình bình hành-giả

■ Chuyển đổi CSS w3. org/TR/css-transforms

88

CHƯƠNG 3. HÌNH DẠNG

RELATED

SPECS

11

Hình ảnh kim cương Điều kiện tiên quyết Chuyển đổi CSS, bí mật “Hình bình hành” ở trang 84

Sự cố Cắt hình ảnh theo hình kim cương khá phổ biến trong thiết kế trực quan, nhưng vẫn không hoàn toàn đơn giản để thực hiện trong CSS. Trên thực tế, cho đến gần đây, về cơ bản là không thể. Do đó, khi các nhà thiết kế web muốn theo phong cách này, họ thường không cắt trước hình ảnh của mình thông qua trình chỉnh sửa hình ảnh. Tất nhiên, không cần phải nói rằng đây thực sự không phải là một cách có thể duy trì để áp dụng bất kỳ hiệu ứng nào và cuối cùng sẽ trở thành một mớ hỗn độn nếu một người muốn thay đổi kiểu dáng hình ảnh trong tương lai. Chắc chắn, những ngày này phải có một cách tốt hơn, phải không?

90

CHƯƠNG 3. HÌNH DẠNG

HÌNH 3. 17 Sau khi thiết kế lại vào năm 2013, 24ways. org hiện hiển thị ảnh hồ sơ tác giả được cắt theo hình kim cương, sử dụng kỹ thuật được thảo luận tại đây

giải pháp dựa trên phép biến đổi Ý tưởng chính giống như giải pháp đầu tiên được thảo luận trong phần bí mật trước đó [bí mật “Hình bình hành” ở trang 84]—chúng ta cần bọc hình ảnh của mình bằng một dấu , sau đó áp dụng các phép biến đổi rotate[] ngược lại cho chúng

HTML

hình ảnh { chiều rộng. 400px; . xoay [45 độ];

HÌNH 3. 18

tràn ra. ẩn giấu;

hình ảnh ban đầu của chúng tôi, mà chúng tôi là

}

sẽ cắt theo hình kim cương

ảnh > img { chiều rộng tối đa. 100%; . xoay[-45deg];

BÍ MẬT #11. HÌNH ẢNH KIM CƯƠNG

91

Tuy nhiên, như bạn có thể thấy trong Hình 3. 19, điều này không hoàn toàn hiệu quả và hoàn thành những gì chúng tôi đang cố gắng đạt được. Tất nhiên, trừ khi chúng tôi đang cố gắng cắt hình ảnh theo hình bát giác, trong trường hợp đó, chúng tôi có thể dừng ngay bây giờ và làm việc khác với thời gian của mình. Tuy nhiên, để cắt nó thành hình kim cương, vẫn còn một chút mồ hôi nữa để. Vấn đề chính là chiều rộng tối đa. khai báo 100%. 100% đề cập đến phía của chúng tôi. hộp đựng tranh. Tuy nhiên, chúng tôi muốn hình ảnh của chúng tôi được

HÌNH 3. 19 Phép biến đổi rotate[] đối diện là

rộng bằng đường chéo của nó, không phải cạnh của nó. Bạn có thể đoán rằng có, chúng ta cần định lý Pythagore một lần nữa [nếu bạn cần xem lại, có

không đủ để đạt được hiệu ứng này

một trong phần “Sọc chéo” trên trang 43]. Như định lý cho biết

[. div hình ảnh được hiển thị với một

chúng ta, đường chéo của một hình vuông bằng cạnh của nó nhân với

nét đứt]

2 ≈ 1. 414213562. Do đó, nên đặt độ rộng tối đa thành 2 × 100 % ≈ 141. 4213562 % hoặc làm tròn lên tới 142%, vì chúng tôi không muốn nó nhỏ hơn trong bất kỳ trường hợp nào [nhưng lớn hơn một chút cũng không sao, vì dù sao thì chúng tôi cũng đang cắt xén hình ảnh của mình]. Trên thực tế, việc phóng to hình ảnh thông qua một

scale[] biến đổi, vì một vài lý do. ■ Chúng tôi muốn kích thước của hình ảnh giữ nguyên 100% nếu không hỗ trợ chuyển đổi CSS. ■ Phóng to hình ảnh thông qua biến đổi scale[] sẽ thu nhỏ hình ảnh từ tâm [trừ khi một nguồn gốc biến đổi khác được chỉ định]. Phóng to nó thông qua thuộc tính chiều rộng của nó sẽ thu nhỏ nó từ góc trên cùng bên trái, vì vậy chúng ta sẽ kết thúc

HÌNH 3. 20

phải sử dụng lợi nhuận âm để di chuyển nó

Hình ảnh được cắt cuối cùng của chúng tôi

Đặt tất cả lại với nhau, mã cuối cùng của chúng ta trông như thế này

hình ảnh { chiều rộng. 400px; . xoay [45 độ]; . ẩn giấu; . ảnh > img { chiều rộng tối đa. 100%; . tỷ lệ xoay [-45deg] [1. 42];

92

CHƯƠNG 3. HÌNH DẠNG

Như bạn có thể xác minh trong Hình 3. 20, điều này cuối cùng mang lại cho chúng tôi kết quả mà chúng tôi muốn. CHƠI. chơi. bí mật css. io/hình ảnh kim cương

Giải pháp cắt đường dẫn Giải pháp trước đó hoạt động, nhưng về cơ bản, đó là một cách hack. Nó yêu cầu một phần tử HTML bổ sung và nó lộn xộn, phức tạp và dễ vỡ. nếu chúng ta tình cờ xử lý các hình không vuông, nó sẽ bị vỡ rất thảm [Hình 3. 21]. Trên thực tế, có một cách tốt hơn nhiều để làm điều đó. Ý tưởng chính là sử dụng

LIMITED SUPPORT

thuộc tính clip-path, một tính năng khác được mượn từ SVG, mà ngày nay cũng có thể được áp dụng cho nội dung HTML [ít nhất là trong các trình duyệt hỗ trợ] với một cú pháp đẹp, dễ đọc, không giống như đối tác SVG của nó, được biết là đã khiến mọi người phát điên. Cảnh báo chính của nó là hỗ trợ trình duyệt hạn chế [tại thời điểm viết]. Tuy nhiên, nó xuống cấp một cách duyên dáng [không bị cắt], vì vậy, đây là một giải pháp thay thế ít nhất nên được xem xét. Bạn có thể quen với việc cắt các đường dẫn từ các ứng dụng chỉnh sửa hình ảnh như Adobe Photoshop. Đường dẫn cắt cho phép chúng tôi cắt phần tử theo hình dạng mà chúng tôi muốn. Trong trường hợp này, chúng tôi sẽ sử dụng hình dạng đa giác [] để chỉ định hình thoi, cho phép chúng tôi chỉ định bất kỳ hình dạng đa giác nào dưới dạng một chuỗi các điểm được phân tách bằng dấu phẩy. Chúng tôi thậm chí có thể sử dụng tỷ lệ phần trăm và chúng đề cập đến kích thước của phần tử. Mã đơn giản như

HÌNH 3. 21 đường dẫn clip. đa giác[50% 0, 100% 50%, 50% 100%, 0 50%];

Giải pháp dựa trên biến đổi bị hỏng nặng khi xử lý các hình ảnh không vuông

Đó là nó, tin hay không. Kết quả giống như Hình 3. 20, nhưng thay vì yêu cầu hai phần tử HTML và tám dòng mã CSS khó hiểu, giờ đây nó được tạo chỉ bằng một dòng đơn giản. Điều kỳ diệu của clip-path không dừng lại ở đây. Thuộc tính thậm chí có thể tạo hiệu ứng động, miễn là chúng ta tạo hiệu ứng động giữa các hàm hình dạng giống nhau [đa giác[], trong trường hợp của chúng ta], với cùng số điểm. Do đó, nếu chúng ta muốn khám phá toàn bộ hình ảnh một cách mượt mà khi di chuột qua, chúng ta sẽ làm như thế này

BÍ MẬT #11. HÌNH ẢNH KIM CƯƠNG

93

img { đường dẫn clip. đa giác[50% 0, 100% 50%, 50% 100%, 0 50%]; . đường dẫn clip 1 giây; . di chuột { clip-path. đa giác[0 0, 100% 0,

HÌNH 3. 22 Phương pháp clip-path điều chỉnh

100% 100%, 0 100%];

độc đáo với hình ảnh không vuông

Hơn nữa, phương pháp này điều chỉnh độc đáo cho các hình ảnh không phải hình vuông, như bạn có thể xác minh trong Hình 3. 22. Ah, niềm vui của CSS hiện đại… ▶ CHƠI. chơi. bí mật css. io/kim cương-clip

■ Chuyển đổi CSS w3. org/TR/css-transforms ■ CSS Masking w3. org/TR/css-masking ■ Chuyển tiếp CSS w3. org/TR/css-chuyển tiếp

94

CHƯƠNG 3. HÌNH DẠNG

RELATED

SPECS

12

Các góc cắt bỏ Điều kiện tiên quyết Độ dốc CSS, kích thước nền, bí mật “Nền sọc” ở trang 40

Vấn đề

Tiếp theo

Cắt góc không chỉ là một cách để tiết kiệm tiền mà còn là một phong cách khá phổ biến trong cả thiết kế in ấn và web. Nó thường liên quan đến việc cắt bỏ một hoặc nhiều góc của phần tử theo góc 45° [còn được gọi là vát góc].

HÌNH 3. 23

ners]. Đặc biệt là gần đây, với thiết kế phẳng chiến thắng chủ nghĩa đa dạng, có

Một nút với các góc bị cắt,

đã là một sự gia tăng mức độ phổ biến của hiệu ứng này. Khi cutout cor-

tạo hình mũi tên

ners chỉ ở một bên và mỗi bên chiếm 50% chiều cao của phần tử, nó

nhấn mạnh ý nghĩa của nó

tạo một hình mũi tên rất phổ biến cho các nút và điều hướng breadcrumb — xem Hình 3. 23. Tuy nhiên, CSS vẫn chưa được trang bị tốt để tạo hiệu ứng này một cách dễ dàng, đơn giản. Điều này khiến hầu hết các tác giả hướng tới việc sử dụng hình nền để đạt được nó, bằng cách che khuất các góc bị cắt bằng

96

CHƯƠNG 3. HÌNH DẠNG

hình tam giác [khi phông nền có màu đồng nhất] hoặc bằng cách sử dụng một hoặc nhiều hình ảnh cho toàn bộ phông nền, với [các] góc đã được cắt sẵn

HÌNH 3. 24 Một ví dụ về một trang web trong đó một góc bị cắt bỏ [phía dưới bên trái của hộp “Tìm & Đặt sách” bán trong suốt] thực sự bổ sung cho thiết kế

Các phương pháp như vậy rõ ràng là không linh hoạt, khó bảo trì và thêm độ trễ, cả bằng cách tăng yêu cầu HTTP và tổng kích thước tệp của trang web. Có cách nào tốt hơn?

Giải pháp Một giải pháp có dạng gradient CSS toàn năng. Giả sử chúng ta chỉ muốn một góc bị cắt, chẳng hạn góc dưới cùng bên phải. chính

tập trung nào. Bạn phải nhìn vào các góc của tôi chứ không phải

mẹo là tận dụng thực tế là độ dốc có thể chấp nhận một góc

đọc văn bản của tôi. Văn bản là

hướng [e. g. , 45deg] và các vị trí dừng màu ở độ dài tuyệt đối, cả hai

chỉ giữ chỗ

trong số đó không bị ảnh hưởng bởi những thay đổi về kích thước của phần tử

HÌNH 3. 25

nền đang bật. Đặt tất cả lại với nhau, tất cả những gì chúng ta cần là một gradient tuyến tính. Nó sẽ cần một điểm dừng màu trong suốt cho góc bị cắt và một điểm dừng màu khác

Một phần tử bị cắt góc dưới cùng bên phải, thông qua một dải màu CSS đơn giản

ở cùng một vị trí, với màu chúng tôi muốn cho nền của chúng tôi. CSS trông như thế này [đối với góc có kích thước 15px]

lai lịch. #58a; . độ dốc tuyến tính [-45deg, 15px trong suốt, #58a 0];

BÍ MẬT #12. GÓC CẮT

97

TIP

Chúng tôi đang sử dụng các màu riêng biệt [

#58a và

#655] để gỡ lỗi dễ dàng hơn. Trong

Đơn giản phải không? . 25. Về mặt kỹ thuật, chúng tôi thậm chí không cần khai báo đầu tiên. Chúng tôi chỉ bao gồm nó như một mùa thu-

thực tế, cả hai độ dốc sẽ là

trở lại. nếu độ dốc CSS không được hỗ trợ, khai báo thứ hai sẽ là

cùng màu

bị loại bỏ, vì vậy chúng tôi vẫn muốn có ít nhất một nền màu đồng nhất. Bây giờ, giả sử chúng ta muốn có hai góc bị cắt, chẳng hạn như hai góc dưới cùng. Chúng tôi không thể đạt được điều này chỉ với một gradient, vì vậy chúng tôi sẽ cần hai. Suy nghĩ đầu tiên của chúng tôi có thể là một cái gì đó như thế này

lai lịch. #58a; . độ dốc tuyến tính [-45deg, 15px trong suốt, #58a 0], độ dốc tuyến tính [45deg, 15px trong suốt, #655 0];

Tuy nhiên, như bạn có thể thấy trong Hình 3. 26, điều này không hoạt động. Theo mặc định, cả hai gradient chiếm toàn bộ phần tử, vì vậy chúng che khuất lẫn nhau. Chúng ta cần làm cho chúng nhỏ hơn, bằng cách sử dụng kích thước nền để làm cho mỗi gradient chỉ chiếm một nửa phần tử. tập trung nào. Bạn được cho là đang nhìn vào các góc của tôi, không đọc văn bản của tôi. Văn bản chỉ là trình giữ chỗ

lai lịch. #58a; . độ dốc tuyến tính [-45deg, 15px trong suốt, #58a 0] phải,

HÌNH 3. 26 Không thể áp dụng hiệu ứng cắt bỏ cho cả hai góc dưới cùng

tập trung nào. Bạn được cho là

độ dốc tuyến tính [45deg, 15px trong suốt, #655 0] trái; . 50% 100%;

Bạn có thể thấy những gì xảy ra trong Hình 3. 27. Như bạn có thể thấy, mặc dù

đọc văn bản của tôi. Văn bản là

kích thước nền đã được áp dụng, các gradient vẫn che phủ lẫn nhau. Lý do cho điều này là chúng ta quên bật lặp lại nền

chỉ giữ chỗ

tắt, vì vậy mỗi hình nền của chúng tôi được lặp lại hai lần. Vì vậy, lưng của chúng tôi-

được nhìn vào các góc của tôi, không

căn cứ vẫn đang che khuất lẫn nhau - bằng cách lặp lại lần này. Cái mới

HÌNH 3. 27 kích thước nền là không đủ

98

CHƯƠNG 3. HÌNH DẠNG

mã sẽ trông như thế này

lai lịch. #58a; . độ dốc tuyến tính[-45deg, 15px trong suốt, #58a 0] phải, độ dốc tuyến tính[45deg, 15px trong suốt, #655 0] trái; . 50% 100%; . không lặp lại;

Bạn có thể xem kết quả trong Hình 3. 28 và xác minh rằng—cuối cùng—nó hoạt động. Tại thời điểm này, có lẽ bạn có thể tìm ra cách áp dụng hiệu ứng này

tập trung nào. Bạn phải nhìn vào các góc của tôi chứ không phải

đến cả bốn góc. Bạn sẽ cần bốn độ dốc và mã trông

đọc văn bản của tôi. Văn bản là

như thế này

chỉ giữ chỗ

HÌNH 3. 28

lai lịch. #58a;

Dưới cùng bên trái và dưới cùng bên phải của chúng tôi

lai lịch. độ dốc tuyến tính [135deg,

các góc cắt hiện đang hoạt động

trong suốt 15px, #58a 0]

trên cùng bên trái, độ dốc tuyến tính [-135deg, 15px trong suốt, #655 0] Này, tập trung. Bạn được cho là

trên cùng bên phải, linear-gradient[-45deg, 15px trong suốt, #58a 0] dưới cùng bên phải,

đang nhìn vào các góc của tôi, không đọc văn bản của tôi. Văn bản chỉ là trình giữ chỗ

linear-gradient[45deg, 15px trong suốt, #655 0] phía dưới bên trái;

HÌNH 3. 29

kích thước nền. 50% 50%;

Hiệu ứng được áp dụng cho cả bốn góc,

Bối cảnh Lặp lại. không lặp lại;

với bốn độ dốc

Bạn có thể xem kết quả trong Hình 3. 29. Một vấn đề với mã trước đó là nó không thể bảo trì được. Nó yêu cầu năm lần chỉnh sửa để thay đổi màu nền và bốn lần để thay đổi kích thước góc. Mixin tiền xử lý có thể giúp giảm sự lặp lại. Đây là cách mã có thể trông như thế nào với SCSS

BÍ MẬT #12. GÓC CẮT

99

@mixin beveled-corners[$bg,

SCSS

$tl. 0, $tr. $tl, $br. $tl, $bl. $tr] { nền. $bg; . độ dốc tuyến tính [135deg, trong suốt $tl, $bg 0] trên cùng bên trái, độ dốc tuyến tính [225deg, trong suốt $tr, $bg 0] trên cùng bên phải, độ dốc tuyến tính [-45deg, trong suốt $br, $bg 0] dưới cùng . 50% 50%; . không lặp lại;

Sau đó, khi cần, nó sẽ được sử dụng như thế này, với 2–5 đối số

@include vát-góc[#58a, 15px, 5px];

SCSS

Trong ví dụ này, phần tử chúng ta sẽ nhận được góc cắt 15px trên cùng bên trái và dưới cùng bên phải và một góc trên cùng bên phải và dưới cùng bên trái 5px, tương tự như cách

bán kính đường viền hoạt động khi chúng tôi cung cấp ít hơn bốn độ dài. Điều này là do chúng tôi đã cung cấp các giá trị mặc định cho các đối số trong hỗn hợp SCSS của mình và vâng, các giá trị mặc định này cũng có thể tham chiếu đến các đối số khác. CHƠI. chơi. bí mật css. io/bevel-corners-gradients

Các góc cắt cong Một biến thể của phương pháp chuyển màu hoạt động để tạo các góc cắt cong, một hiệu ứng mà nhiều người gọi là "bán kính đường viền bên trong", vì nó trông giống như một

100

CHƯƠNG 3. HÌNH DẠNG

HÌNH 3. 30 Một cách sử dụng tuyệt vời các góc cắt cong trong g2 geogeske. com;

phiên bản nghịch đảo của các góc tròn. Sự khác biệt duy nhất là sử dụng độ dốc xuyên tâm thay vì độ dốc tuyến tính

lai lịch. #58a;

tập trung nào. Bạn được cho là

lai lịch

đang nhìn vào các góc của tôi, không đọc văn bản của tôi. Văn bản là

radial-gradient[hình tròn ở trên cùng bên trái, 15px trong suốt, #58a 0] trên cùng bên trái, radial-gradient[hình tròn ở trên cùng bên phải, 15px trong suốt, #58a 0] trên cùng bên phải, radial-gradient[hình tròn ở dưới cùng bên phải,

chỉ giữ chỗ

HÌNH 3. 31 Góc cắt cong, với độ dốc xuyên tâm

trong suốt 15px, #58a 0] dưới cùng bên phải, radial-gradient[vòng tròn ở dưới cùng bên trái, 15px trong suốt, #58a 0] dưới cùng bên trái; . 50% 50%; . không lặp lại;

Bạn có thể xem kết quả trong Hình 3. 31. Giống như trong kỹ thuật trước, kích thước góc có thể được kiểm soát thông qua các vị trí dừng màu và một mixin cũng sẽ làm cho mã dễ bảo trì hơn ở đây

BÍ MẬT #12. GÓC CẮT

101

CHƠI. chơi. bí mật css. io/scoop-corner

Giải pháp hình ảnh viền & SVG nội tuyến Mặc dù giải pháp dựa trên độ dốc hoạt động nhưng nó có một số vấn đề. ■ Đoạn mã rất dài và lặp đi lặp lại. Trong trường hợp phổ biến, khi chúng tôi muốn có cùng kích thước góc ở cả bốn góc, chúng tôi cần thực hiện bốn lần chỉnh sửa để sửa đổi nó. Tương tự, chúng ta cần thực hiện bốn lần chỉnh sửa để thay đổi màu nền, năm lần đếm dự phòng. ■ Thật là lộn xộn đến mức không thể [tùy thuộc vào trình duyệt] để tạo hoạt ảnh giữa các kích thước góc khác nhau. Rất may, có một số phương pháp khác nhau mà chúng tôi có thể sử dụng, tùy thuộc vào nhu cầu của chúng tôi. Một trong số đó là sử dụng hình ảnh đường viền với SVG nội tuyến để tạo các góc. Đưa ra cách thức hoạt động của hình ảnh đường viền [nếu bạn không nhớ, hãy xem đoạn mồi nhanh trong Hình 2. 58], bạn có thể tưởng tượng SVG của chúng ta trông như thế nào không?

HÌNH 3. 32

Bởi vì kích thước không quan trọng [hình ảnh đường viền sẽ chăm sóc da đầu-

Hình ảnh đường viền dựa trên SVG của chúng tôi, với

ing và SVG mở rộng hoàn hảo bất kể kích thước — ah, niềm vui của vector

cắt của nó

đồ họa. ], mọi phép đo có thể là 1, cho các số dễ dàng hơn, ngắn hơn. Các góc sẽ có chiều dài là 1 và các cạnh thẳng cũng sẽ là 1. Kết quả [đã phóng to] sẽ giống như Hình 3. 32. Mã sẽ trông như thế này

ranh giới. 15px trong suốt; . 1 url['dữ liệu. hình ảnh/svg+xml,\ \ \ '];

Lưu ý rằng chúng tôi đã sử dụng kích thước lát cắt là 1. Điều này không có nghĩa là 1 pixel; . Nếu chúng ta có 1

đã chỉ định nó theo tỷ lệ phần trăm, chúng tôi sẽ cần tính gần đúng 3 hình ảnh với thứ gì đó như 33. 34%. Những con số gần đúng luôn có rủi ro,

102

CHƯƠNG 3. HÌNH DẠNG

bởi vì không phải tất cả các trình duyệt đều sử dụng cùng một mức độ chính xác. Tuy nhiên, bằng cách sử dụng các đơn vị của hệ tọa độ của tệp SVG, chúng tôi đã tránh được những cơn đau đầu về độ chính xác. Kết quả được thể hiện trong Hình 3. 33. Như bạn có thể thấy, các góc cắt bỏ của chúng tôi ở đó, nhưng không có nền. Chúng ta có thể giải quyết điều đó theo hai cách. một trong hai

tập trung nào. Bạn phải nhìn vào các góc của tôi chứ không phải

bằng cách chỉ định nền hoặc bằng cách thêm từ khóa điền vào

đọc văn bản của tôi. Văn bản là

khai báo hình ảnh đường viền, để nó không loại bỏ phần giữa

chỉ giữ chỗ

lát cắt. Trong trường hợp này, chúng ta sẽ chỉ định nền, bởi vì

HÌNH 3. 33

nó cũng sẽ hoạt động như một dự phòng. Ngoài ra, bạn có thể nhận thấy rằng các góc của chúng tôi nhỏ hơn so với kỹ thuật trước đó, điều này có thể gây khó hiểu. Nhưng chúng tôi đã chỉ định một

Áp dụng SVG của chúng tôi trên đường viền-

thuộc tính hình ảnh

chiều rộng đường viền 15px. Lý do là với gradient, 15px nằm dọc theo đường gradient, vuông góc với hướng của gradient. Tuy nhiên, chiều rộng đường viền không được đo theo đường chéo mà theo chiều ngang

15px

kiểm đếm/theo chiều dọc. Bạn có thể thấy nơi này sẽ đi?

2

lại định lý pythagore mà chúng ta cũng đã thấy trong phần bí mật “Hình nền sọc” ở trang 40. Hình 3. 34 sẽ giúp mọi thứ rõ ràng hơn. Tóm lại, để đạt được cùng kích thước, chúng ta cần sử dụng chiều rộng đường viền lớn hơn 2 lần so với kích thước chúng ta sẽ sử dụng với phương pháp gradient. trong này

15px

HÌNH 3. 34 Chỉ định chiều rộng đường viền của

15px, kết quả là [theo đường chéo

trường hợp, đó sẽ là 15 × 2 ≈ 21. 213203436 pixel, hợp lý với

đo] kích thước góc của

xấp xỉ 20px, trừ khi chúng ta thực sự cần kích thước đường chéo

15 ≈ 10. 606601718, là 2

càng gần 15px càng tốt

tại sao các góc của chúng tôi trông nhỏ hơn

ranh giới. 20px trong suốt; . 1 url['dữ liệu. hình ảnh/svg+xml,\ \ \ ']; . #58a;

Tuy nhiên, như bạn có thể thấy trong Hình 3. 35, điều này không chính xác có kết quả như mong đợi. Những góc cắt được tạo ra một cách tỉ mỉ của chúng tôi đã đi đâu? . Bạn có thể hiểu

BÍ MẬT #12. GÓC CẮT

103

tập trung nào. Bạn được cho là đang nhìn vào các góc của tôi, không đọc văn bản của tôi. Văn bản chỉ là trình giữ chỗ

điều gì đang xảy ra nếu bạn đặt nền thành một màu khác, chẳng hạn như

#655. Như bạn có thể thấy trong Hình 3. 36, lý do khiến các góc của chúng tôi biến mất là do hậu cảnh mà chúng tôi chỉ định đang che khuất chúng. Tất cả những gì chúng ta cần làm để khắc phục điều này là sử dụng clip nền để ngăn nền

HÌNH 3. 35

kéo dài đến vùng biên giới

Những góc đẹp của chúng ta đã đi đâu?

ranh giới. 20px trong suốt; . Bạn được cho là đang nhìn vào các góc của tôi, không đọc văn bản của tôi. Văn bản chỉ là trình giữ chỗ

HÌNH 3. 36 Thay đổi nền của chúng ta sang một màu khác sẽ giải quyết…

hình ảnh đường viền. 1 url['dữ liệu. hình ảnh/svg+xml,\ \ \ ']; . #58a; . hộp đệm;

góc biến mất bí ẩn

Sự cố hiện đã được khắc phục và hộp của chúng tôi bây giờ trông giống hệt như Hey, focus. Bạn được cho là

Hình 3. 29. Tuy nhiên chúng ta có thể dễ dàng thay đổi kích thước góc chỉ trong một

được nhìn vào các góc của tôi, không

nơi. chúng tôi chỉ sửa đổi chiều rộng đường viền. Chúng tôi thậm chí có thể làm động nó, bởi vì

đọc văn bản của tôi. Văn bản là

chiều rộng đường viền là hoạt hình. Chúng ta cũng có thể thay đổi nền với

chỉ giữ chỗ

HÌNH 3. 37 Các góc cắt của chúng tôi với nền gradient xuyên tâm

chỉ có hai chỉnh sửa thay vì năm. Ngoài ra, vì nền của chúng ta hiện không phụ thuộc vào hiệu ứng góc, nên chúng ta thậm chí có thể chỉ định một dải màu trên nền hoặc bất kỳ mẫu nào khác, miễn là nó vẫn

#58a về phía các cạnh. Vì

ví dụ, hãy xem Hình 3. 37 để biết ví dụ sử dụng gradient xuyên tâm từ

hsla[0,0%,100%,. 2] trong suốt. Chỉ còn một vấn đề nhỏ. Nếu hình ảnh đường viền không được hỗ trợ, dự phòng không chỉ là không có góc. Do cắt nền, có vẻ như có ít khoảng cách hơn giữa cạnh hộp và nội dung của nó. Để khắc phục điều đó, chúng ta chỉ cần cung cấp cho đường viền của mình một màu giống với nền

ranh giới. 20px rắn #58a; . 1 url['dữ liệu. hình ảnh/svg+xml,\ \ \ ']; . #58a; . hộp đệm;

Màu này bị bỏ qua khi áp dụng hình ảnh đường viền, nhưng sẽ cung cấp màu dự phòng duyên dáng hơn khi không áp dụng, trông giống như Hình 3. 35. Như một nhược điểm, điều này làm tăng số lần chỉnh sửa mà chúng tôi cần thực hiện để thay đổi màu nền thành ba. CHƠI. chơi. bí mật css. io/bevel-corners Lời khuyên dành cho Martijn Saly [twitter. com/martijnsaly] vì đã đưa ra ý tưởng ban đầu về việc sử dụng SVG hình ảnh đường viền và nội tuyến như một giải pháp cho các góc vát, trong một tweet của anh ấy từ ngày 5 tháng 1 năm 2015 [twitter. com/martijnsaly/status/552152520114855936]

ĐẦU MŨ

Giải pháp cắt đường dẫn Mặc dù giải pháp hình ảnh đường viền rất nhỏ gọn và tương đối KHÔ, nhưng nó vẫn có những hạn chế. Ví dụ: chúng ta vẫn cần có nền đồng màu hoặc nền đồng màu về phía các cạnh. Điều gì sẽ xảy ra nếu chúng ta muốn một loại nền khác, chẳng hạn như kết cấu, hoa văn hoặc

LIMITED SUPPORT

một gradient tuyến tính? . Bạn có nhớ thuộc tính clip-path từ bí mật “Hình ảnh kim cương” ở trang 90 không? . Ví dụ: mã cho đường cắt để cắt một phần tử trong hình chữ nhật với các góc vát có kích thước 20px [được đo theo chiều ngang] sẽ như thế này. BÍ MẬT #12. GÓC CẮT

105

lai lịch. #58a; . đa giác[ 20px 0, calc[100% - 20px] 0, 100% 20px, 100% calc[100% - 20px], calc[100% - 20px] 100%, 20px 100%, 0 calc[100% - 20px]

Mặc dù mã ngắn nhưng điều này không có nghĩa là nó KHÔ, đây là một trong những vấn đề lớn nhất của nó nếu bạn không sử dụng bộ xử lý trước. Trên thực tế, đó là giải pháp WET nhất trong số các giải pháp CSS thuần túy mà chúng tôi đã trình bày, với tám [. ] cần chỉnh sửa để thay đổi kích thước góc. Mặt khác, chúng ta chỉ có thể thay đổi nền ở một nơi, vì vậy có. Một trong những lợi ích của nó là chúng ta có thể có bất kỳ hình nền nào chúng ta muốn,

HÌNH 3. 38

hoặc thậm chí clip thay thế các yếu tố như hình ảnh. Kiểm tra hình 3. 38

Một hình ảnh được tạo kiểu với vát

cho một hình ảnh được tạo kiểu với các góc vát. Không có phương pháp nào trước đây có thể

góc, thông qua clip-path

làm cái này. Ngoài ra, nó cũng có thể hoạt hình, không chỉ với các kích thước góc khác nhau mà cả các hình dạng khác nhau. Tất cả những gì chúng ta cần làm là sử dụng một đường cắt khác. Ngoài tính ƯỚT và hỗ trợ trình duyệt hạn chế, nó còn có nhược điểm là sẽ cắt văn bản nếu không có đủ phần đệm vì nó chỉ cắt phần tử mà không phân biệt giữa các phần của nó. Ngược lại, các

FUTURE

góc cắt

Trong tương lai, chúng ta sẽ không phải dùng đến CSS gradients, clipping hoặc SVG cho hiệu ứng này. Một tài sản mới,

hình góc, sắp có trong Hình nền và đường viền CSS cấp 4 [nhà phát triển. w3. org/csswg/cssbackgrounds-4/] để cứu chúng ta khỏi những nỗi đau này. Nó sẽ được sử dụng kết hợp với bán kính đường viền để tạo ra các góc bị cắt có hình dạng khác nhau, với kích thước của chúng được xác định trong bán kính đường viền. Ví dụ: chỉ định các góc cắt 15px trên tất cả các mặt sẽ đơn giản như. bán kính đường viền. 15px; . vát;

106

CHƯƠNG 3. HÌNH DẠNG

phương thức gradient sẽ chỉ để văn bản tràn ra ngoài các góc [vì chúng chỉ là nền] và phương thức hình ảnh đường viền sẽ hoạt động giống như một đường viền và làm cho văn bản bao bọc. CHƠI. chơi. bí mật css. io/bevel-corner-clip

■ CSS Backgrounds & Borders w3. org/TR/css-backgrounds

RELATED

SPECS

■ Giá trị hình ảnh CSS w3. org/TR/css-images ■ Chuyển đổi CSS w3. org/TR/css-transforms ■ CSS Masking w3. org/TR/css-masking ■ Chuyển tiếp CSS w3. org/TR/css-transitions ■ Nhà phát triển Nền và Đường viền CSS Cấp 4. w3. org/csswg/css-nền-4

BÍ MẬT #12. GÓC CẮT

107

13

Tab hình thang Điều kiện tiên quyết Chuyển đổi 3D cơ bản, bí mật “Hình bình hành” ở trang 84

Vấn đề

Hình thang HÌNH 3. 39 hình thang, làm giả qua

Hình thang thậm chí còn tổng quát hơn hình bình hành. chỉ có hai cạnh của chúng song song. Hai cái còn lại có thể ở bất kỳ góc độ nào. Theo truyền thống, chúng nổi tiếng là những hình dạng khó tạo trong CSS, mặc dù chúng cũng rất hữu ích, đặc biệt là đối với các tab. Khi các tác giả không được

giáp với các phần tử giả [đối với

mô phỏng chúng thông qua các hình ảnh nền được làm cẩn thận, chúng được sử dụng-

rõ ràng, các yếu tố giả là

đồng minh được tạo dưới dạng hình chữ nhật với hai hình tam giác ở mỗi bên, được làm giả thông qua

hiển thị ở đây với màu xanh đậm hơn]

viền [Hình 3. 39]. Mặc dù kỹ thuật này giúp chúng tôi tiết kiệm thêm yêu cầu HTTP mà chúng tôi sẽ dành cho một hình ảnh và có thể dễ dàng điều chỉnh theo các độ rộng khác nhau, nhưng nó vẫn chưa tối ưu. Nó lãng phí cả các phần tử giả có sẵn và cũng rất không linh hoạt về kiểu dáng. Ví dụ: chúc may mắn khi thêm đường viền, họa tiết nền hoặc một số cách làm tròn trên tab đó

108

CHƯƠNG 3. HÌNH DẠNG

HÌNH 3. 40 IDE Cloud9 [c9. io] có các tab hình thang cho mỗi tài liệu đang mở

HÌNH 3. 41 Một thiết kế lại thủ thuật css trước đó. com nổi bật với các tab hình thang, mặc dù chúng chỉ nghiêng về một hướng

Vì tất cả các kỹ thuật nổi tiếng về hình thang đều khá lộn xộn và/hoặc khó bảo trì nên hầu hết các tab chúng ta thấy trên Web đều không bị nghiêng, mặc dù các tab trong đời thực thường nghiêng. Có cách nào lành mạnh, linh hoạt để tạo các tab hình thang không?

Giải pháp Nếu tồn tại sự kết hợp của các phép biến đổi 2D có thể tạo ra một hình thang, chúng ta chỉ cần áp dụng một biến thể của các giải pháp được thảo luận trong bí mật “Hình bình hành” ở trang 84 là xong. Thật không may, không có. Tuy nhiên, hãy nghĩ về việc xoay một hình chữ nhật trong thế giới vật chất, ba chiều. Hình ảnh hai chiều mà chúng ta thường nhìn thấy là một hình thang, do phối cảnh. Rất may, chúng ta có thể mô phỏng hiệu ứng này trong CSS bằng cách sử dụng xoay 3D

BÍ MẬT #13. BẢNG HÌNH TREO

109

biến đổi. Góc nhìn cá nhân[. 5em] xoayX[5deg];

Bạn có thể thấy cách điều này tạo ra một hình thang trong Hình 3. 42. Tất nhiên, vì chúng tôi đã áp dụng biến đổi 3D cho toàn bộ phần tử của mình nên văn bản cũng bị biến dạng. Các phép biến đổi 3D không thể bị “hủy bỏ” bên trong phần tử giống như cách các phép biến đổi 2D có thể [i. e. , thông qua một phép biến đổi ngược lại]. Hủy bỏ chúng trên phần tử bên trong là có thể về mặt kỹ thuật, nhưng rất phức tạp. Do đó, cách thực dụng duy nhất để tận dụng các phép biến đổi 3D để tạo ra hình thang là áp dụng phép biến đổi đó cho một phần tử giả, giống như cách tiếp cận được thực hiện cho hình bình hành trong bí mật “Hình bình hành” ở trang 84

tab { vị trí. liên quan đến; . chặn Nội tuyến; . . 5em 1em. 35em;

HÌNH 3. 42 Tạo hình thang thông qua xoay 3D Trên cùng. Trước Đáy. Sau đó

màu. trắng; . chuyển hướng. trước { nội dung. ''; . tuyệt đối; . 0; . 0; . 0; . 0; . -1;

HÌNH 3. 43 Áp dụng biến đổi 3D cho

lai lịch. #58a;

hộp được tạo bởi giả

biến đổi. Góc nhìn cá nhân[. 5em] xoayX[5deg];

yếu tố, để văn bản của chúng tôi không bị ảnh hưởng

}

Như bạn có thể thấy trong Hình 3. 43, cái này hoạt động để tạo một hình thang cơ bản. Vẫn còn một vấn đề, mặc dù. Khi chúng ta áp dụng một phép biến đổi mà không đặt gốc biến đổi, phần tử sẽ được xoay trong không gian xung quanh tâm của nó. Do đó, kích thước của nó trên hình chiếu 2D trong màn hình của chúng tôi thay đổi theo nhiều cách, như Hình 3. 44 điểm nổi bật. chiều rộng của nó tăng lên, nó dịch chuyển một chút

110

CHƯƠNG 3. HÌNH DẠNG

lên trên cùng, chiều cao của nó giảm đi một chút, v.v., điều này gây khó khăn cho việc thiết kế xung quanh. Để làm cho số liệu của nó dễ quản lý hơn một chút, chúng tôi có thể chỉ định

HÌNH 3. 44

biến đổi nguồn gốc. đáy;

Hình thang của chúng tôi chồng lên trên trước của nó

quay trong không gian. Bạn có thể thấy sự khác biệt trong hình 3. 45. Bây giờ thì nhiều

biến đổi phiên bản, để làm nổi bật

dễ đoán hơn. chỉ có chiều cao của nó giảm. Tuy nhiên, chiều cao giảm

thay đổi số liệu của nó đi qua

sắc nét hơn nhiều, bởi vì toàn bộ phần tử xoay ra khỏi người xem, trong khi trước đây, một nửa phần tử xoay “phía sau” màn hình và nửa còn lại ở trên màn hình, vì vậy toàn bộ phần tử gần người xem hơn trong không gian ba chiều. Để khắc phục điều này, chúng tôi có thể nghĩ đến việc áp dụng thêm một số phần đệm trên cùng. Tuy nhiên, kết quả sau đó sẽ trông rất tệ trong các trình duyệt không có 3D

HÌNH 3. 45 Hình thang của chúng tôi được phủ lên trên phiên bản chuyển đổi trước của nó, để làm nổi bật

hỗ trợ chuyển đổi [Hình 3. 46]. Thay vào đó, chúng tôi sẽ tăng kích thước của nó thông qua một

thay đổi số liệu của nó đi qua khi

cũng biến đổi, để toàn bộ nội dung bị loại bỏ khi biến đổi 3D

sử dụng nguồn gốc biến đổi. đáy;

không được hỗ trợ. Với một thử nghiệm nhỏ, chúng tôi thấy rằng một số tỷ lệ dọc [i. e. , biến đổi scaleY[]] khoảng 130% là đủ để bù cho không gian bị mất

biến đổi. tỷ lệY[1. 3] quan điểm [. 5em] xoayX[5deg]; . đáy;

HÌNH 3. 46 Bạn có thể thấy cả kết quả và dự phòng trong Hình 3. 47. Tại thời điểm này, kết quả trực quan tương đương với kỹ thuật dựa trên đường viền cũ đã thảo luận

Khắc phục sự cố với phần đệm bổ sung dẫn đến dự phòng trông rất kỳ lạ [hiển thị ở trên cùng]

sớm hơn; . Tuy nhiên, tính ưu việt của kỹ thuật này bắt đầu xuất hiện khi bạn bắt đầu áp dụng một số kiểu dáng cho các tab. Ví dụ, hãy xem đoạn mã sau, được sử dụng để tạo kiểu cho các tab trong Hình 3. 48

điều hướng > một vị trí {. liên quan đến; . chặn Nội tuyến; . . 3em 1em 0;

HÌNH 3. 47 Bù lại chiều cao bị mất bằng

scale[] cung cấp dự phòng tốt hơn nhiều [hiển thị ở trên cùng]

BÍ MẬT #13. BẢNG HÌNH TREO

111

điều hướng > một. trước { nội dung. ''; . tuyệt đối; . 0; . 0; . 0; . 0; . -1; . #ccc; . độ dốc tuyến tính [ hsla[0,0%,100%,. 6], hsla[0,0%,100%,0]]; . rgba rắn 1px[0,0,0,. 4]; . không ai; . . 5 em. 5em 0 0; . 0. 15em ruột trắng; . Góc nhìn cá nhân[. 5em] xoayX[5deg]; . đáy;

Như bạn có thể thấy, chúng tôi đã áp dụng hình nền, đường viền, góc bo tròn và bóng hộp—và chúng hoạt động bình thường, không có câu hỏi nào. Hơn nữa, chỉ bằng cách thay đổi gốc biến đổi thành dưới cùng bên trái hoặc dưới cùng

phải, chúng ta có thể nhận được các tab nghiêng trái hoặc phải tương ứng. [Ví dụ, xem Hình 3. 49. ]

HÌNH 3. 48 Ưu điểm của kỹ thuật này là tính linh hoạt về kiểu dáng

112

CHƯƠNG 3. HÌNH DẠNG

HÌNH 3. 49 Các tab nghiêng bằng cách thay đổi

biến đổi nguồn gốc

Bất chấp tất cả những ưu điểm của nó, kỹ thuật này không phải là hoàn hảo. Nó liên quan đến một nhược điểm khá lớn. góc của các cạnh phụ thuộc vào chiều rộng của phần tử. Do đó, thật khó để có được các hình thang có cùng góc khi xử lý nội dung thay đổi. Tuy nhiên, cách này hiệu quả đối với các yếu tố liên quan đến các biến thể chiều rộng nhỏ, chẳng hạn như menu điều hướng. Trong những trường hợp đó, sự khác biệt hầu như không đáng chú ý. CHƠI. chơi. bí mật css. io/tab hình thang

■ Chuyển đổi CSS w3. org/TR/css-transforms

RELATED

SPECS

BÍ MẬT #13. BẢNG HÌNH TREO

113

14

Biểu đồ hình tròn đơn giản Điều kiện tiên quyết Độ dốc CSS, SVG cơ bản, hoạt ảnh CSS, bí mật “Nền sọc” ở trang 40, bí mật “Hình elip linh hoạt” ở trang 76

Vấn đề Biểu đồ hình tròn, ngay cả ở dạng hai màu đơn giản nhất của chúng, theo truyền thống không dễ tạo bằng công nghệ web, mặc dù cực kỳ phổ biến đối với những thứ từ số liệu thống kê đơn giản đến chỉ số tiến trình và bộ hẹn giờ. Việc triển khai thường liên quan đến việc sử dụng trình chỉnh sửa hình ảnh bên ngoài để tạo nhiều hình ảnh cho nhiều giá trị của biểu đồ hình tròn hoặc khung JavaScript lớn được thiết kế cho các biểu đồ phức tạp hơn nhiều. Mặc dù kỳ tích không phải là không thể như trước đây, nhưng vẫn không có một lớp lót đơn giản nào cho nó. Tuy nhiên, có nhiều cách tốt hơn, dễ bảo trì hơn để đạt được điều đó ngày nay

114

CHƯƠNG 3. HÌNH DẠNG

giải pháp dựa trên biến đổi Giải pháp này là tốt nhất về đánh dấu. nó chỉ cần một phần tử và phần còn lại được thực hiện với các phần tử giả, biến đổi và độ dốc CSS. Hãy bắt đầu với một yếu tố đơn giản. HTML

Hiện tại, giả sử chúng ta muốn có một biểu đồ hình tròn hiển thị tỷ lệ phần trăm được mã hóa cứng là 20%. Chúng tôi sẽ làm việc để làm cho nó linh hoạt sau. Trước tiên, hãy tạo kiểu cho phần tử dưới dạng hình tròn, đây sẽ là hình nền của chúng ta [Hình 3. 50]

bánh { chiều rộng. 100px; . 100px; . 50%;

HÌNH 3. 50

lai lịch. vàng lục;

Điểm xuất phát của chúng tôi [hoặc, biểu đồ hình tròn hiển thị 0%]

}

Biểu đồ hình tròn của chúng ta sẽ có màu xanh lục [cụ thể là [

vàng xanh] với màu nâu

#655] hiển thị tỷ lệ phần trăm. Chúng ta có thể bị cám dỗ để sử dụng skew

biến đổi phần trăm, nhưng như một thử nghiệm nhỏ cho thấy, chúng tỏ ra là một giải pháp rất lộn xộn. Thay vào đó, chúng tôi sẽ tô màu phần bên trái và bên phải của vòng tròn bằng hai màu của chúng tôi và sử dụng phần tử giả xoay để chỉ khám phá phần trăm chúng tôi cần. Để tô màu phần bên phải của hình tròn màu nâu, chúng ta sẽ sử dụng một gradient tuyến tính đơn giản

hình nền. linear-gradient[sang phải, trong suốt 50%, #655 0];

Như bạn có thể thấy trong Hình 3. 51, đây là tất cả những gì cần thiết. Bây giờ, chúng ta có thể tiến hành tạo kiểu cho phần tử giả sẽ hoạt động như một mặt nạ. BÍ MẬT #14. BẢNG BIỂU ĐỒ ĐƠN GIẢN

115

bánh. trước { nội dung. ''; . chặn; . 50%; . 100%;

HÌNH 3. 51

}

Tô màu phần bên phải của hình tròn màu nâu, với một gradient tuyến tính đơn giản

Bạn có thể xem trong hình 3. 52 trong đó phần tử giả của chúng ta hiện nằm so với phần tử hình tròn. Hiện tại, nó không được tạo kiểu và nó không bao gồm bất cứ thứ gì. Nó chỉ đơn thuần là một hình chữ nhật vô hình. Để bắt đầu tạo kiểu cho nó, hãy thực hiện một vài quan sát. ■ Vì chúng ta muốn nó bao phủ phần màu nâu của hình tròn nên chúng ta cần áp dụng nền màu xanh lục cho nó, sử dụng background-color. kế thừa để tránh trùng lặp, vì chúng tôi muốn nó có cùng màu nền với màu nền của nó

HÌNH 3. 52 Phần tử giả sẽ hoạt động như một mặt nạ được hiển thị ở đây với các đường đứt nét

cha mẹ. ■ Chúng ta muốn nó xoay quanh tâm của vòng tròn, nằm ở giữa cạnh trái của phần tử giả, vì vậy chúng ta nên áp dụng một phép biến đổi-

nguồn gốc của 0 50% với nó, hoặc chỉ còn lại

!

Cẩn thận không sử dụng

lai lịch. kế thừa;, thay vì màu nền. kế thừa;, nếu không thì độ dốc cũng sẽ được kế thừa

■ Chúng tôi không muốn nó là một hình chữ nhật, vì nó làm cho nó tràn ra ngoài các cạnh của biểu đồ hình tròn, vì vậy chúng tôi cần áp dụng tràn. ẩn để. bánh hoặc bán kính đường viền thích hợp để biến nó thành hình bán nguyệt. Đặt tất cả lại với nhau, CSS của phần tử giả của chúng ta sẽ trông như thế này

bánh. trước { nội dung. ''; . chặn; . 50%; . 100%; . 0 100% 100% 0 / 50%; . thừa kế; . trái;

116

CHƯƠNG 3. HÌNH DẠNG

Chiếc bánh của chúng ta hiện có dạng như Hình 3. 54. Đây là nơi vui vẻ bắt đầu. Chúng ta có thể bắt đầu xoay phần tử giả bằng cách áp dụng biến đổi rotate[]. Đối với 20% chúng tôi đang cố gắng đạt được, chúng tôi có thể sử dụng giá trị

72 độ [0. 2 × 360 = 72] hoặc. 2turn, dễ đọc hơn nhiều. Bạn cũng có thể thấy nó trông như thế nào đối với một vài giá trị khác, trong Hình 3. 53. Chúng ta có thể bị cám dỗ để nghĩ rằng chúng ta đã hoàn thành, nhưng thật không may, nó không đơn giản như vậy. Biểu đồ hình tròn của chúng tôi hoạt động tốt khi hiển thị tỷ lệ phần trăm từ 0 đến 50%, nhưng nếu chúng tôi cố gắng mô tả tỷ lệ phần trăm 60% [bằng cách áp dụng. 6 vòng quay], Hình 3. 55 xảy ra. Tuy nhiên, đừng mất hy vọng vì chúng tôi có thể — và chúng tôi sẽ — khắc phục điều này. Nếu chúng tôi nghĩ về tỷ lệ phần trăm 50%–100% là một vấn đề riêng biệt, chúng tôi có thể nhận thấy rằng chúng tôi có thể sử dụng phiên bản đảo ngược của giải pháp trước đó cho chúng. một phần tử giả màu nâu, quay từ 0 đến. lần lượt là 5. Vì vậy, đối với chiếc bánh 60%, mã phần tử giả sẽ trông như thế này

bánh. trước { nội dung. ''; . chặn; . 50%; . 100%; . 0 100% 100% 0 / 50%; . #655;

HÌNH 3. 53

biến đổi nguồn gốc. trái;

Biểu đồ hình tròn đơn giản của chúng tôi hiển thị

biến đổi. quay[. 1 lượt];

tỷ lệ phần trăm khác nhau; . 10% [36 độ hoặc. 1 lượt],

}

20% [72deg hoặc. 2 lượt], 40% [144 độ hoặc. 4 lượt]

Bạn có thể thấy điều này đang hoạt động trong Hình 3. 56. Bởi vì chúng tôi hiện đã tìm ra cách để mô tả bất kỳ tỷ lệ phần trăm nào, chúng tôi thậm chí có thể tạo hiệu ứng động cho biểu đồ hình tròn từ 0% đến 100% bằng hoạt ảnh CSS, tạo ra một chỉ báo tiến độ lạ mắt

@keyframes quay { thành { biến đổi. quay[. 5 lượt];

BÍ MẬT #14. BẢNG BIỂU ĐỒ ĐƠN GIẢN

117

@keyframes bg { 50% { nền. #655; . bánh. trước {

HÌNH 3. 54

Nội dung. '';

Phần tử giả của chúng tôi [hiển thị ở đây

trưng bày. chặn;

với một phác thảo nét đứt] sau khi chúng tôi

lề trái. 50%;

tạo kiểu xong rồi

Chiều cao. 100%; . 0 100% 100% 0 / 50%; . thừa kế; . trái; . quay vô hạn tuyến tính 3s, vô hạn bg 6s bước cuối;

HÌNH 3. 55 Biểu đồ hình tròn của chúng tôi phá vỡ tỷ lệ phần trăm lớn hơn 50% [hiển thị ở đây

CHƠI. chơi. bí mật css. io/pie-hoạt hình

60%]

Tất cả những điều này đều tốt, nhưng làm cách nào để tạo kiểu cho nhiều biểu đồ hình tròn tĩnh với các tỷ lệ phần trăm khác nhau, đây là trường hợp sử dụng phổ biến nhất?

20%

HTML

60%

và nhận hai biểu đồ hình tròn, một biểu đồ hiển thị 20% và biểu đồ còn lại hiển thị 60%. Đầu tiên, chúng ta sẽ khám phá cách chúng ta có thể làm điều đó với các kiểu nội tuyến, sau đó

HÌNH 3. 56

chúng tôi luôn có thể viết một đoạn mã ngắn để phân tích nội dung văn bản và thêm vào

Chiếc bánh 60% chính xác hiện tại của chúng tôi

kiểu nội tuyến, để tạo sự sang trọng cho mã, tính đóng gói, khả năng bảo trì và có lẽ quan trọng nhất là khả năng truy cập. Thách thức đối với việc kiểm soát tỷ lệ phần trăm biểu đồ hình tròn với các kiểu nội tuyến là mã CSS chịu trách nhiệm đặt tỷ lệ phần trăm được đặt trên phần tử giả. Như bạn đã biết, chúng tôi không thể đặt kiểu nội tuyến trên các phần tử giả, vì vậy chúng tôi cần sáng tạo

118

CHƯƠNG 3. HÌNH DẠNG

Giải pháp đến từ một trong những nơi khó xảy ra nhất. Chúng tôi sẽ sử dụng hình ảnh động mà chúng tôi đã trình bày, nhưng nó sẽ

TIP

Bạn có thể sử dụng kỹ thuật tương tự cho các trường hợp khác

nơi bạn muốn sử dụng các giá trị từ

tạm dừng. Thay vì chạy nó như một hoạt hình bình thường, chúng ta sẽ sử dụng

một quang phổ không có sự lặp lại và

hoạt hình tiêu cực chậm trễ để chuyển qua bất kỳ điểm nào trong ani-

tính toán phức tạp, cũng như cho

mation tĩnh và ở đó. Bối rối?

thông số kỹ thuật không chỉ cho phép độ trễ mà còn rất hữu ích cho các trường hợp

gỡ lỗi hoạt hình bằng cách bước qua chúng. Để biết một ví dụ đơn giản, riêng biệt về kỹ thuật này, hãy xem play. bí mật css. io/

như thế này

nội suy tĩnh

“Một sự chậm trễ tiêu cực là hợp lệ. Tương tự như độ trễ bằng 0, điều đó có nghĩa là hoạt ảnh thực thi ngay lập tức, nhưng được tự động tiến triển theo giá trị tuyệt đối của độ trễ, như thể hoạt ảnh đã bắt đầu vào thời điểm đã chỉ định trong quá khứ và do đó, nó dường như bắt đầu giữa chừng trong quá trình hoạt động của nó. . ” — Ảnh động CSS Cấp 1 [w3. org/TR/css-animations/#animation-delay]

Vì hoạt ảnh của chúng tôi bị tạm dừng, khung hình đầu tiên của nó [được xác định bởi độ trễ hoạt ảnh âm của chúng tôi], sẽ là khung hình duy nhất được hiển thị. Tỷ lệ phần trăm được hiển thị trên biểu đồ hình tròn sẽ là tỷ lệ phần trăm của tổng thời lượng độ trễ hoạt ảnh của chúng tôi là. Ví dụ: với thời lượng hiện tại là 6 giây, chúng ta sẽ cần độ trễ hoạt hình là -1. 2 giây để hiển thị tỷ lệ phần trăm 20%. Để đơn giản hóa phép toán, chúng tôi sẽ đặt thời lượng là 100 giây. Hãy nhớ rằng vì hoạt ảnh bị tạm dừng vĩnh viễn nên thời lượng chúng tôi chỉ định không có tác dụng nào khác. Có một vấn đề cuối cùng. hoạt hình nằm trên phần tử giả, nhưng chúng tôi muốn đặt kiểu nội tuyến trên. yếu tố bánh. Tuy nhiên, vì không có hoạt ảnh trên , chúng tôi có thể đặt độ trễ hoạt ảnh trên đó làm kiểu nội tuyến, sau đó sử dụng độ trễ hoạt ảnh. thừa kế; . Tóm lại, phần đánh dấu của chúng ta cho biểu đồ hình tròn 20% và 60% sẽ như thế này

BÍ MẬT #14. BẢNG BIỂU ĐỒ ĐƠN GIẢN

119

Và mã CSS mà chúng ta vừa trình bày cho hoạt ảnh này giờ đây sẽ trở thành [không bao gồm. quy tắc hình tròn, vì nó vẫn giữ nguyên]

@keyframes quay { thành { biến đổi. quay[. 5 lượt];

20%

50% { nền. #655; . bánh. trước { /* [Phần còn lại của kiểu dáng giữ nguyên] */ hoạt ảnh. quay vô hạn tuyến tính 50 giây, vô hạn bg 100 giây ở cuối;

60%

hoạt hình-phát-trạng thái. tạm dừng;

HÌNH 3. 57 Văn bản của chúng tôi, trước khi chúng tôi ẩn nó

chậm trễ hoạt hình. thừa kế;

Tại thời điểm này, chúng tôi có thể chuyển đổi đánh dấu để sử dụng tỷ lệ phần trăm làm nội dung, giống như mục tiêu ban đầu của chúng tôi và thêm các kiểu nội tuyến trì hoãn hoạt ảnh thông qua một tập lệnh đơn giản

$$['. bánh']. forEach[function[pie] {

JS

var p = parseFloat[bánh. textContent]; . Phong cách. animationDelay = '-' + p + 's';

Lưu ý rằng chúng tôi đã để nguyên văn bản vì chúng tôi cần nó vì lý do khả năng truy cập và khả năng sử dụng. Hiện tại, các biểu đồ hình tròn của chúng ta trông giống như Hình 3. 57. Chúng tôi cần ẩn văn bản mà chúng tôi có thể truy cập thông qua màu sắc. trong suốt, để nó vẫn có thể lựa chọn và in được. Để đánh bóng thêm, chúng tôi có thể căn giữa tỷ lệ phần trăm trong biểu đồ hình tròn để tỷ lệ phần trăm không nằm ở vị trí ngẫu nhiên khi người dùng chọn. Để làm được điều đó, chúng ta cần phải

120

CHƯƠNG 3. HÌNH DẠNG

■ Chuyển đổi chiều cao của chiếc bánh thành chiều cao dòng [hoặc thêm chiều cao dòng bằng với chiều cao, nhưng đó là sự trùng lặp mã vô nghĩa, bởi vì dòng-

height cũng sẽ đặt chiều cao được tính theo đó]. ■ Kích thước và định vị phần tử giả thông qua định vị tuyệt đối để nó không đẩy văn bản xuống ■ Thêm căn chỉnh văn bản. trung tâm; . Mã cuối cùng trông như thế này

chiếc bánh {vị trí. liên quan đến; . 100px; . 100px; . 50%; . vàng lục; . linear-gradient[sang phải, trong suốt 50%, #655 0]; . trong suốt; . trung tâm; . quay[. 5 lượt]; . #655; . bánh. trước { nội dung. ''; . tuyệt đối; . 0; . 50%; . 50%; . 100%; . 0 100% 100% 0 / 50%; . thừa kế;

BÍ MẬT #14. BẢNG BIỂU ĐỒ ĐƠN GIẢN

121

biến đổi nguồn gốc. trái; . quay vô hạn tuyến tính 50 giây, vô hạn bg 100 giây ở cuối; . tạm dừng; . thừa kế;

CHƠI. chơi. bí mật css. io/bánh-tĩnh

Giải pháp SVG SVG giúp nhiều tác vụ đồ họa trở nên dễ dàng hơn và biểu đồ hình tròn cũng không ngoại lệ. Tuy nhiên, thay vì tạo một biểu đồ hình tròn với các đường dẫn, thứ sẽ yêu cầu phép toán phức tạp, thay vào đó, chúng ta sẽ sử dụng một mẹo nhỏ. Hãy bắt đầu từ một vòng tròn

HÌNH 3. 58

điểm xuất phát của chúng tôi. một vòng tròn SVG màu xanh lá cây

với một chất béo

#655 đột quỵ

SVG

Bây giờ, hãy áp dụng một số kiểu dáng cơ bản cho nó. Như bạn có thể biết, các thuộc tính CSS này cũng có sẵn dưới dạng

khoanh tròn {

thuộc tính trên phần tử SVG,

lấp đầy. vàng lục;

có thể thuận tiện nếu porta-

Cú đánh. #655;

khả năng là một mối quan tâm

Chiều rộng đột quỵ. 30;

Bạn có thể thấy vòng tròn được vuốt của chúng tôi trong Hình 3. 58. Nét SVG không chỉ bao gồm các thuộc tính nét và chiều rộng nét. Có nhiều thuộc tính liên quan đến nét vẽ ít phổ biến hơn để tinh chỉnh nét vẽ. Một trong

122

CHƯƠNG 3. HÌNH DẠNG

chúng là nét gạch ngang, dùng để tạo nét đứt. Ví dụ, chúng ta có thể sử dụng nó như thế này

đột quỵ-dasharray. 20 10;

Điều này có nghĩa là chúng tôi muốn các dấu gạch ngang có độ dài 20 với các khoảng trống có độ dài 10, giống như trong Hình 3. 59. Tại thời điểm này, bạn có thể đã bắt đầu tự hỏi những gì

HÌNH 3. 59 Một nét đứt đơn giản, được tạo bằng

đột quỵ-dasharray

trên Trái đất, đoạn mồi nét vẽ SVG này có liên quan đến biểu đồ hình tròn. Nó bắt đầu trở nên rõ ràng hơn khi chúng ta áp dụng một nét có chiều rộng dấu gạch ngang bằng 0 và chiều rộng khoảng cách lớn hơn hoặc bằng chu vi của hình tròn của chúng ta [C = 2πr, vì vậy trong trường hợp của chúng ta là C = 2π × 30 ≈ 189]

đột quỵ-dasharray. 0 189;

HÌNH 3. 60 Nhiều giá trị nét-dấu gạch ngang và tác dụng của chúng;

0 189 40 189 95 189 150 189

Như bạn có thể thấy trong vòng tròn đầu tiên trong Hình 3. 60, thao tác này loại bỏ hoàn toàn mọi nét vẽ và chúng ta chỉ còn lại một hình tròn màu lục. Tuy nhiên, niềm vui bắt đầu khi chúng ta bắt đầu tăng giá trị đầu tiên [Hình 3. 60]. bởi vì khoảng cách quá dài, chúng ta không còn nét đứt nữa, chỉ là nét bao phủ phần trăm chu vi của hình tròn mà chúng ta chỉ định. Bạn có thể đã bắt đầu tìm ra nơi này sẽ đi. nếu chúng ta giảm bán kính vòng tròn của mình đủ để nó được bao phủ hoàn toàn bởi

HÌNH 3. 61

đột quỵ, chúng tôi kết thúc với một cái gì đó tương tự như một biểu đồ hình tròn

Đồ họa SVG của chúng tôi đang bắt đầu

Ví dụ, bạn có thể thấy trong hình 3. 61 nó trông như thế nào khi được áp dụng cho một

giống biểu đồ hình tròn

hình tròn có bán kính 25 và chiều rộng nét vẽ là 50, giống như nội dung được tạo bởi đoạn mã sau

BÍ MẬT #14. BẢNG BIỂU ĐỒ ĐƠN GIẢN

123

Nhớ. Các nét SVG luôn ở một nửa bên trong và một nửa bên ngoài phần tử

đề cập đến chúng được áp dụng cho. Trong tương lai, chúng tôi sẽ có thể kiểm soát hành vi này

SVG

vòng tròn { điền. vàng lục; . #655; . 50; . 60 158;

Bây giờ, biến nó thành một biểu đồ hình tròn giống như biểu đồ mà chúng ta đã thực hiện trong giải pháp trước đó khá dễ dàng. chúng ta chỉ cần thêm một vòng tròn màu xanh lục lớn hơn bên dưới nét vẽ và xoay nó 90° ngược chiều kim đồng hồ để nó bắt đầu từ giữa trên cùng. Bởi vì phần tử này cũng là một phần tử HTML, nên chúng ta chỉ có thể tạo kiểu cho phần tử đó

svg { biến đổi. xoay[-90deg]; . vàng lục; . 50%;

HÌNH 3. 62

}

Biểu đồ hình tròn SVG cuối cùng

Bạn có thể xem kết quả cuối cùng trong Hình 3. 62. Kỹ thuật này giúp tạo hiệu ứng động cho biểu đồ hình tròn từ 0% đến 100% thậm chí còn dễ dàng hơn. Chúng ta chỉ cần tạo một hoạt ảnh CSS để tạo hoạt ảnh cho nét vẽ-dasharray từ 0 158 đến 158

158. @keyframes fillup { thành { stroke-dasharray. 158 158;

124

CHƯƠNG 3. HÌNH DẠNG

vòng tròn { điền. vàng lục; . #655; . 50; . 0 158; . lấp đầy 5s tuyến tính vô hạn;

Là một cải tiến bổ sung, chúng tôi có thể chỉ định một bán kính nhất định trên hình tròn sao cho độ dài chu vi của nó là [gần vô hạn] 100, để chúng tôi có thể chỉ định độ dài nét gạch ngang dưới dạng phần trăm mà không cần phải tính toán. Vì chu vi là 2πr nên bán kính của chúng ta cần là

100 2π

≈ 15. 915494309, mà đối với nhu cầu của chúng tôi có thể là

làm tròn đến 16. Chúng tôi cũng sẽ chỉ định kích thước của SVG trong thuộc tính viewBox thay vì thuộc tính chiều rộng và chiều cao, để làm cho nó điều chỉnh theo kích thước của vùng chứa của nó. Sau những sửa đổi này, đánh dấu cho biểu đồ hình tròn của Hình 3. 62 bây giờ sẽ trở thành

SVG

Và CSS sẽ trở thành

svg { chiều rộng. 100px; . 100px; . xoay[-90deg]; . vàng lục; . 50%;

BÍ MẬT #14. BẢNG BIỂU ĐỒ ĐƠN GIẢN

125

lấp đầy. vàng lục; . #655; . 32; . 38 100;

Lưu ý bây giờ việc thay đổi tỷ lệ phần trăm dễ dàng như thế nào. Tất nhiên, ngay cả với sự đơn giản hóa này, chúng tôi không muốn phải lặp lại tất cả đánh dấu SVG này cho mọi biểu đồ hình tròn. Đã đến lúc JavaScript giúp chúng ta một chút tự động hóa. Chúng tôi sẽ viết một tập lệnh nhỏ để đánh dấu HTML đơn giản như sau…

20%

HTML

60%

…và thêm một SVG nội tuyến bên trong mỗi. phần tử hình tròn, với tất cả các phần tử và thuộc tính cần thiết. Nó cũng sẽ thêm một phần tử, dành cho khả năng truy cập, để người dùng trình đọc màn hình cũng có thể biết tỷ lệ phần trăm được hiển thị. Kịch bản cuối cùng sẽ trông như thế này

$$['. bánh']. forEach[function[pie] {

JS

var p = parseFloat[bánh. textContent]; . //www. w3. org/2000/svg"; var svg = tài liệu. createElementNS[NS, "svg"]; . createElementNS[NS, "vòng tròn"]; . createElementNS[NS, "tiêu đề"]; . setAttribute["r", 16]; . setAttribute["cx", 16]; . setAttribute["cy", 16]; . setAttribute["nét-dasharray", p + " 100"]; . setAttribute["viewBox", "0 0 32 32"]; . textContent = chiếc bánh. văn bảnNội dung; . textContent = '';

126

CHƯƠNG 3. HÌNH DẠNG

svg. appendChild[tiêu đề]; . appendChild[vòng tròn]; . appendChild[svg];

FUTURE

Biểu đồ hình tròn

Bạn có nhớ chuyển màu hình nón từ phần “Bàn cờ” ở trang 55 không? . Tất cả những gì nó cần cho một biểu đồ hình tròn sẽ là một phần tử hình tròn, với dải màu hình nón gồm hai điểm dừng màu. Ví dụ: biểu đồ hình tròn 40% trong Hình 3. 53 sẽ đơn giản như

bánh { chiều rộng. 100px; . 100px; . 50%; . conic-gradient[#655 40%, vàng lục 0]; . org/TR/css3values/#attr-notation] được triển khai rộng rãi, bạn sẽ có thể kiểm soát tỷ lệ phần trăm bằng một thuộc tính HTML đơn giản

lai lịch. conic-gradient[#655 attr[data-value %], yellowgreen 0];

Điều này cũng làm cho việc thêm màu thứ ba trở nên cực kỳ dễ dàng. Ví dụ: đối với biểu đồ hình tròn như biểu đồ được hiển thị ở trên cùng bên phải của hộp này, chúng tôi chỉ cần thêm hai điểm dừng màu nữa

lai lịch. conic-gradient[deeppink 20%, #fb3 0, #fb3 30%, yellowgreen 0];

BÍ MẬT #14. BẢNG BIỂU ĐỒ ĐƠN GIẢN

127

Đó là nó. Bạn có thể nghĩ rằng phương thức CSS tốt hơn, bởi vì mã của nó đơn giản hơn và ít xa lạ hơn. Tuy nhiên, phương pháp SVG có một số lợi ích nhất định mà giải pháp CSS thuần túy không có. ■ Rất dễ dàng để thêm màu thứ ba. chỉ cần thêm một vòng tròn có nét khác và thay đổi nét của nó bằng nét-dashoffset. Ngoài ra, thêm chiều dài nét vẽ của nó vào chiều dài nét vẽ của hình tròn trước [bên dưới] nó. Bạn hình dung chính xác như thế nào khi thêm màu thứ ba vào biểu đồ hình tròn được tạo bằng giải pháp đầu tiên? . Giải pháp đầu tiên phụ thuộc vào nền và do đó, sẽ không in. ■ Chúng ta có thể thay đổi màu sắc bằng các kiểu nội tuyến, nghĩa là chúng ta có thể dễ dàng thay đổi chúng thông qua tập lệnh [e. g. , tùy thuộc vào đầu vào của người dùng]. Giải pháp đầu tiên dựa trên các phần tử giả, không thể sử dụng các kiểu nội tuyến ngoại trừ thông qua kế thừa, điều này không phải lúc nào cũng thuận tiện. CHƠI. chơi. bí mật css. io/bánh-svg

■ Chuyển đổi CSS w3. org/TR/css-transforms ■ Giá trị hình ảnh CSS w3. org/TR/css-images ■ Hình nền và đường viền CSS w3. org/TR/css-backgrounds ■ Đồ họa Vector có thể mở rộng w3. org/TR/SVG ■ Giá trị hình ảnh CSS cấp 4 w3. hình ảnh org/TR/css4

128

CHƯƠNG 3. HÌNH DẠNG

RELATED

SPECS

Hiệu ứng hình ảnh

4

15

Bóng một phía Vấn đề Một trong những câu hỏi phổ biến nhất mà tôi thấy được hỏi về bóng hộp trên các trang web Hỏi & Đáp là làm thế nào để có thể áp dụng bóng cho chỉ một [hoặc hiếm hơn là hai] mặt. Tìm kiếm nhanh trên stackoverflow. com tiết lộ gần một nghìn kết quả cho điều này. Điều này có ý nghĩa, vì chỉ hiển thị bóng ở một bên sẽ tạo ra hiệu ứng tinh tế hơn nhưng không kém phần chân thực. Thông thường, các nhà phát triển thất vọng thậm chí sẽ viết vào danh sách gửi thư của Nhóm làm việc CSS yêu cầu các thuộc tính mới như box-shadow-bottom để có thể thực hiện việc này. Tuy nhiên, những hiệu ứng như vậy đã có thể xảy ra với việc sử dụng khéo léo chiếc hộp tốt-

thuộc tính bóng mà chúng tôi đã học và yêu thích

Bóng một bên Hầu hết mọi người sử dụng bóng hộp có ba độ dài và một màu, như vậy

bóng hộp. 2px 3px 4px rgba[0,0,0,. 5];

130

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

Một loạt các bước sau đây là một cách tốt [mặc dù không hoàn toàn chính xác về mặt kỹ thuật] để hình dung cách vẽ bóng đổ này [Hình 4. 1]

HINH 4. 1 Ví dụ mô hình tinh thần của một hộp-

cái bóng được sơn

1. Một rgba[0,0,0,. 5] hình chữ nhật được vẽ với cùng kích thước và vị trí với phần tử của chúng ta

Trừ khi có ghi chú khác, đề cập đến kích thước của một phần tử ở đây có nghĩa là kích thước của hộp đường viền của nó, không phải

2. Nó được di chuyển 2px sang bên phải và 3px xuống dưới cùng

chiều rộng và chiều cao CSS của nó

3. Nó bị mờ 4px bằng thuật toán làm mờ Gaussian [hoặc tương tự]. Về cơ bản, điều này có nghĩa là quá trình chuyển đổi màu trên các cạnh của bóng giữa màu bóng và độ trong suốt hoàn toàn sẽ dài xấp xỉ gấp đôi bán kính mờ [trong ví dụ của chúng tôi là 8px]. 4. Hình chữ nhật mờ sau đó được cắt bớt ở nơi nó giao nhau với phần tử ban đầu của chúng ta, để nó có vẻ “ở đằng sau” nó. Điều này hơi khác so với cách mà hầu hết các tác giả hình dung bóng đổ [một hình chữ nhật mờ bên dưới phần tử]. Tuy nhiên, đối với một số trường hợp sử dụng, điều quan trọng là phải nhận ra rằng sẽ không có bóng nào được vẽ bên dưới phần tử. Ví dụ: nếu chúng ta đặt nền bán trong suốt cho phần tử, chúng ta sẽ không thấy bóng bên dưới. Điều này khác với bóng văn bản, không bị cắt bớt bên dưới văn bản. Việc sử dụng bán kính làm mờ 4px có nghĩa là kích thước của bóng của chúng ta lớn hơn khoảng 4px so với kích thước của phần tử, vì vậy một phần của bóng sẽ hiển thị từ mọi phía của phần tử. Chúng tôi có thể thay đổi độ lệch để ẩn bất kỳ bóng nào từ trên xuống và bên trái, bằng cách tăng chúng lên ít nhất 4px. Tuy nhiên, sau đó điều này dẫn đến một cái bóng quá dễ thấy, trông không đẹp mắt [Hình 4. 2]. Ngoài ra, ngay cả khi đây không phải là vấn đề,

Nói chính xác thì chúng ta sẽ thấy bóng 1px ở trên cùng [4px - 3px],

2px ở bên trái [4px - 2px], 6px ở bên phải [4px + 2px] và 7px ở dưới cùng [4px + 3px]. Trong thực tế, nó sẽ trông nhỏ hơn vì quá trình chuyển đổi màu trên các cạnh không tuyến tính, giống như một dải màu sẽ là

chúng tôi chỉ muốn có một cái bóng ở một bên, không phải hai, nhớ không? . Bán kính trải rộng tăng hoặc [nếu âm] giảm kích thước của bóng tối xuống

BÍ MẬT #15. BÓNG MỘT MẶT

131

số tiền bạn chỉ định. Ví dụ: bán kính trải rộng là -5px sẽ giảm chiều rộng và chiều cao của bóng đi 10px [5px mỗi bên]. Theo logic, nếu chúng ta áp dụng bán kính trải rộng âm có giá trị tuyệt đối bằng bán kính mờ, thì bóng có cùng kích thước với phần tử mà nó được áp dụng trên. Trừ khi chúng ta di chuyển nó với độ lệch

HINH 4. 2

[hai độ dài đầu tiên], chúng tôi sẽ không thấy bất kỳ độ dài nào. Vì vậy, nếu chúng ta áp dụng một

Cố gắng che giấu cái bóng khỏi

độ lệch dọc dương, chúng ta sẽ bắt đầu thấy bóng ở dưới cùng của

bên trên và bên trái bằng cách sử dụng độ lệch bằng với bán kính mờ

yếu tố, nhưng không phải trên bất kỳ mặt nào khác, đó là hiệu ứng mà chúng tôi đang cố gắng đạt được

bóng hộp. 0 5px 4px -4px màu đen;

Bạn có thể xem kết quả trong Hình 4. 3

HINH 4. 3 bóng hộp ở phía dưới

CHƠI. chơi. bí mật css. io/shadow-one-side

chỉ bên

Bóng trên hai mặt liền kề Một câu hỏi thường gặp khác liên quan đến việc áp dụng bóng trên hai mặt. Nếu hai cạnh kề nhau [e. g. , bên phải và dưới cùng], thì điều này dễ dàng hơn. bạn có thể chọn một hiệu ứng như trong Hình 4. 2 hoặc áp dụng một biến thể của thủ thuật đã thảo luận trong phần trước, với những điểm khác biệt sau. ■ Chúng tôi không muốn thu nhỏ bóng đổ để giải thích cho việc làm mờ cả hai bên mà chỉ một bên. Do đó, thay vì bán kính trải rộng có giá trị ngược lại với bán kính mờ, nó sẽ bằng một nửa giá trị đó. ■ Chúng ta cần cả hai độ lệch, vì chúng ta muốn di chuyển bóng theo cả hai chiều ngang

HINH 4. 4 bóng hộp chỉ ở hai bên liền kề

và theo chiều dọc. Giá trị của chúng cần phải lớn hơn hoặc bằng một nửa bán kính mờ, vì chúng ta muốn ẩn phần bóng còn lại khỏi hai bên còn lại. Ví dụ, đây là cách chúng ta có thể áp dụng một bên phải và bên dưới

132

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

màu đen, bóng 6px cho

bóng hộp. 3px 3px 6px -3px màu đen;

Bạn có thể xem kết quả trong Hình 4. 4. CHƠI. chơi. bí mật css. io/shadow-2-side

Bóng ở hai phía đối diện Nó bắt đầu phức tạp hơn khi chúng ta muốn có bóng ở hai phía đối diện, chẳng hạn như bên trái và bên phải. Bởi vì bán kính trải rộng được áp dụng cho tất cả các bên như nhau

Có các cuộc thảo luận trong CSS WG về việc cho phép giá trị bán kính trải rộng theo chiều ngang/dọc riêng biệt-

[tôi. e. , không có cách nào để xác định rằng chúng tôi muốn phóng to bóng đổ

ues trong tương lai, mà sẽ sim-

theo chiều dọc và thu nhỏ theo chiều dọc], cách duy nhất để làm điều này là sử dụng hai bóng-

plify này

ows, mỗi bên một cái. Sau đó, về cơ bản, chúng tôi áp dụng thủ thuật được thảo luận trong phần “Bóng ở một bên” trên trang 130 hai lần

bóng hộp. 5px 0 5px -5px đen, -5px 0 5px -5px đen;

HINH 4. 5

Bạn có thể xem kết quả trong Hình 4. 5

bóng hộp ở hai phía đối diện

CHƠI. chơi. bí mật css. io/bóng đối diện

■ CSS Backgrounds & Borders w3. org/TR/css-backgrounds

RELATED

SPECS

BÍ MẬT #15. BÓNG MỘT MẶT

133

16

Đổ bóng không đều Điều kiện tiên quyết box-shadow

Vấn đề bóng hộp hoạt động rất tốt khi chúng ta muốn tạo bóng đổ trên hình chữ nhật hoặc bất kỳ hình dạng nào có thể được tạo bằng bán kính đường viền [tham khảo bí mật “Hình elip linh hoạt” trên trang 76 để biết một vài ví dụ về điều đó]. Tuy nhiên, nó trở nên kém hữu ích hơn khi chúng ta có các phần tử giả hoặc các đồ trang trí bán trong suốt khác, bởi vì bóng hộp bỏ qua độ trong suốt một cách đáng xấu hổ. Một số ví dụ bao gồm. ■ Hình ảnh bán trong suốt, hình nền hoặc hình ảnh viền [e. g. , khung ảnh màu vàng cổ điển] ■ Các đường viền có chấm, nét đứt hoặc nửa trong suốt không có nền [hoặc khi

clip nền không phải là hộp viền] ■ Bong bóng đối thoại, với con trỏ được tạo thông qua phần tử giả

134

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

■ Các góc bị cắt giống như những gì chúng ta đã thấy trong bí mật “Các góc bị cắt” ở trang 96 ■ Hầu hết các hiệu ứng góc được gấp lại, bao gồm cả hiệu ứng ở phần sau của chương này ■ Các hình dạng được tạo qua clip-path, giống như các hình ảnh kim cương trong bí mật “Hình ảnh kim cương”

HINH 4. 6 Phần tử có kiểu dáng CSS làm cho bóng hộp trở nên vô dụng;

2px 2px 10px rgba[0,0,0,. 5]

Kết quả của nỗ lực vô ích khi áp dụng bóng hộp cho một số trong số chúng được hiển thị trong Hình 4. 6. Có giải pháp nào cho những trường hợp như vậy hay chúng ta phải từ bỏ bóng hoàn toàn?

Giải pháp Đặc tả Hiệu ứng Bộ lọc [w3. org/TR/filter-effects] đưa ra giải pháp cho vấn đề này, thông qua thuộc tính bộ lọc mới, được mượn từ SVG. Tuy nhiên, mặc dù các bộ lọc CSS về cơ bản là các bộ lọc SVG, nhưng chúng không yêu cầu bất kỳ kiến ​​thức nào về SVG. Thay vào đó, chúng được chỉ định thông qua một số

LIMITED SUPPORT

rất nhiều chức năng tiện lợi, chẳng hạn như blur[], thang độ xám[] hoặc—chờ đã—drop-shadow[]. Bạn thậm chí có thể xâu chuỗi nhiều bộ lọc nếu muốn, bằng khoảng trắng ngăn cách chúng, như thế này

lọc. mờ [] thang độ xám [] đổ bóng [];

Bộ lọc drop-shadow[] chấp nhận các tham số giống như hộp cơ bản-

bóng, nghĩa là không có bán kính trải rộng, không có từ khóa chèn và không có nhiều bóng được phân tách bằng dấu phẩy. Ví dụ, thay vì

BÍ MẬT #16. BÓNG THẢ BẤT THƯỜNG XUYÊN

135

bóng hộp. 2px 2px 10px rgba[0,0,0,. 5];

chúng tôi sẽ viết

lọc. bóng đổ [2px 2px 10px rgba[0,0,0,. 5]];

!

Bạn có thể thấy kết quả của bộ lọc drop-shadow[] này khi được áp dụng trên

Chúng có thể sử dụng các thuật toán làm mờ khác nhau, vì vậy bạn có thể cần

để điều chỉnh giá trị mờ của bạn

các yếu tố tương tự như Hình 4. 6 trong Hình 4. 7

HINH 4. 7 Bộ lọc drop-shadow[], được áp dụng cho các phần tử trong Hình 4. 6

Điều tốt nhất về các bộ lọc CSS là chúng xuống cấp một cách duyên dáng. khi chúng không được hỗ trợ, không có gì bị hỏng, không có hiệu ứng nào được áp dụng. Bạn có thể nhận được hỗ trợ trình duyệt tốt hơn một chút bằng cách sử dụng bộ lọc SVG bên cạnh, nếu bạn thực sự cần hiệu ứng này để hoạt động trong nhiều trình duyệt nhất có thể. Bạn có thể tìm thấy các bộ lọc SVG tương ứng cho mọi chức năng bộ lọc trong đặc tả Hiệu ứng bộ lọc [w3. org/TR/hiệu ứng bộ lọc/]. Bạn có thể bao gồm cả bộ lọc SVG và bộ lọc CSS được đơn giản hóa bên cạnh và để tầng xử lý cái nào thắng

lọc. url[thả bóng. svg#drop-shadow]; . bóng đổ [2px 2px 10px rgba[0,0,0,. 5]];

Thật không may, nếu bộ lọc SVG là một tệp riêng biệt, thì nó không thể tùy chỉnh như một chức năng đẹp, thân thiện với con người có ngay trong mã CSS của bạn và nếu là nội tuyến, nó sẽ làm lộn xộn mã. Các tham số được cố định bên trong tệp và sẽ không thực tế nếu có nhiều tệp nếu chúng tôi muốn có một bóng đổ hơi khác. Chúng tôi có thể sử dụng các URI dữ liệu [cũng sẽ lưu yêu cầu HTTP bổ sung], nhưng 136

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

họ vẫn sẽ đóng góp vào một kích thước tệp lớn. Bởi vì đây là một dự phòng, bạn nên sử dụng một hoặc hai biến thể, ngay cả đối với các lần thả hơi khác nhau

bộ lọc bóng []. Một lưu ý khác cần ghi nhớ là mọi khu vực không trong suốt sẽ đổ bóng một cách bừa bãi, bao gồm cả văn bản [khi nền của bạn trong suốt], như bạn đã thấy trong Hình 4. 7. Bạn có thể nghĩ rằng bạn có thể hủy bỏ điều này bằng cách sử dụng text-shadow. không;, nhưng văn bản-

bóng hoàn toàn tách biệt và sẽ không hủy hiệu ứng của bộ lọc dropshadow[] trên văn bản. Ngoài ra, nếu bạn đang sử dụng text-shadow để tạo bóng thực sự trên văn bản, thì bóng này cũng sẽ bị đổ bóng bởi bộ lọc dropshadow[], về cơ bản là tạo bóng của bóng. lấy một

HINH 4. 8 bóng chữ cũng đổ bóng qua bộ lọc drop-shadow[]

hãy xem mã CSS ví dụ sau [và tha thứ cho kết quả hơi sến súa—nó đang cố gắng chứng minh vấn đề theo tất cả sự kỳ lạ của nó]

màu. màu hồng đậm; . 2px rắn; . . 1em. 2em vàng; . bóng đổ[. 05em. 05em. 1em màu xám];

Bạn có thể xem kết xuất mẫu trong Hình 4. 8, hiển thị cả văn bản-

bóng và bóng đổ [] mà nó tạo ra. CHƠI. chơi. bí mật css. io/thả bóng

■ Hiệu ứng bộ lọc w3. org/TR/hiệu ứng bộ lọc

RELATED

SPECS

BÍ MẬT #16. BÓNG THẢ BẤT THƯỜNG XUYÊN

137

17

Pha màu Điều kiện tiên quyết Mô hình màu HSL, kích thước nền

Sự cố Thêm tông màu vào ảnh thang độ xám [hoặc ảnh đã được chuyển đổi sang thang độ xám] là một cách phổ biến và trang nhã để mang lại sự thống nhất trực quan cho một nhóm ảnh có phong cách rất khác nhau. Thông thường, hiệu ứng được áp dụng tĩnh và loại bỏ trên. di chuột và/hoặc một số tương tác khác. Theo truyền thống, chúng tôi sử dụng một ứng dụng chỉnh sửa hình ảnh để tạo hai phiên bản của hình ảnh và viết một số mã CSS đơn giản để xử lý việc hoán đổi chúng. Cách tiếp cận này hoạt động, nhưng nó làm tăng thêm các yêu cầu HTTP bổ sung và cồng kềnh, đồng thời là một cơn ác mộng về bảo trì. Hãy tưởng tượng quyết định thay đổi màu sắc của hiệu ứng. bạn sẽ phải xem qua tất cả các hình ảnh và tạo các phiên bản đơn sắc mới

138

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

HINH 4. 9 Trang web CSSConf 2014 đã sử dụng hiệu ứng này cho ảnh diễn giả, nhưng hiển thị ảnh đủ màu khi di chuột và lấy nét

Các cách tiếp cận khác liên quan đến việc phủ một màu bán trong suốt lên trên hình ảnh hoặc áp dụng độ mờ cho hình ảnh và phủ nó lên một màu đồng nhất. Tuy nhiên, đây không phải là một tông màu thực sự. ngoài việc không chuyển đổi tất cả các màu trong ảnh thành các sắc thái của màu mục tiêu, nó còn làm giảm đáng kể độ tương phản. Ngoài ra còn có các tập lệnh biến hình ảnh thành một phần tử và áp dụng sắc thái thông qua JavaScript. Điều này tạo ra màu sắc phù hợp, nhưng khá chậm và hạn chế. Sẽ không dễ dàng hơn nhiều nếu có thể áp dụng tông màu cho hình ảnh ngay từ CSS của chúng tôi phải không?

Giải pháp dựa trên bộ lọc Vì không có chức năng bộ lọc đơn lẻ nào được thiết kế riêng cho hiệu ứng này nên chúng tôi cần khéo léo một chút và kết hợp nhiều bộ lọc. Bộ lọc đầu tiên chúng tôi sẽ áp dụng là nâu đỏ [], mang lại cho hình ảnh một tông màu vàng cam không bão hòa, với hầu hết các pixel có màu sắc xung quanh

LIMITED SUPPORT

35–40. Nếu đây là màu chúng ta muốn, thì chúng ta đã hoàn thành. Tuy nhiên, trong hầu hết các trường hợp, nó sẽ không. Nếu màu của chúng ta bão hòa hơn, chúng ta có thể sử dụng

bộ lọc bão hòa [] để tăng độ bão hòa của mọi pixel. Hãy giả sử

BÍ MẬT #17. TINH MÀU

139

chúng tôi muốn cung cấp cho hình ảnh một sắc thái của

hsl[335, 100%, 50%]. Chúng tôi cần

để tăng độ bão hòa lên một chút, vì vậy chúng tôi sẽ sử dụng tham số là 4. Giá trị chính xác tùy thuộc vào trường hợp của bạn và chúng tôi thường phải đánh cầu nó. Như Hình 4. 11 chứng minh, bộ lọc kết hợp này mang lại cho hình ảnh của chúng ta một tông màu vàng ấm áp. Đẹp như hình ảnh của chúng tôi bây giờ, chúng tôi không muốn tô màu nó bằng màu vàng cam này, mà bằng một màu hồng đậm, sáng. Do đó, chúng ta cũng cần áp dụng bộ lọc hue-rotate[], để bù màu sắc của mỗi pixel theo độ mà chúng ta chỉ định. Để tạo hue 335 từ khoảng 40, chúng ta cần thêm khoảng 295 [335 - 40] vào nó

HINH 4. 10 hàng đầu. Ảnh gốc

lọc. nâu đỏ [] bão hòa [4] hue-rotate [295deg];

Đáy. Hình ảnh sau bộ lọc sepia[]

Tại thời điểm này, chúng tôi đã tô màu cho hình ảnh của mình và bạn có thể xem nó trông như thế nào trong Hình 4. 12. Nếu đó là một hiệu ứng được bật. di chuột hoặc các trạng thái khác, chúng tôi thậm chí có thể áp dụng chuyển tiếp CSS cho nó

hình ảnh {

HINH 4. 11

chuyển tiếp. . bộ lọc 5s;

Hình ảnh của chúng tôi sau khi thêm một

lọc. nâu đỏ [] bão hòa [4] hue-rotate [295deg];

bộ lọc bão hòa []

} hình ảnh. di chuột, hình ảnh. tập trung { bộ lọc. không ai;

HINH 4. 12 Hình ảnh của chúng ta sau khi thêm hue-

bộ lọc rotate[] cũng vậy

140

CHƠI. chơi. bí mật css. io/màu-tint-bộ lọc

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

Giải pháp chế độ hòa trộn Giải pháp bộ lọc hoạt động, nhưng bạn có thể nhận thấy rằng kết quả không hoàn toàn giống với những gì có thể thu được bằng trình chỉnh sửa hình ảnh. Mặc dù chúng tôi đã cố gắng tô màu với một màu rất tươi sáng, nhưng kết quả vẫn trông khá nhợt nhạt. Nếu chúng ta cố gắng tăng tham số trong bộ lọc bão hòa[],

LIMITED SUPPORT

chúng tôi bắt đầu nhận được một hiệu ứng khác, cách điệu quá mức. Rất may, có một cách tốt hơn để tiếp cận điều này. chế độ hòa trộn. Nếu bạn đã từng sử dụng một trình chỉnh sửa hình ảnh chẳng hạn như Adobe Photoshop, có lẽ bạn đã quen thuộc với các chế độ hòa trộn. Khi hai phần tử chồng lên nhau, các chế độ hòa trộn sẽ kiểm soát cách màu sắc của phần tử trên cùng hòa trộn với màu sắc của bất kỳ phần tử nào bên dưới nó. Khi nói đến tô màu cho hình ảnh, chế độ hòa trộn bạn cần là độ sáng. Các

chế độ hòa trộn độ sáng duy trì độ sáng HSL của phần tử trên cùng, đồng thời áp dụng màu sắc và độ bão hòa của phông nền của nó. Nếu phông nền là màu của chúng tôi và thành phần có chế độ hòa trộn được áp dụng cho nó là hình ảnh của chúng tôi, thì về cơ bản đây không phải là màu sắc được cho là gì

HINH 4. 13

làm?

So sánh phương pháp lọc

Để áp dụng chế độ hòa trộn cho một phần tử, có hai thuộc tính có sẵn cho chúng tôi. mix-blend-mode để áp dụng các chế độ hòa trộn cho toàn bộ

[trên cùng] và phương pháp chế độ hòa trộn [dưới cùng]

các phần tử và chế độ hòa trộn nền để áp dụng các chế độ hòa trộn cho từng lớp nền riêng biệt. Điều này có nghĩa là để sử dụng phương pháp này trên một hình ảnh, chúng tôi có hai tùy chọn, cả hai tùy chọn đều không lý tưởng. ■ Bọc hình ảnh của chúng ta trong một vùng chứa có màu nền là màu chúng ta muốn ■ Sử dụng một thay vì một hình ảnh, với hình nền của nó được đặt thành hình ảnh mà chúng ta muốn tô màu và một lớp nền thứ hai bên dưới với màu của chúng ta Tùy thuộc vào đặc điểm cụ thể . Ví dụ: nếu chúng tôi muốn áp dụng hiệu ứng cho một phần tử, chúng tôi sẽ cần phải bọc nó trong một phần tử khác. Tuy nhiên, nếu chúng ta đã có một phần tử khác, chẳng hạn như một , chúng ta có thể sử dụng phần tử đó

HTML

BÍ MẬT #17. TINH MÀU

141

Sau đó, bạn chỉ cần khai báo hai lần để áp dụng hiệu ứng

một hình nền. hsl[335, 100%, 50%]; . độ sáng;

Cũng giống như các bộ lọc CSS, các chế độ hòa trộn xuống cấp một cách duyên dáng. nếu chúng không được hỗ trợ, thì không có hiệu ứng nào được áp dụng nhưng hình ảnh vẫn hiển thị hoàn hảo. Một cân nhắc quan trọng là trong khi các bộ lọc có thể hoạt hình, thì các chế độ hòa trộn không. Chúng tôi đã thấy cách bạn có thể tạo hiệu ứng động cho hình ảnh mờ dần thành đơn sắc bằng một chuyển đổi CSS đơn giản trên thuộc tính bộ lọc, nhưng bạn không thể làm điều tương tự với các chế độ hòa trộn. Tuy nhiên, đừng lo lắng, vì điều này không có nghĩa là hoạt hình không có vấn đề gì, nó chỉ có nghĩa là chúng ta cần phải suy nghĩ vượt trội. Như đã giải thích, mix-blend-mode pha trộn toàn bộ phần tử với bất cứ thứ gì bên dưới nó. Do đó, nếu chúng ta áp dụng chế độ hòa trộn độ sáng thông qua thuộc tính này, hình ảnh sẽ luôn được hòa trộn với thứ gì đó. Tuy nhiên, sử dụng thuộc tính chế độ hòa trộn nền trộn từng lớp hình nền với những lớp bên dưới nó, không biết bất kỳ thứ gì bên ngoài phần tử. Điều gì xảy ra sau đó khi chúng ta chỉ có một hình nền và màu nền trong suốt? . không có pha trộn diễn ra. Chúng ta có thể tận dụng quan sát đó và sử dụng nền-

thuộc tính chế độ hòa trộn cho hiệu ứng của chúng tôi. HTML sẽ phải khác một chút

142

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

Sau đó, chúng ta chỉ cần áp dụng CSS cho cái đó, vì kỹ thuật này không yêu cầu bất kỳ yếu tố bổ sung nào

hình ảnh được tô màu { chiều rộng. 640px; . 440px; . che; . hsl[335, 100%, 50%]; . độ sáng; . . màu nền 5s; . hình ảnh pha màu. hover { màu nền. trong suốt;

Tuy nhiên, như đã đề cập trước đây, cả hai kỹ thuật đều không lý tưởng. Các vấn đề chính đang diễn ra ở đây là. ■ Kích thước của hình ảnh cần được mã hóa cứng trong mã CSS. ■ Về mặt ngữ nghĩa, đây không phải là hình ảnh và trình đọc màn hình sẽ không đọc được như vậy. Giống như hầu hết mọi thứ trong cuộc sống, không có cách nào hoàn hảo để làm điều này, nhưng trong phần này, chúng ta đã thấy ba cách khác nhau để áp dụng hiệu ứng này, mỗi cách đều có ưu và nhược điểm riêng. Cái bạn chọn tùy thuộc vào nhu cầu cụ thể của dự án của bạn. CHƠI. chơi. bí mật css. io/màu sắc

BÍ MẬT #17. TINH MÀU

143

Lời khuyên dành cho Dudley Storey [demosthenes. info] để nghĩ ra thủ thuật tạo hiệu ứng động cho các chế độ hoà trộn [demosthenes. info/blog/888/ Tạo-Đơn sắc-Màu-Hình ảnh có màu-Với-CSS-pha trộn]. HAT MẸO ■ Hiệu ứng bộ lọc w3. org/TR/filter-effects ■ Tổng hợp và Trộn w3. org/TR/compositing ■ CSS Transitions w3. org/TR/css-chuyển tiếp

144

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

RELATED

SPECS

18

Hiệu ứng kính mờ Điều kiện tiên quyết Màu RGBA/HSLA

Sự cố Chúng tôi đang sử dụng thuật ngữ “phông nền” ở đây để chỉ một phần của trang nằm bên dưới một phần tử,

Một trong những trường hợp sử dụng đầu tiên của màu bán trong suốt là sử dụng chúng làm nền, trên phông nền chụp ảnh hoặc phông nền bận rộn khác, để giảm

mà thể hiện thông qua bán của nó

tương phản và làm cho văn bản có thể đọc được. Kết quả khá ấn tượng,

nền trong suốt

nhưng vẫn có thể khó đọc, đặc biệt với màu có độ mờ rất thấp và/hoặc phông nền bận rộn. Ví dụ, hãy xem Hình 4. 14, trong đó phần tử chính có nền trắng bán trong suốt. Đánh dấu trông như thế này. HTML

“Cách duy nhất để thoát khỏi cám dỗ […]”

146

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

Oscar Wilde, Bức tranh của Dorian Gray

Và CSS trông như thế này [với tất cả các bit không liên quan được bỏ qua cho ngắn gọn]

cơ thể { nền. url["con hổ. jpg"] 0 / bìa đã sửa; } chính { nền. hsla[0,0%,100%,. 3];

Như bạn có thể quan sát, văn bản thực sự khó đọc do hình ảnh đằng sau nó bị mờ và màu nền chỉ mờ 25%. Chúng ta có thể

HINH 4. 14 Nền trắng nửa trong suốt của chúng tôi làm cho văn bản khó đọc

BÍ MẬT #18. HIỆU ỨNG KÍNH Mờ

147

HINH 4. 15 Tăng giá trị alpha của màu nền sẽ khắc phục vấn đề dễ đọc nhưng cũng làm cho thiết kế của chúng ta kém thú vị hơn

tất nhiên cải thiện khả năng đọc bằng cách tăng tham số alpha của màu nền, nhưng sau đó hiệu ứng sẽ không thú vị bằng [xem Hình 4. 15]. Trong thiết kế in ấn truyền thống, vấn đề này thường được giải quyết bằng cách làm mờ phần ảnh bên dưới vùng chứa văn bản của chúng tôi. Nền mờ không bận rộn và do đó, văn bản trên đó dễ đọc hơn. Bởi vì làm mờ tốn kém về mặt tính toán, nên trước đây, việc sử dụng kỹ thuật này trong các trang web và thiết kế giao diện người dùng bị cấm sử dụng. Tuy nhiên, với việc cải thiện GPU và khả năng tăng tốc phần cứng ngày càng trở nên phổ biến đối với ngày càng nhiều thứ, ngày nay nó được sử dụng khá thường xuyên. Trong vài năm qua, chúng ta đã thấy kỹ thuật này trong các phiên bản mới hơn của cả Microsoft Windows, cũng như Apple iOS và Mac OS X [Hình 4. 16]

HINH 4. 16 Giao diện người dùng trong mờ với phông nền mờ ngày càng trở nên phổ biến trong vài năm qua, vì chi phí làm mờ tài nguyên không còn quá đắt nữa [Apple iOS 8. 1 được hiển thị ở bên trái và Apple OS X Yosemite được hiển thị ở bên phải]

148

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

Chúng tôi cũng có khả năng làm mờ các phần tử trong CSS, thông qua bộ lọc blur[], về cơ bản là phiên bản được tăng tốc phần cứng của nguyên hàm bộ lọc làm mờ SVG tương ứng mà chúng tôi luôn có cho các phần tử SVG. Tuy nhiên, nếu chúng ta trực tiếp áp dụng bộ lọc blur[] cho ví dụ của mình, thì toàn bộ phần tử sẽ bị mờ, điều này khiến nó thậm chí còn khó đọc hơn. [Hinh 4. 17]. Có cách nào để chỉ áp dụng nó cho phông nền của phần tử không [i. e. , phần nền phía sau phần tử của chúng ta]?

HINH 4. 17 Áp dụng bộ lọc blur[] cho chính phần tử sẽ khiến mọi thứ trở nên tồi tệ hơn

Giải pháp Với điều kiện là phần tử của chúng ta có phần đính kèm nền là cố định, điều này là có thể, mặc dù hơi phức tạp. Bởi vì chúng tôi không thể áp dụng làm mờ cho

Cũng có thể thực hiện được ngay cả với nền không cố định, chỉ là lộn xộn hơn

chính phần tử của chúng ta, chúng ta sẽ áp dụng nó cho một phần tử giả được đặt phía sau phần tử và có nền khớp liền mạch với phần tử trên. Đầu tiên, chúng tôi thêm phần tử giả và định vị nó một cách tuyệt đối, với tất cả các độ lệch bằng 0, để nó bao phủ toàn bộ phần tử

chính { vị trí. liên quan đến;

BÍ MẬT #18. HIỆU ỨNG KÍNH Mờ

149

} chủ yếu. trước { nội dung. ''; . tuyệt đối; . 0; . 0; . 0; . 0; . rgba[255,0,0,. 5];

!

Hãy cẩn thận khi sử dụng chỉ số z âm để di chuyển một đứa trẻ

bên dưới cha mẹ của nó. nếu nói cha mẹ

Chúng tôi cũng áp dụng một bán trong suốt

nền đỏ, vì vậy chúng ta có thể nhìn thấy

những gì chúng tôi đang làm, nếu không thì việc gỡ lỗi trở nên khó khăn khi chúng tôi thỏa thuận-

được lồng trong các phần tử khác với

kết hợp với phần tử trong suốt [và do đó, vô hình]. Như bạn có thể thấy trong

hình nền, con sẽ đi bên dưới

hinh 4. 18, phần tử giả của chúng tôi hiện ở trên nội dung của chúng tôi, do đó

những cái đó cũng vậy

làm sạch nó. Chúng ta có thể khắc phục điều này bằng cách thêm z-index. -1; . 20]. Bây giờ là lúc thay thế nền đỏ bán trong suốt đó bằng một nền thực sự phù hợp với phông nền của chúng ta, bằng cách sao chép trên nền hoặc bằng cách tách nó thành quy tắc riêng. Bây giờ chúng ta có thể làm mờ không?

Tại sao không chỉ sử dụng nền. kế thừa trên chính. trước?

cơ thể, chính. trước { nền. url["con hổ. jpg"] 0 / đã sửa bìa; }

nền cũng vậy

chính { vị trí. liên quan đến; . hsla[0,0%,100%,. 3]; . trước { nội dung. ''; . tuyệt đối; . 0; . 0; . 0; . 0; . làm mờ [20px];

150

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

HINH 4. 18 Phần tử giả hiện đang che khuất văn bản

HINH 4. 19 Chúng tôi đã sửa lỗi mờ mờ ở các cạnh, nhưng bây giờ cũng có một số vết mờ bên ngoài phần tử của chúng tôi

Như bạn có thể thấy trong Hình 4. 21, chúng tôi ở đó khá nhiều. Hiệu ứng làm mờ trông hoàn hảo ở giữa, nhưng ít mờ hơn ở gần các cạnh. Điều này xảy ra vì làm mờ làm giảm diện tích được bao phủ bởi một màu đơn sắc bằng bán kính làm mờ. Áp dụng một

nền đỏ cho phần tử giả của chúng tôi

giúp làm rõ những gì đang diễn ra [Hình 4. 22]

BÍ MẬT #18. HIỆU ỨNG KÍNH Mờ

151

HINH 4. 20 Di chuyển phần tử giả phía sau cha của nó, với chỉ số z. -1;

Để khắc phục sự cố này, chúng tôi sẽ làm cho phần tử giả ít nhất 20px [bằng với bán kính mờ của chúng tôi] lớn hơn kích thước của vùng chứa nó, bằng cách áp dụng lề -20px trở xuống để đảm bảo an toàn, giống như các trình duyệt khác . Như Hình 4. 19 chứng minh, điều này khắc phục vấn đề vết mờ mờ ở các cạnh, nhưng hiện tại cũng có một số vết mờ bên ngoài hộp chứa của chúng tôi, khiến nó trông giống như vết nhòe thay vì kính mờ. Rất may, điều này cũng dễ sửa chữa. chúng tôi sẽ chỉ áp dụng tràn. ẩn giấu; . Mã cuối cùng trông như sau và kết quả của nó có thể được nhìn thấy trong Hình 4. 23

cơ thể, chính. trước { nền. url["con hổ. jpg"] 0 / bìa cố định; } chính { vị trí. liên quan đến; . hsla[0,0%,100%,. 3]; . ẩn giấu; . trước {

152

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

Nội dung. ''; . tuyệt đối; . 0; . 0; . 0; . 0; . làm mờ [20px]; . -30px;

HINH 4. 21 Làm mờ phần tử giả của chúng tôi gần như hoạt động, nhưng nó ít mờ hơn ở các cạnh, làm giảm ảo ảnh kính mờ

HINH 4. 22 Thêm một

nền đỏ giúp

hiểu những gì đang xảy ra

BÍ MẬT #18. HIỆU ỨNG KÍNH Mờ

153

HINH 4. 23 Kết quả cuối cùng của chúng tôi

Lưu ý rằng trang của chúng tôi hiện đã trở nên dễ đọc hơn bao nhiêu và trang trông thanh lịch hơn bao nhiêu. Người ta tranh luận liệu dự phòng cho hiệu ứng này có tạo nên sự xuống cấp duyên dáng hay không. Nếu bộ lọc không được hỗ trợ, chúng tôi sẽ nhận được kết quả mà chúng tôi đã thấy ở phần đầu [Hình 4. 14]. Chúng ta có thể làm cho dự phòng dễ đọc hơn một chút bằng cách tăng độ mờ của màu nền. CHƠI. chơi. bí mật css. io/kính mờ

■ Hiệu ứng bộ lọc w3. org/TR/hiệu ứng bộ lọc

154

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

RELATED

SPECS

19

Hiệu ứng góc gấp Điều kiện tiên quyết Biến đổi CSS, chuyển màu CSS, bí mật “Góc cắt” ở trang 96

Vấn đề Tạo kiểu cho một góc [thường là trên cùng bên phải hoặc dưới cùng bên phải] của một phần tử theo cách làm cho nó trông như được gấp lại, với nhiều mức độ chân thực khác nhau, đã là một cách trang trí rất phổ biến trong nhiều năm nay. Ngày nay, có một số giải pháp CSS thuần túy hữu ích, giải pháp đầu tiên được xuất bản dễ dàng vào năm 2010 bởi bậc thầy phần tử giả, Nicolas Gallagher [nicolasgallagher. com/pure-css-folded-corner effect]. Tiền đề chính của họ thường là thêm hai hình tam giác ở góc trên cùng bên trái. một để lật trang và một màu trắng, để che góc của thành phần chính. Những hình tam giác này thường được tạo bằng thủ thuật đường viền cũ

156

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

HINH 4. 24 Một số thiết kế lại thủ thuật css trước đó. com có ​​các góc gấp đặc trưng, ​​ở góc trên cùng bên phải của mỗi hộp bài viết

Ấn tượng như những giải pháp này vào thời của họ, ngày nay chúng rất hạn chế và thiếu sót trong một số trường hợp. ■ Khi nền phía sau phần tử của chúng ta không phải là một màu đơn sắc, mà là một mẫu, họa tiết, ảnh, chuyển màu hoặc bất kỳ loại hình nền nào khác ■ Khi chúng ta muốn một góc khác với 45° và/hoặc một nếp gấp được xoay Là

Giải pháp 45° Chúng ta sẽ bắt đầu từ một phần tử có góc trên cùng bên phải được vát, được tạo bằng giải pháp dựa trên gradient trong bí mật “Cutout Corners”

“Cách duy nhất để thoát khỏi một

ở trang 96. Để tạo góc vát trên cùng bên phải có kích thước 1em bằng công nghệ này-

cám dỗ là để đầu hàng nó. ”

duy nhất, mã trông như thế này và kết xuất mẫu có thể được nhìn thấy trong

— Oscar Wilde, Bức tranh của Dorian Gray

hinh 4. 25

HINH 4. 25 nền. #58a;

điểm xuất phát của chúng tôi. một phần tử với

lai lịch

một góc cắt trên cùng bên phải, được thực hiện thông qua một

độ dốc tuyến tính [-135deg, trong suốt 2em, #58a 0];

dốc

Tại thời điểm này, chúng tôi đã hoàn thành một nửa. tất cả những gì chúng ta cần làm là thêm một hình tam giác tối hơn để lật trang. Chúng tôi sẽ làm điều đó bằng cách thêm một BÍ MẬT khác #19. GÓC GÓC HIỆU ỨNG

157

gradient để tạo hình tam giác, chúng tôi sẽ thay đổi kích thước theo nhu cầu của mình với

kích thước nền và vị trí ở góc trên bên phải. Để tạo hình tam giác, tất cả những gì chúng ta cần là một gradient tuyến tính có góc với hai điểm dừng gặp nhau ở giữa

lai lịch. linear-gradient[đến dưới cùng bên trái, trong suốt 50%, rgba[0,0,0,. 4] 0] không lặp lại 100% 0 / 2em 2em;

Bạn có thể thấy kết quả của việc chỉ có nền này trong Hình 4. 26. “Cách duy nhất để thoát khỏi cám dỗ là đầu hàng nó. ”

Bước cuối cùng sẽ là kết hợp chúng, và chúng ta sẽ hoàn thành, phải không?

— Oscar Wilde, Bức tranh

điều đó, đảm bảo rằng hình tam giác lật trang nằm phía trên góc cắt của chúng tôi

của Dorian Grey

dốc

HINH 4. 26

lai lịch. #58a;

Độ dốc thứ hai của chúng tôi cho nếp gấp

lai lịch

tam giác, biệt lập;

linear-gradient [đến dưới cùng bên trái,

ở đây như màu xám nhạt thay vì màu trắng,

trong suốt 50%, rgba[0,0,0,. 4] 0]

để bạn có thể thấy nó ở đâu

không lặp lại 100% 0 / 2em 2em, linear-gradient[-135deg, transparent 2em, #58a 0];

Như bạn có thể thấy trong Hình 4. 27, kết quả không như ý muốn“Cách duy nhất để thoát khỏi cám dỗ là đầu hàng nó. ” — Oscar Wilde, Bức tranh của Dorian Gray

mong đợi. Tại sao kích thước không phù hợp? . Lý do là [như chúng ta đã thảo luận trong phần bí mật “Các góc bị cắt” ở trang 96] kích thước góc 2em trong dải màu thứ hai của chúng ta nằm trong điểm dừng màu và do đó được đo dọc theo đường dải màu, là đường chéo. trên

HINH 4. 27

mặt khác, chiều dài 2em trong kích thước nền là chiều rộng và

Kết hợp hai gradient

chiều cao của gạch nền, được đo theo chiều ngang và

không sản xuất chính xác

theo chiều dọc

kết quả mong đợi

Để làm cho cả hai thẳng hàng, chúng ta cần thực hiện một trong các thao tác sau, tùy thuộc vào việc chúng ta muốn giữ kích thước nào trong hai kích thước. ■ Để giữ kích thước đường chéo 2em, chúng ta có thể nhân kích thước nền với 2

158

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

■ Để giữ kích thước 2em theo chiều ngang và chiều dọc, chúng ta có thể chia vị trí điểm dừng màu của gradient góc cắt của chúng ta cho 2. Bởi vì kích thước nền được lặp lại hai lần và hầu hết các phép đo CSS khác không được đo theo đường chéo, nên việc sử dụng cái sau thường được ưu tiên hơn. Vị trí dừng màu sẽ trở thành

2 2

= 2 ≈ 1. 414213562,

mà chúng ta sẽ làm tròn lên 1. 5 em

lai lịch. #58a;

“Cách duy nhất để thoát khỏi một

lai lịch

cám dỗ là để đầu hàng nó. ” — Oscar Wilde, Bức tranh

linear-gradient [đến dưới cùng bên trái,

của Dorian Grey

trong suốt 50%, rgba[0,0,0,. 4] 0] không lặp lại 100% 0 / 2em 2em,

HINH 4. 28

độ dốc tuyến tính [-135deg,

Sau khi thay đổi màu dừng

trong suốt 1. 5em, #58a 0];

vị trí của dải màu xanh lam, góc gấp của chúng ta cuối cùng cũng hoạt động

Như bạn có thể thấy trong Hình 4. 28, điều này cuối cùng mang lại cho chúng ta một góc bo tròn đẹp, linh hoạt, tối giản

!

Đảm bảo có ít nhất nhiều phần đệm bằng góc

kích thước, nếu không văn bản sẽ chồng lên nhau

CHƠI. chơi. bí mật css. io/góc gấp

góc [vì nó chỉ là nền], làm hỏng ảo ảnh góc gấp

Giải pháp cho các góc khác Góc gấp trong thực tế hiếm khi chính xác 45°. Ví dụ, nếu chúng ta muốn một cái gì đó thực tế hơn một chút, chúng ta có thể sử dụng một góc hơi khác

-150deg cho một góc 30°. Tuy nhiên, nếu chúng ta chỉ thay đổi góc của góc vát, hình tam giác biểu thị phần lật của trang sẽ không hiển thị

“Cách duy nhất để thoát khỏi cám dỗ là đầu hàng nó. ” — Oscar Wilde, Bức tranh của Dorian Gray

chỉ, dẫn đến vỡ trông giống như Hình 4. 29. Tuy nhiên, việc điều chỉnh kích thước của nó không đơn giản. Kích thước của tam giác đó không được xác định

HINH 4. 29

bởi một góc, nhưng bởi chiều rộng và chiều cao của nó. Làm thế nào chúng ta có thể tìm thấy những gì chiều rộng và

Thay đổi góc cắt của chúng tôi

chiều cao chúng ta cần?

góc gây ra sự cố này

BÍ MẬT #19. GÓC GÓC HIỆU ỨNG

159

Mã hiện tại trông như thế này

lai lịch. #58a; . linear-gradient[đến dưới cùng bên trái, trong suốt 50%, rgba[0,0,0,. 4] 0] không lặp lại 100% 0 / 2em 2em, linear-gradient[-150deg, transparent 1. 5em, #58a 0];

Tam giác vuông 30-60-90 là tam giác vuông có hai góc còn lại bằng 30° và 60°

Như bạn có thể thấy trong Hình 4. 30, về cơ bản ta cần tính độ dài cạnh huyền của hai tam giác vuông 30-60-90 khi biết độ dài một cạnh góc vuông của chúng. Như đường tròn lượng giác như hình 4. 31 nhắc nhở chúng ta, nếu chúng ta biết các góc và độ dài của một tam giác vuông

x z

cạnh của góc, chúng ta có thể tính độ dài của hai cạnh còn lại của nó bằng cách sử dụng

1

5e

m

y

sin, cosin và định lý Pitago. Chúng tôi biết từ toán học [hoặc máy tính] cos 30° =

3 2

1

và tội lỗi 30° = 2. Chúng tôi cũng biết từ trig-

vòng tròn onometric mà trong trường hợp của chúng ta, sin 30° =

HINH 4. 30

và cos 30° =

Vì vậy. 1 2

Góc cắt của chúng tôi, được mở rộng [các góc được đánh dấu màu xám là 30°]

3 2

HINH 4. 31 Sine và cosin giúp chúng ta tính toán

=

1. 5 năm

=

1. 5 x

⇒y=

⇒ x = 2 × 1. 5 ⇒ x = 3

2×1. 5 3

⇒ y = 3 ≈ 1. 732050808

y

chân của tam giác vuông dựa trên góc và cạnh huyền của chúng

r θ x

160

1. 5 x

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

năm x

1. 5. y

Tại thời điểm này, chúng ta cũng có thể tính z, thông qua định lý Pitago

z = x2 + y2 =

32 + 32 = 3 + 9 = 12 = 2 3

Bây giờ chúng ta có thể thay đổi kích thước hình tam giác để phù hợp

lai lịch. #58a; . linear-gradient[đến dưới cùng bên trái, trong suốt 50%, rgba[0,0,0,. 4] 0] không lặp lại 100% 0 / 3em 1. 73em, độ dốc tuyến tính [-150deg, trong suốt 1. 5em, #58a 0];

Lúc này góc của chúng ta có dạng như hình 4. 32. Như bạn có thể thấy, hình tam giác bây giờ khớp với góc bị cắt của chúng ta, nhưng kết quả trông thậm chí còn kém thực tế hơn. Mặc dù chúng tôi có thể không dễ dàng tìm ra lý do tại sao, nhưng chính mắt chúng tôi đã nhìn thấy nhiều góc gấp trước đây và ngay lập tức biết rằng điều này

“Cách duy nhất để thoát khỏi cám dỗ là đầu hàng nó. ” — Oscar Wilde, Bức tranh của Dorian Gray

sai lệch hoàn toàn so với mô hình mà họ đã quen. Bạn có thể giúp tâm trí có ý thức của mình hiểu tại sao nó trông giả tạo như vậy bằng cách cố gắng gấp một tờ giấy thật theo góc này. Thực sự là không có cách nào để gấp nó lại và làm cho nó trông hơi mơ hồ như Hình 4. 32

HINH 4. 32 Mặc dù chúng tôi đã đạt được kết quả như mong muốn, nhưng hóa ra có vẻ như

Như bạn có thể thấy trong một góc gấp thực tế, ngoài đời thực, chẳng hạn như góc trong

thậm chí còn kém thực tế hơn trước

hinh 4. 33, hình tam giác mà chúng ta cần tạo được xoay nhẹ và có cùng kích thước với hình tam giác mà chúng ta “cắt” từ góc của phần tử. Vì chúng ta không thể xoay nền nên đã đến lúc chuyển hiệu ứng sang phần tử giả

lưu ý { vị trí. liên quan đến; . #58a; . độ dốc tuyến tính [-150deg, trong suốt 1. 5em, #58a 0];

BÍ MẬT #19. GÓC GÓC HIỆU ỨNG

161

}. Ghi chú. trước { nội dung. ''; . tuyệt đối; . 0; . 0; . linear-gradient[đến dưới cùng bên trái, trong suốt 50%, rgba[0,0,0,. 4] 0]

HINH 4. 33

100% 0 không lặp lại;

Một phiên bản tương tự của gấp

chiều rộng. 3em;

hiệu ứng góc [tờ giấy ưa thích

Chiều cao. 1. 73em;

lịch sự của Leonie và Phoebe

}

Verou]

Tại thời điểm này, chúng tôi vừa sao chép hiệu ứng tương tự như trong Hình 4. 32 với các phần tử giả. Bước tiếp theo của chúng ta là thay đổi hướng của hình tam giác hiện có bằng cách hoán đổi chiều rộng và chiều cao của nó để làm cho nó phản chiếu góc bị cắt thay vì bổ sung cho nó. Sau đó, chúng ta sẽ xoay nó 30° [[90° – 30°] – 30°] ngược chiều kim đồng hồ, sao cho cạnh huyền của nó song song với góc bị cắt của chúng ta

Ghi chú. trước { nội dung. ''; . tuyệt đối; . 0; . 0; . linear-gradient[đến dưới cùng bên trái, trong suốt 50%, rgba[0,0,0,. 4] 0] 100% 0 không lặp lại; . 1. 73em; . 3em; . xoay[-30deg];

Bạn có thể thấy ghi chú của chúng tôi trông như thế nào sau những thay đổi này trong Hình 4. 34. Như bạn có thể thấy, về cơ bản chúng ta đã ở đó và chúng ta chỉ cần di chuyển hình tam giác sao cho các cạnh huyền của hai hình tam giác của chúng ta [hình tối và hình cắt

162

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

một] trùng nhau. Vì mọi thứ hiện đang đứng yên, chúng ta cần di chuyển hình tam giác theo cả chiều ngang và chiều dọc, vì vậy sẽ khó khăn hơn để biết phải làm gì. Chúng ta có thể làm mọi thứ dễ dàng hơn cho chính mình bằng cách đặt biến đổi nguồn gốc thành

phía dưới bên phải, sao cho góc dưới bên phải của tam giác là-

“Cách duy nhất để thoát khỏi cám dỗ là đầu hàng nó. ” — Oscar Wilde, Bức tranh của Dorian Gray

đến tâm quay, và do đó, cố định ở cùng một vị trí

HINH 4. 34 Chúng tôi đang bắt đầu đạt được điều đó, nhưng chúng tôi

Ghi chú. trước {

cần di chuyển tam giác

/* [Phần còn lại của kiểu dáng] */ biến đổi. xoay[-30deg]; . góc phải ở phía dưới;

“Cách duy nhất để thoát khỏi một

}

cám dỗ là để đầu hàng nó. ” — Oscar Wilde, Bức tranh

Như bạn có thể thấy trong Hình 4. 35, bây giờ chúng ta chỉ cần di chuyển hình tam giác của mình theo chiều dọc về phía trên cùng. Để tìm số tiền chính xác, chúng ta có thể sử dụng lại một số hình học. Như bạn có thể thấy trong Hình 4. 36, độ lệch dọc mà tam giác của chúng ta cần là x − y = 3 − 3 ≈ 1. 267949192, chúng ta có thể làm tròn lên 1. 3 em

của Dorian Grey

HINH 4. 35 Thêm biến đổi nguồn gốc

góc phải ở phía dưới; . bây giờ chúng ta chỉ cần di chuyển hình tam giác của mình theo chiều dọc

Ghi chú. trước { /* [Phần còn lại của kiểu dáng] */

x

biến đổi. dịchY[-1. 3em] xoay[-30deg]; . góc phải ở phía dưới;

năm x

}

x-y

Kết xuất mẫu trong Hình 4. 37 xác nhận rằng điều này cuối cùng mang lại cho chúng tôi hiệu quả mà chúng tôi đang hướng tới. Phew, thật dữ dội. Ngoài ra, bây giờ tam giác của chúng ta được tạo thông qua các phần tử giả, chúng ta có thể làm cho nó thực tế hơn nữa, bằng cách thêm các góc tròn, độ dốc [thực tế] và hộp-

bóng tối. Mã cuối cùng trông như sau

HINH 4. 36 Tìm hiểu xem tam giác của chúng ta di chuyển bao nhiêu không khó như thoạt nhìn

BÍ MẬT #19. GÓC GÓC HIỆU ỨNG

163

Đảm bảo đặt

!

Ghi chú {

translateY[] biến đổi thành-

trước vòng quay, nếu không tri-

Chức vụ. liên quan đến;

góc sẽ di chuyển dọc theo góc 30° của nó, vì mọi phép biến đổi cũng

lai lịch. #58a;

biến đổi toàn bộ tọa độ

lai lịch

hệ thống của phần tử, không chỉ là

độ dốc tuyến tính [-150deg,

mỗi phần tử

trong suốt 1. 5em, #58a 0]; . . 5em;

“Cách duy nhất để thoát khỏi một

Ghi chú. trước {

cám dỗ là để đầu hàng nó. ” — Oscar Wilde, Bức tranh

Nội dung. '';

của Dorian Grey

Chức vụ. tuyệt đối; . 0; . 0;

HINH 4. 37

lai lịch. linear-gradient [đến dưới cùng bên trái,

Hình tam giác của chúng tôi cuối cùng được căn chỉnh và

trong suốt 50%, rgba[0,0,0,. 2] 0, rgba[0,0,0,. 4]]

sờ vào

100% 0 không lặp lại; . 1. 73em; . 3em;

“Cách duy nhất để thoát khỏi một

biến đổi. dịchY[-1. 3em] xoay[-30deg];

cám dỗ là để đầu hàng nó. ” — Oscar Wilde, Bức tranh

biến đổi nguồn gốc. góc phải ở phía dưới;

của Dorian Grey

bán kính đường viền dưới cùng bên trái. thừa kế; . -. 2 em. 2em. 3em -. 1em rgba[0,0,0,. 15];

HINH 4. 38 Với một vài hiệu ứng nữa, góc gấp của chúng ta trở nên sống động

Và bạn có thể chiêm ngưỡng thành quả lao động của chúng tôi trong hình 4. 38. CHƠI. chơi. bí mật css. io/folded-corner-realistic Hiệu ứng trông đẹp, nhưng nó KHÔ như thế nào? . ■ Chỉ cần một lần chỉnh sửa để thay đổi kích thước phần tử và các số liệu khác [phần đệm, v.v. ]. ■ Chỉ cần hai lần chỉnh sửa [một lần không có dự phòng] để thay đổi màu nền

164

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

■ Phải mất bốn lần chỉnh sửa và một số phép tính không cần thiết để thay đổi kích thước góc gấp. ■ Phải mất năm lần chỉnh sửa và một vài phép tính thậm chí ít tầm thường hơn để thay đổi góc gấp. 2 cái cuối xấu quá. Có lẽ đã đến lúc cho một mixin tiền xử lý. SCSS

@mixin fold-corner[$background, $size, $angle. 30 độ] { vị trí. liên quan đến; . $nền; . linear-gradient[$angle - 180deg, transparent $size, $background 0]; . . 5em; . $size / sin[$angle]; . $size / cos[$angle]; . trước { nội dung. ''; . tuyệt đối; . 0; . 0; . linear-gradient[đến dưới cùng bên trái, trong suốt 50%, rgba[0,0,0,. 2] 0, rgba[0,0,0,. 4]] 100% 0 không lặp lại; . $y; . $x; . translateY[$y - $x] rotate[2*$angle - 90deg]; . góc phải ở phía dưới; . thừa kế;

bóng hộp. -. 2 em. 2 em. 3em -. 1em rgba[0,0,0,. 2];

BÍ MẬT #19. GÓC GÓC HIỆU ỨNG

165

/* được dùng như. */. lưu ý { @include Folded-corner[#58a, 2em, 40deg];

!

Tại thời điểm viết bài, SCSS không hỗ trợ lượng giác

CHƠI. chơi. bí mật css. io/folded-corner-mixin

chức năng tự nhiên. Để kích hoạt hỗ trợ, bạn có thể sử dụng Compass framework [compassstyle. org], trong số các thư viện khác

■ CSS Backgrounds & Borders w3. org/TR/css-backgrounds

Bạn thậm chí có thể tự viết chúng, sử dụng khai triển hàm Taylor. ÍT hơn, mặt khác,

■ CSS Image Values w3. org/TR/css-images

bao gồm chúng ra khỏi hộp

■ Chuyển đổi CSS w3. org/TR/css-transforms

166

CHƯƠNG 4. HIỆU ỨNG HÌNH ẢNH

RELATED

SPECS

kiểu chữ

5

20

Dấu gạch nối Vấn đề Các nhà thiết kế thích biện minh cho văn bản. Nếu bạn nhìn vào bất kỳ tạp chí hay cuốn sách nào được thiết kế đẹp mắt, bạn sẽ thấy nó ở khắp mọi nơi. Tuy nhiên, trên Web, biện minh được sử dụng rất ít và thậm chí còn ít được sử dụng bởi các nhà thiết kế lành nghề. Tại sao lại như vậy, vì chúng ta đã căn chỉnh văn bản. biện minh; . 1. Nhìn vào tất cả các

HÌNH 5. 1 Hiệu ứng mặc định của CSS justification

“những dòng sông trắng” được tạo bằng cách điều chỉnh khoảng cách để căn chỉnh văn bản. Điều này không chỉ trông xấu mà còn cản trở khả năng đọc. Trong bản in, sự biện minh luôn đi đôi với sự gạch nối. Bởi vì gạch nối cho phép các từ được chia nhỏ thành các âm tiết, nên ít cần điều chỉnh khoảng trắng hơn, dẫn đến văn bản trông tự nhiên hơn nhiều. Cho đến gần đây, có nhiều cách để gạch nối văn bản trên Web, nhưng chúng là loại giải pháp còn tệ hơn cả vấn đề. Cách thông thường liên quan đến việc sử dụng mã phía máy chủ, JavaScript, trình tạo trực tuyến hoặc thậm chí chỉ bằng tay không và rất nhiều kiên nhẫn của chúng tôi để chèn dấu gạch nối mềm [] giữa các âm tiết, để trình duyệt biết vị trí của từng từ có thể bị ngắt. Thông thường, chi phí như vậy không đáng nên nhà thiết kế đã quyết định sử dụng một kiểu căn chỉnh văn bản khác để thay thế

168

CHƯƠNG 5. HÌNH ẢNH

Giải pháp Trong văn bản CSS cấp 3, một thuộc tính mới xuất hiện. gạch nối. Nó chấp nhận ba giá trị. không, thủ công và tự động. Giá trị ban đầu của nó là thủ công, để phù hợp với hành vi hiện có. chúng ta luôn có thể gạch nối thủ công, với dấu gạch nối mềm. Rõ ràng, dấu gạch ngang. không ai;

HÌNH 5. 2

gạch nối. tự động;

Kết quả của dấu gạch nối. tự động

Đó là tất cả những gì nó cần. Bạn có thể xem kết quả trong Hình 5. 2. Tất nhiên, để điều này hoạt động, bạn cần phải khai báo một ngôn ngữ thông qua thuộc tính lang HTML, nhưng đó là điều bạn nên làm bất kể. Nếu bạn muốn kiểm soát chi tiết hơn đối với dấu gạch nối [e. g. , trong đoạn văn bản giới thiệu ngắn], bạn vẫn có thể sử dụng một vài dấu gạch nối mềm [] để giúp trình duyệt. Thuộc tính dấu gạch nối sẽ ưu tiên chúng và sau đó tìm ra nơi khác mà nó có thể ngắt từ

TRIVIA

Gói từ hoạt động như thế nào?

Giống như nhiều thứ trong khoa học máy tính, gói từ nghe có vẻ đơn giản và dễ hiểu, nhưng thực ra không phải vậy. Có nhiều thuật toán để thực hiện nó, nhưng phổ biến nhất là thuật toán Tham lam và thuật toán Knuth-Pass. Thuật toán Greedy hoạt động bằng cách phân tích từng dòng một, điền vào đó càng nhiều từ [hoặc âm tiết, khi sử dụng dấu gạch nối] càng tốt và chuyển sang dòng tiếp theo khi gặp từ/âm tiết đầu tiên không khớp. Thuật toán Knuth-Plass, bắt nguồn từ tên của các kỹ sư đã phát triển nó, phức tạp hơn nhiều. Nó hoạt động bằng cách tính đến toàn bộ văn bản và tạo ra kết quả thẩm mỹ hơn nhiều, nhưng cũng chậm hơn đáng kể để tính toán. Hầu hết các ứng dụng xử lý văn bản trên máy tính để bàn đều sử dụng thuật toán Knuth-Plass. Tuy nhiên, các trình duyệt hiện đang sử dụng Greedy vì lý do hiệu suất, vì vậy kết quả biện minh của chúng vẫn không tốt bằng. BÍ MẬT #20. DẤU NỐI

169

Dấu gạch nối CSS xuống cấp rất duyên dáng. Nếu thuộc tính dấu gạch ngang không được hỗ trợ, bạn chỉ nhận được phần căn chỉnh văn bản giống như Hình 5. 1. Chắc chắn, nó không đẹp hoặc đặc biệt dễ đọc, nhưng vẫn hoàn toàn có thể truy cập được. CHƠI. chơi. bí mật css. io/gạch nối

■ Văn bản CSS w3. org/TR/css-văn bản

RELATED

SPECS

■ Nhà phát triển văn bản CSS cấp 4. w3. org/csswg/css-text-4

FUTURE

Kiểm soát gạch nối

Nếu bạn đến từ một nền tảng thiên về thiết kế hơn, bạn có thể cảm thấy khó chịu với ý tưởng về dấu gạch nối dưới dạng chuyển đổi, không có cài đặt nào khác để kiểm soát cách nó ngắt từ. Bạn có thể vui khi biết rằng trong tương lai, chúng tôi sẽ có nhiều quyền kiểm soát chi tiết hơn đối với dấu gạch nối, với một số thuộc tính liên quan được lên kế hoạch trong CSS Text Level 4 [nhà phát triển. w3. org/csswg/css-text-4], một số trong số đó là. ■ gạch nối-giới hạn-dòng ■ gạch nối-giới hạn-ký tự ■ gạch nối-giới hạn-vùng ■ gạch nối-giới hạn-cuối ■ ký tự gạch nối

170

CHƯƠNG 5. HÌNH ẢNH

21

Chèn ngắt dòng Vấn đề

Tên. Le Verou

Nhu cầu chèn ngắt dòng thông qua CSS thường phát sinh với danh sách định nghĩa

E-mail. [email được bảo vệ]

[Hình 5. 3], mà còn trong một số trường hợp khác. Thường xuyên hơn không, chúng tôi sử dụng một

Địa điểm. Trái đất

danh sách định nghĩa bởi vì chúng tôi muốn trở thành cư dân mạng tốt và sử dụng thích hợp, se-

HÌNH 5. 3

đánh dấu mantic, ngay cả khi những gì chúng tôi muốn trực quan chỉ là một vài dòng

Danh sách định nghĩa có tên/giá trị

cặp tên/giá trị. Ví dụ: hãy xem xét đánh dấu này

cặp trên mỗi dòng

Tên. Tên Lea Verou. Email của Le Verou. [email được bảo vệ]

E-mail. [email được bảo vệ]

Địa điểm. Trái đất

Địa điểm

HÌNH 5. 4 Kiểu dáng mặc định của danh sách định nghĩa của chúng tôi

172

CHƯƠNG 5. HÌNH ẢNH

Trái đất

HTML

Kết quả trực quan mà chúng tôi mong muốn giống như kiểu dáng đơn giản được hiển thị trong Hình 5. 3. Bước đầu tiên thường là áp dụng một số CSS cơ bản như sau

đ { lề. 0; . in đậm;

Tuy nhiên, vì s và s là các phần tử khối, nên cuối cùng chúng ta có một thứ trông giống Hình 5 hơn. 4, với cả tên và giá trị trên dòng riêng của họ. Nỗ lực tiếp theo thường liên quan đến việc thử các giá trị khác nhau của thuộc tính hiển thị trên s, s hoặc cả hai, thậm chí thường là ngẫu nhiên khi chúng ta dần trở nên tuyệt vọng hơn. Tuy nhiên, theo cách đó, chúng ta thường kết thúc

Tên. Email của Le Verou. [email được bảo vệ] Vị trí. Trái đất

HÌNH 5. 5 màn hình. nội tuyến chỉ phá vỡ mọi thứ thậm chí còn tồi tệ hơn

lên với một cái gì đó như Hình 5. 5. Trước khi chúng ta bắt đầu bứt tóc, nguyền rủa các vị thần CSS hoặc từ bỏ việc tách biệt các mối quan tâm và sửa đổi đánh dấu của mình, có cách nào để giữ cho cả sự tỉnh táo và đạo đức [viết mã] của chúng ta không?

Giải pháp Về cơ bản, điều chúng ta cần làm là thêm ngắt dòng vào cuối mỗi. Nếu chúng tôi không ngại đánh dấu trình bày, chúng tôi có thể đã làm điều đó với các phần tử
tốt, như vậy.

Bạn có thể thấy nó trông như thế nào khi không có lớp phủ trong Hình 6. 15. Sau đó, chúng ta cần áp dụng một lớp cho phần tử mỗi khi chúng ta làm cho hộp thoại xuất hiện và sau đó áp dụng bộ lọc mờ, như vậy

chủ yếu. không nhấn mạnh {

HÌNH 6. 15 Một hộp thoại đơn giản không có lớp phủ để loại bỏ

lọc. làm mờ [5px];

nhấn mạnh phần còn lại của trang

Như bạn có thể thấy trong Hình 6. 16, đây đã là một cải tiến lớn. Tuy nhiên, hiện tại, hiệu ứng làm mờ được áp dụng ngay lập tức, trông không được tự nhiên cho lắm và có cảm giác UX khá khó xử. Vì các bộ lọc CSS có thể hoạt ảnh được, thay vào đó, chúng tôi có thể chuyển đổi mượt mà sang trang bị mờ

chính { chuyển tiếp. . bộ lọc 6s;

HÌNH 6. 16

}

Làm mờ phần tử khi hộp thoại hiển thị

chủ yếu. không nhấn mạnh { bộ lọc. làm mờ [5px]; . Một cách để làm điều này là sử dụng độ sáng [] và/hoặc

bộ lọc tương phản []. HÌNH 6. 17

chủ yếu. không nhấn mạnh {

Áp dụng cả làm mờ và làm mờ, cả thông qua bộ lọc CSS

242

lọc. mờ [3px] độ tương phản [. 8] độ sáng [. số 8];

CHƯƠNG 6. KINH NGHIỆM NGƯỜI DÙNG

Bạn có thể xem kết quả trong Hình 6. 17. Làm mờ thông qua các bộ lọc CSS có nghĩa là nếu chúng không được hỗ trợ thì sẽ không có dự phòng. Có thể là một ý tưởng tốt hơn nếu thực hiện làm mờ thông qua một số phương pháp khác, phương pháp này cũng có thể đóng vai trò là phương án dự phòng [e. g. , phương thức box-shadow mà chúng ta đã thấy trong bí mật trước]. Điều này cũng sẽ cứu chúng ta khỏi “hiệu ứng hào quang” mà bạn có thể thấy trên các cạnh của Hình 6. 17. Lưu ý cách trong Hình 6. 18 nơi chúng tôi sử dụng bóng để làm mờ, vấn đề này đã biến mất

HÌNH 6. 18 Áp dụng làm mờ thông qua các bộ lọc CSS và

CHƠI. chơi. bí mật css. io/deemphasizing-blur

làm mờ thông qua bóng hộp, cũng đóng vai trò là dự phòng

Đội mũ cho Hakim El Hattab [hakim. se] để đưa ra một hiệu ứng tương tự [phòng thí nghiệm. hakim. se/avgrund]. Ngoài ra, trong phiên bản hiệu ứng của Hakim, nội dung cũng trở nên nhỏ hơn thông qua biến đổi scale[], để tăng thêm ảo giác rằng hộp thoại đang tiến gần hơn về mặt vật lý với chúng ta

■ Hiệu ứng bộ lọc w3. org/TR/hiệu ứng bộ lọc

ĐẦU MŨ

RELATED

SPECS

■ Chuyển tiếp CSS w3. org/TR/css-chuyển tiếp

BÍ MẬT #33. KHỬ NÉT BẰNG CÁCH LÀM Mờ

243

34

Gợi ý cuộn Điều kiện tiên quyết Độ dốc CSS, kích thước nền

Vấn đề ■ Ada Catlace ■ Alan Purring

Thanh cuộn là điều khiển chính để chỉ ra rằng có nhiều nội dung trong một phần tử hơn là bắt mắt. Tuy nhiên, chúng thường cồng kềnh và gây mất tập trung về mặt thị giác, vì vậy các hệ điều hành hiện đại đã bắt đầu hợp lý hóa chúng,

■ Schrödingcat

thường ẩn chúng hoàn toàn cho đến khi người dùng thực sự tương tác với

■ Tim Berners-Lee

phần tử có thể cuộn

■ WebKitty Json 6. 19 ■HÌNH

hộp có nhiều nội dung hơn và ■ThisVoid có thể cuộn được, nhưng trừ khi bạn tương tác với nó, bạn sẽ không biết

Mặc dù ngày nay thanh cuộn hiếm khi được sử dụng để điều khiển thao tác cuộn [thay vào đó, người dùng có xu hướng cuộn qua cử chỉ], cho thấy rằng có nhiều nội dung trong một phần tử hơn những gì bắt mắt là thông tin rất hữu ích giúp truyền đạt một cách tinh tế, ngay cả đối với . Các nhà thiết kế UX làm việc trên Google Reader, một trình đọc nguồn cấp dữ liệu [hiện đã ngừng hoạt động] của Google, đã tìm ra một cách rất tao nhã để chỉ ra điều này. khi ma co

244

CHƯƠNG 6. KINH NGHIỆM NGƯỜI DÙNG

có nhiều nội dung hơn, một bóng tối tinh tế được hiển thị ở phía trên và/hoặc phía dưới của thanh bên [Hình 6. 20]

HÌNH 6. 20 Mẫu UX thanh lịch của Google Reader để chỉ ra rằng cần phải cuộn để xem toàn bộ nội dung của thanh bên Trái. Cuộn hết cỡ lên giữa. Cuộn đến giữa danh sách nguồn cấp dữ liệu Phải. Đã cuộn tất cả xuống phía dưới

Tuy nhiên, để đạt được hiệu ứng này trong Google Reader, khá nhiều kịch bản đã được sử dụng. Điều đó có thực sự cần thiết hay chúng ta có thể đạt được hiệu quả tương tự với CSS không?

Giải pháp Trước tiên hãy bắt đầu với một số đánh dấu đơn giản, một danh sách đơn giản không có thứ tự với một số nội dung giữ chỗ [tên mèo lập dị. ]

    HTML

  • Ada Catlace
  • Alan Purring
  • Schrödingcat
  • Tim Berners-Lee
  • WebMèo con
  • Json
  • vô hiệu
  • Neko
  • NaN
  • Cát5
  • BÍ MẬT #34. GỢI Ý CUỘN

    245

  • véc tơ

Sau đó, chúng ta có thể áp dụng một số kiểu dáng cơ bản cho

    để làm cho nó nhỏ hơn nội dung của nó và có thể cuộn được

    tràn ra. tự động; . 10em; . 8em; . . 3 em. 5em; . 1px màu bạc nguyên khối;

    ■ Ada Catlace ■ Alan Purring ■ Schrödingcat ■ Tim Purrners-Lee ■ WebKitty

    Đây là nơi mọi thứ bắt đầu trở nên thú vị. Hãy áp dụng một bóng tối ở trên cùng, với một gradient xuyên tâm

    lai lịch. radial-gradient[ở trên cùng, rgba[0,0,0,. 2], minh bạch 70%] không lặp lại; . 100% 15px;

    ■ Json

    HÌNH 6. 21

    ■ Vô hiệu

    bóng tối hàng đầu của chúng tôi

    Bạn có thể xem kết quả trong Hình 6. 21. Hiện tại nó vẫn ở cùng một vị trí khi chúng tôi cuộn. Điều này ngang bằng với cách hoạt động của hình nền theo mặc định. vị trí của chúng được cố định so với phần tử, bất kể phần tử được cuộn bao xa. Điều này cũng áp dụng cho hình ảnh có nền-

    tập tin đính kèm. đã sửa. Sự khác biệt duy nhất của chúng là chúng cũng giữ nguyên vị trí khi trang tự cuộn. Có cách nào để có được một hình nền để cuộn với nội dung của một phần tử không? . Tuy nhiên, vấn đề đã khá rõ ràng và một từ khóa background-attachment mới đã được thêm vào Backgrounds & Borders Level 3 [w3. org/TR/css3background/#local0] để giải quyết nó. địa phương. Tuy nhiên, tập tin đính kèm nền. local không giải quyết được trường hợp sử dụng của chúng tôi ngay lập tức. Nếu chúng ta áp dụng nó cho độ dốc bóng của chúng ta, nó sẽ cho chúng ta kết quả hoàn toàn ngược lại. chúng ta có một cái bóng khi chúng ta cuộn hết cỡ đến

    246

    CHƯƠNG 6. KINH NGHIỆM NGƯỜI DÙNG

    trên cùng, nhưng khi chúng tôi cuộn xuống, bóng tối biến mất. Tuy nhiên, đó là một sự khởi đầu — chúng ta đang bắt đầu đi đến một nơi nào đó. Bí quyết là sử dụng hai nền. một cho bóng và một về cơ bản là hình chữ nhật màu trắng để che bóng, hoạt động như một mặt nạ. Nền tạo bóng sẽ có giá trị mặc định

    tệp đính kèm nền [cuộn], vì chúng tôi muốn nó luôn ở đúng vị trí. Tuy nhiên, chúng tôi sẽ cung cấp cho nền mặt nạ một

    phần đính kèm nền của cục bộ, để nó che bóng khi chúng ta cuộn hết cỡ, nhưng cuộn theo nội dung khi chúng ta cuộn xuống, do đó để lộ bóng. Chúng tôi sẽ sử dụng một gradient tuyến tính để tạo hình chữ nhật mặt nạ, có cùng màu với nền của phần tử [trong trường hợp của chúng tôi là màu trắng]

    lai lịch. độ dốc tuyến tính [trắng, trắng], độ dốc xuyên tâm [ở trên cùng, rgba [0,0,0,. 2], trong suốt 70%]; . không lặp lại; . 100% 15px; . cục bộ, cuộn;

    Bạn có thể thấy điều này trông như thế nào trong các giai đoạn cuộn khác nhau trong Hình 6. 22. Bạn có thể nhận thấy rằng điều này dường như tạo ra hiệu ứng mong muốn, nhưng nó có một nhược điểm đáng kể. khi chúng ta chỉ cuộn nhẹ, cách bóng tối được tiết lộ rất lộn xộn và khó xử. Có cách nào làm mượt hơn không?

    ■ Ada Catlace

    HÌNH 6. 22

    ■ Ada Catlace

    ■ Ada Catlace

    ■ Alan Purring

    ■ Alan Purring

    ■ Alan Purring

    ■ Schrödingcat

    các giai đoạn cuộn

    ■ Schrödingcat

    ■ Schrödingcat

    ■ Tim Berners-Lee

    Tên đệm. Cuộn xuống một chút

    ■ Tim Purrners-Lee ■ Tim Purrners-Lee ■ WebKitty ■ WebKitty ■ WebKitty ■ Json ■ Json ■ Void

    Hai nền tảng của chúng tôi ở bên trái khác nhau. Đã cuộn hết cỡ lên trên cùng Bên phải. Cuộn xuống đáng kể

    BÍ MẬT #34. GỢI Ý CUỘN

    247

    HÌNH 6. 23 Sử dụng dải màu trắng để

    trong suốt như một nỗ lực đầu tiên để làm mờ bóng một cách trơn tru

    Tại sao trong suốt màu trắng và không chỉ

    trong suốt?

    ■ Ada Catlace ■ Ada Catlace

    ■ Ada Catlace

    ■ Alan Purring

    ■ Alan Purring

    ■ Alan Purring

    ■ Schrödingcat

    ■ Schrödingcat

    ■ Schrödingcat

    ■ Tim Berners-Lee

    ■ Tim Purrners-Lee ■ Tim Purrners-Lee ■ WebKitty ■ WebKitty ■ WebKitty ■ Json ■ Json ■ Void

    Chúng ta có thể lợi dụng thực tế là “mặt nạ” của chúng ta là một [thoái hóa]

    gradient tuyến tính và chuyển đổi nó thành một gradient thực từ trắng sang trong suốt

    độ dốc có thể bao gồm các sắc thái của

    trắng [hsla[0,0%,100%,0] hoặc rgba[255,255,255,0]], sao cho

    màu xám khi nó chuyển từ mờ đục

    nhẹ nhàng tiết lộ bóng của chúng tôi

    trắng sang đen trong suốt. Nếu các trình duyệt đang nội suy màu sắc trong cái được gọi là không gian RGBA được nhân trước theo thông số kỹ thuật, thì điều này không nên

    lai lịch. độ dốc tuyến tính [màu trắng, hsla [0,0%, 100%, 0]], độ dốc xuyên tâm [ở trên cùng, rgba [0,0,0,. 2],

    xảy ra. Nội suy khác nhau al-

    trong suốt 70%];

    gorithms nằm ngoài phạm vi của cuốn sách này, nhưng có rất nhiều tài liệu trên mạng này

    đây là một bước đi đúng hướng. Như bạn có thể thấy trong Hình 6. 23, nó dần dần để lộ bóng, như chúng ta muốn. Tuy nhiên, nó hiện đang có một lỗ hổng khá nghiêm trọng. nó không còn che khuất hoàn toàn bóng khi chúng ta cuộn hết cỡ lên trên cùng. Chúng ta có thể khắc phục điều này bằng cách di chuyển điểm dừng màu trắng xuống thấp hơn một chút [chính xác là 15px, bằng chiều cao bóng của chúng ta], để chúng ta có được một vùng màu trắng đồng nhất trước khi bắt đầu mờ dần. Hơn nữa, chúng ta cần tăng kích thước của “mặt nạ” lớn hơn bóng đổ, nếu không chúng ta sẽ không nhận được độ dốc. Chiều cao chính xác phụ thuộc vào độ mịn mà chúng ta muốn hiệu ứng [i. e. , bóng sẽ hiện ra nhanh như thế nào khi chúng ta cuộn?]. Sau một số thử nghiệm, có vẻ như 50px là một giá trị hợp lý. Mã cuối cùng trông như sau và bạn có thể xem kết quả trong Hình 6. 24

    248

    CHƯƠNG 6. KINH NGHIỆM NGƯỜI DÙNG

    ■ Ada Catlace

    ■ Ada Catlace

    ■ Alan Purring

    ■ Alan Purring

    ■ Schrödingcat

    ■ Schrödingcat ■ Tim Purrners-Lee ■ WebKitty

    ■ Tim Purrners-Lee ■ WebKitty

    ■ Ada Catlace

    HÌNH 6. 24

    ■ Alan Purring

    kết quả cuối cùng

    ■ Schrödingcat ■ Tim Purrners-Lee ■ WebKitty ■ Json

    ■ Json

    ■ Vô hiệu

    lai lịch. độ dốc tuyến tính [màu trắng 30%, trong suốt], độ dốc xuyên tâm [ở mức 50% 0, rgba [0,0,0,. 2], trong suốt 70%]; . không lặp lại; . 100% 50px, 100% 15px; . cục bộ, cuộn;

    Tất nhiên, để đạt được hiệu ứng ban đầu, chúng ta cần thêm hai chuyển màu cho bóng dưới và mặt nạ của nó, nhưng logic hoàn toàn giống nhau, vì vậy đây có thể là bài tập dành cho người đọc [hoặc xem phần Play sau. ví dụ cho giải pháp]. CHƠI. chơi. bí mật css. io/scrolling-hints Lời khen dành cho Roman Komarov vì đã đưa ra phiên bản đầu tiên của hiệu ứng này [kizu. ru/en/fun/shadowscroll]. Phiên bản của anh ấy sử dụng các phần tử giả và định vị thay vì hình nền và có thể là một giải pháp thay thế thú vị cho một số trường hợp sử dụng nhất định

    ■ CSS Backgrounds & Borders w3. org/TR/css-backgrounds

    ĐẦU MŨ

    RELATED

    SPECS

    ■ CSS Image Values w3. org/TR/css-images

    BÍ MẬT #34. GỢI Ý CUỘN

    249

    35

    So sánh hình ảnh tương tác Vấn đề Đôi khi nảy sinh nhu cầu thể hiện sự khác biệt về hình ảnh giữa hai hình ảnh, thường là so sánh trước và sau. Ví dụ: thể hiện tác động của thao tác chỉnh sửa ảnh trong danh mục đầu tư, kết quả của một số phương pháp làm đẹp nhất định trên trang web của chuyên gia thẩm mỹ hoặc kết quả có thể nhìn thấy của một sự kiện thảm khốc ở một khu vực địa lý. Giải pháp phổ biến nhất là chỉ đặt các hình ảnh cạnh nhau. Tuy nhiên, theo cách này, mắt người chỉ nhận thấy những điểm khác biệt rất dễ thấy và bỏ sót những điểm nhỏ hơn. Điều này tốt nếu so sánh không quan trọng hoặc sự khác biệt lớn, nhưng trong tất cả các trường hợp khác, chúng tôi cần một cái gì đó hữu ích hơn. Có nhiều giải pháp cho vấn đề này từ góc độ UX. Một giải pháp phổ biến là hiển thị liên tiếp cả hai hình ảnh ở cùng một vị trí, thông qua hoạt ảnh GIF hoặc hoạt ảnh CSS. Điều này tốt hơn nhiều so với việc hiển thị các hình ảnh cạnh nhau, nhưng người dùng sẽ tốn thời gian để nhận thấy tất cả sự khác biệt vì họ phải đợi nhiều lần lặp lại, mỗi lần lại dán mắt vào một khu vực khác nhau của hình ảnh

    250

    CHƯƠNG 6. KINH NGHIỆM NGƯỜI DÙNG

    HÌNH 6. 25 Một ví dụ về tiện ích so sánh hình ảnh tương tác, cho phép người dùng so sánh kết quả thảm khốc của cuộc bạo loạn ở London năm 2011, từ hãng tin lớn của Anh The Guardian. Người dùng phải kéo thanh màu trắng ngăn cách hai hình ảnh, nhưng không có khả năng cho biết thanh này có thể kéo được, đó là lý do tại sao văn bản trợ giúp [“Di chuyển thanh trượt…”] là cần thiết. Lý tưởng nhất là một giao diện tốt, dễ học, không cần văn bản trợ giúp. Nguồn. người giám hộ. com/uk/ tương tác/2011/aug/09/ london-riots-before-afterphotographs

    Một giải pháp hữu ích hơn nhiều được gọi là “thanh trượt so sánh hình ảnh. ” Điều khiển này chồng cả hai hình ảnh và cho phép người dùng

    Trong một số biến thể, người dùng chỉ di chuyển chuột thay vì kéo. Điều này có lợi ích là

    kéo số chia để hiển thị cái này hay cái kia. Tất nhiên, một sự kiểm soát như vậy không

    dễ dàng hơn để thông báo và sử dụng, nhưng ex-

    không thực sự tồn tại trong HTML. Chúng ta phải mô phỏng nó thông qua các yếu tố chúng ta làm

    kinh nghiệm có thể khá khó chịu

    và đã có nhiều triển khai như vậy trong nhiều năm, thường yêu cầu các khung JavaScript và một lượng lớn mã JS. Có cách nào đơn giản hơn để thực hiện kiểm soát như vậy không?

    Giải pháp thay đổi kích thước CSS Nếu chúng ta nghĩ về nó, một thanh trượt so sánh hình ảnh về cơ bản bao gồm một hình ảnh và một phần tử có thể thay đổi kích thước theo chiều ngang, dần dần hiển thị một hình ảnh khác. Đây là nơi các khung JavaScript thường xuất hiện. để làm cho hình ảnh trên cùng có thể thay đổi kích thước theo chiều ngang. Tuy nhiên, chúng tôi không thực sự cần tập lệnh để tạo một phần tử có thể thay đổi kích thước. Trong Giao diện người dùng CSS Cấp 3 [w3. org/TR/ css3-ui/#resize], chúng tôi có một thuộc tính cho điều đó. thay đổi kích thước khiêm tốn. BÍ MẬT #35. SO SÁNH HÌNH ẢNH TƯƠNG TÁC

    251

    Nó thường là một ý tưởng tốt để áp dụng

    thay đổi kích thước. dọc thành s để duy trì khả năng thay đổi kích thước-

    Ngay cả khi bạn chưa bao giờ nghe nói về thuộc tính này, thì có lẽ bạn đã trải nghiệm hành vi của nó vì nó được đặt thành both theo mặc định trên s, điều này làm cho

    ity nhưng vô hiệu hóa thay đổi kích thước theo chiều ngang,

    chúng có thể thay đổi kích thước theo cả hai hướng. Tuy nhiên, nó thực sự có thể được thiết lập trên bất kỳ

    thường phá vỡ bố cục

    phần tử, miễn là thuộc tính tràn của nó không hiển thị. Trong hầu hết mọi thay đổi kích thước phần tử được đặt thành không theo mặc định, điều này sẽ vô hiệu hóa thay đổi kích thước. ngoài ra

    Khi đối tượng phù hợp và đối tượng-

    cả hai, nó cũng chấp nhận các giá trị ngang và dọc, mà lại

    vị trí đạt được phổ biến hơn

    nghiêm ngặt hướng thay đổi kích thước

    hỗ trợ trình duyệt, điều này sẽ không thành vấn đề vì chúng tôi sẽ có thể kiểm soát cách hình ảnh chia tỷ lệ theo cách giống như cách chúng tôi có thể kiểm soát tỷ lệ hình nền

    Điều này có thể khiến người ta thắc mắc. chúng ta có thể sử dụng thuộc tính này để triển khai thanh trượt hình ảnh của mình không? . Suy nghĩ đầu tiên của chúng tôi có thể là chỉ bao gồm hai yếu tố. Tuy nhiên, áp dụng thay đổi kích thước trực tiếp cho một hình ảnh sẽ trông rất tệ, vì thay đổi kích thước hình ảnh trực tiếp làm biến dạng nó. Sẽ hợp lý hơn khi áp dụng nó cho một thùng chứa

    Do đó, chúng tôi kết thúc với đánh dấu như sau

    HTML

    Sau đó, chúng ta cần áp dụng một số CSS cơ bản để định vị và kích thước

    thanh trượt hình ảnh { vị trí. liên quan đến; . chặn Nội tuyến; . thanh trượt hình ảnh > div { vị trí. tuyệt đối;

    HÌNH 6. 26

    hàng đầu. 0; . 0; . 0;

    Sau một số kiểu dáng cơ bản, đây là

    chiều rộng. 50%;

    đã bắt đầu giống với một

    tràn ra. ẩn giấu;

    thanh trượt hình ảnh, nhưng chúng tôi chưa thể thay đổi độ rộng của hình ảnh trên cùng

    252

    }

    CHƯƠNG 6. KINH NGHIỆM NGƯỜI DÙNG

    thanh trượt hình ảnh img { hiển thị. chặn;

    Ngay bây giờ kết quả giống như Hình 6. 26 nhưng vẫn tĩnh. Nếu chúng tôi thay đổi chiều rộng theo cách thủ công, chúng tôi có thể thấy nó trải qua tất cả các giai đoạn mà người dùng sẽ thay đổi kích thước của nó thành. Để làm cho chiều rộng thay đổi linh hoạt theo tương tác của người dùng, thông qua thuộc tính resize, chúng ta cần thêm 2 khai báo

    thanh trượt hình ảnh > div { vị trí. tuyệt đối; . 0; . 0; . 0; . 50%; . ẩn giấu; . nằm ngang;

    Thay đổi trực quan duy nhất là trình xử lý thay đổi kích thước hiện xuất hiện ở góc dưới cùng bên phải của hình ảnh trước đó [Hình 6. 27], nhưng bây giờ chúng ta có thể kéo và thay đổi kích thước cho phù hợp với nội dung của chúng ta. Tuy nhiên, chơi với widget của chúng tôi một chút sẽ bộc lộ một vài điểm yếu. ■ Chúng tôi có thể thay đổi kích thước quá khứ chiều rộng của hình ảnh. ■ Trình xử lý thay đổi kích thước khó phát hiện. Vấn đề đầu tiên rất dễ giải quyết. Tất cả những gì chúng ta cần là chỉ định chiều rộng tối đa là 100%. Tuy nhiên, vấn đề thứ hai phức tạp hơn một chút. Thật không may, vẫn chưa có cách tiêu chuẩn để tạo kiểu cho trình xử lý thay đổi kích thước. Một số công cụ kết xuất hỗ trợ các phần tử giả độc quyền [chẳng hạn như. -webkit-

    HÌNH 6. 27 Thanh trượt hình ảnh của chúng tôi hiện thực sự hoạt động giống như một thanh trượt hình ảnh, nhưng vẫn có một số vấn đề

    resizer] cho việc này, nhưng kết quả của chúng bị hạn chế, cả về hỗ trợ trình duyệt cũng như tính linh hoạt về kiểu dáng. Tuy nhiên, hy vọng không bị mất. hóa ra việc phủ một phần tử giả trên núm điều khiển thay đổi kích thước không can thiệp vào chức năng của nó, ngay cả khi không có sự kiện con trỏ. không ai. Vì vậy, một giải pháp đa trình duyệt để tạo kiểu cho trình xử lý thay đổi kích thước sẽ chỉ là…phủ một trình duyệt khác lên trên trình xử lý đó. Hãy làm điều đó

    BÍ MẬT #35. SO SÁNH HÌNH ẢNH TƯƠNG TÁC

    253

    thanh trượt hình ảnh > div. trước { nội dung. ''; . tuyệt đối; . 0; . 0; . 12px; . 12px; . trắng; . ew-thay đổi kích thước;

    HÌNH 6. 28

    }

    Tạo kiểu cho trình xử lý thay đổi kích thước dưới dạng hình vuông màu trắng, bằng cách phủ một phần tử giả lên nó

    Lưu ý con trỏ. khai báo thay đổi kích thước ew. điều này bổ sung thêm khả năng chi trả, vì nó gợi ý cho người dùng rằng họ có thể sử dụng khu vực này làm trình xử lý thay đổi kích thước. Tuy nhiên, chúng ta không nên phụ thuộc vào những thay đổi của con trỏ vì khả năng chi trả duy nhất của chúng ta, bởi vì chúng chỉ hiển thị khi người dùng đã tương tác với một điều khiển. Ngay bây giờ, trình xử lý thay đổi kích thước của chúng ta sẽ xuất hiện dưới dạng một hình vuông màu trắng [xem Hình 6. 28]. Tại thời điểm này, chúng ta có thể tiếp tục và tạo kiểu cho nó theo ý thích của mình. Ví dụ: để tạo thành một hình tam giác màu trắng với khoảng cách 5px từ các cạnh của hình ảnh [Hình 6. 29], chúng ta có thể viết

    đệm. 5px;

    HÌNH 6. 29 Tạo kiểu giả cho trình thay đổi kích thước giả-

    linear-gradient[-45deg, trắng 50%, trong suốt 0]; . hộp nội dung;

    phần tử dưới dạng hình tam giác với khoảng cách 5px từ các cạnh của hình ảnh

    Là một cải tiến bổ sung, chúng tôi có thể áp dụng tùy chọn người dùng. không cho cả hai hình ảnh, do đó việc không lấy được trình xử lý thay đổi kích thước sẽ không dẫn đến việc chúng bị chọn một cách vô nghĩa. Tóm lại, mã đầy đủ sẽ như thế này

    thanh trượt hình ảnh { vị trí. liên quan đến; . chặn Nội tuyến;

    254

    CHƯƠNG 6. KINH NGHIỆM NGƯỜI DÙNG

    thanh trượt hình ảnh > div { vị trí. tuyệt đối; . 0; . 0; . 0; . 50%; . 100%; . ẩn giấu; . nằm ngang; . thanh trượt hình ảnh > div. trước { nội dung. ''; . tuyệt đối; . 0; . 0; . 12px; . 12px; . 5px; . linear-gradient[-45deg, trắng 50%, trong suốt 0]; . hộp nội dung; . ew-thay đổi kích thước; . thanh trượt hình ảnh img { hiển thị. chặn; . không ai;

    CHƠI. chơi. bí mật css. io/thanh trượt hình ảnh

    Giải pháp nhập phạm vi Phương pháp thay đổi kích thước CSS được mô tả trong phần trước hoạt động tốt và cần rất ít mã. Tuy nhiên, nó có một vài thiếu sót

    BÍ MẬT #35. SO SÁNH HÌNH ẢNH TƯƠNG TÁC

    255

    ■ Không thể truy cập bằng bàn phím. ■ Kéo là cách duy nhất để thay đổi kích thước hình ảnh trên cùng, điều này có thể gây nhàm chán cho những hình ảnh lớn hoặc người dùng bị suy giảm vận động. Cũng có thể nhấp vào một điểm và thay đổi kích thước hình ảnh theo điểm đó mang lại trải nghiệm tốt hơn nhiều. ■ Người dùng chỉ có thể thay đổi kích thước hình ảnh trên cùng từ góc dưới cùng bên phải của nó, điều này có thể khó nhận thấy, ngay cả khi chúng tôi tạo kiểu cho nó theo cách đã mô tả trước đó. Nếu chúng tôi sẵn sàng sử dụng một chút tập lệnh, chúng tôi có thể sử dụng điều khiển thanh trượt [đầu vào phạm vi HTML] được phủ lên trên hình ảnh để kiểm soát việc thay đổi kích thước, giải quyết cả ba vấn đề. Bởi vì dù sao thì chúng ta cũng đang sử dụng JS, nên chúng ta có thể thêm tất cả các phần tử bổ sung thông qua tập lệnh, vì vậy chúng ta có thể bắt đầu với phần đánh dấu rõ ràng nhất có thể

    HTML

    Sau đó, mã JS của chúng tôi sẽ chuyển đổi nó thành mã sau và thêm một sự kiện trên thanh trượt để nó cũng đặt chiều rộng của div

    HTML

    Mã JavaScript khá đơn giản

    $$['. thanh trượt hình ảnh']. forEach[function[slider] { // Tạo thêm div và // bọc nó quanh ảnh đầu tiên

    256

    CHƯƠNG 6. KINH NGHIỆM NGƯỜI DÙNG

    JS

    var div = tài liệu. createElement['div']; . querySelector['img']; . chènB Before[img, div]; . appendChild[img]; . createElement['đầu vào']; . loại = 'phạm vi'; . oninput = function[] { div. Phong cách. chiều rộng = cái này. giá trị + '%'; . appendChild[phạm vi];

    CSS mà chúng tôi sẽ sử dụng làm điểm bắt đầu về cơ bản giống như trong giải pháp trước đó. Chúng tôi sẽ chỉ xóa những phần chúng tôi không cần nữa. ■ Chúng tôi không cần thuộc tính thay đổi kích thước. ■ Chúng tôi không cần. thanh trượt hình ảnh > div. trước quy tắc, bởi vì chúng tôi không còn có bộ thay đổi kích thước. ■ Chúng tôi không cần chiều rộng tối đa vì thanh trượt sẽ kiểm soát điều đó. Đây là cách mã CSS của chúng tôi sẽ xử lý những sửa đổi này

    thanh trượt hình ảnh { vị trí. liên quan đến; . chặn Nội tuyến; . thanh trượt hình ảnh > div { vị trí. tuyệt đối; . 0; . 0; . 0; . 50%; . ẩn giấu;

    HÌNH 6. 30 Kiểm soát của chúng tôi hiện đã hoạt động, nhưng chúng tôi vẫn cần định kiểu đầu vào phạm vi đó

    BÍ MẬT #35. SO SÁNH HÌNH ẢNH TƯƠNG TÁC

    257

    }. thanh trượt hình ảnh img { hiển thị. chặn; . không ai;

    sử dụng đầu vào. trong phạm vi

    TIP

    thay vì chỉ nhập vào

    chỉ định kiểu đầu vào phạm vi nếu

    Nếu chúng tôi kiểm tra mã này ngay bây giờ, bạn sẽ thấy rằng nó đã hoạt động, nhưng nó trông rất tệ. có một đầu vào phạm vi được đặt ngẫu nhiên dưới hình ảnh của chúng tôi

    phạm vi đầu vào được hỗ trợ. sau đó

    [Hình 6. 30]. Chúng ta cần áp dụng một số CSS để đặt nó lên trên

    bạn có thể sử dụng thác để ẩn nó

    chúng, và làm cho nó rộng như chúng

    hoặc tạo kiểu khác trong các trình duyệt cũ hơn

    đầu vào thanh trượt hình ảnh { vị trí. tuyệt đối; . 0; . 10px; . 100%; . 0;

    HÌNH 6. 31 Đầu vào phạm vi của chúng tôi được tạo kiểu để phủ lên hình ảnh

    Như bạn có thể thấy trong Hình 6. 31, điều này đã có vẻ tốt. Có một số phần tử giả độc quyền để định kiểu đầu vào phạm vi chính xác theo cách chúng tôi muốn. Bao gồm các. -moz-phạm vi theo dõi,. -ms-theo dõi,. -

    webkit-thanh trượt-thumb,. -moz-range-thumb, và. -ms-thumb. Giống như hầu hết các tính năng độc quyền, kết quả của chúng không nhất quán, mỏng manh và không thể đoán trước, vì vậy tôi khuyên bạn không nên sử dụng chúng, trừ khi bạn thực sự phải làm vậy. Mày đã được cảnh báo

    258

    CHƯƠNG 6. KINH NGHIỆM NGƯỜI DÙNG

    Tuy nhiên, nếu chúng ta chỉ muốn thống nhất trực quan đầu vào phạm vi với điều khiển hơn một chút, chúng ta có thể sử dụng chế độ hòa trộn và/hoặc bộ lọc. Các chế độ hòa trộn nhân lên, màn hình hoặc độ sáng dường như tạo ra kết quả tốt. Ngoài ra, lọc. độ tương phản [4] sẽ làm cho thanh trượt có màu đen và trắng và giá trị độ tương phản thấp hơn 1 sẽ làm cho thanh trượt có màu xám hơn. Các khả năng là vô tận và không có lựa chọn tối ưu chung nào ở đây. Bạn thậm chí có thể kết hợp các chế độ hòa trộn và bộ lọc, như vậy

    lọc. tương phản[. 5]; . độ sáng;

    Chúng tôi cũng có thể tăng diện tích mà người dùng có thể sử dụng để thay đổi kích thước nhằm mang lại trải nghiệm thú vị hơn [theo Định luật Fitts], bằng cách giảm chiều rộng và tạo sự khác biệt bằng các biến đổi CSS

    chiều rộng. 50%; . tỷ lệ [2]; . phía dưới bên trái;

    HÌNH 6. 32 Bạn có thể xem kết quả của cả hai phương pháp điều trị trong Hình 6. 32. Một lợi ích khác của phương pháp này—mặc dù chỉ là tạm thời—là các đầu vào phạm vi hiện có hỗ trợ trình duyệt tốt hơn so với thuộc tính thay đổi kích thước

    Sử dụng các chế độ hòa trộn và bộ lọc để thống nhất trực quan đầu vào phạm vi với điều khiển của chúng tôi và chuyển đổi CSS để làm cho nó lớn hơn

    Lời khen dành cho Dudley Storey vì đã đưa ra phiên bản đầu tiên của giải pháp này [demosthenes. info/blog/819/A- Before-And-afterImage-So sánh-Slide-Control-in-HTML5]. ĐẦU MŨ

    BÍ MẬT #35. SO SÁNH HÌNH ẢNH TƯƠNG TÁC

    259

    ■ Giao diện Người dùng Cơ bản CSS w3. org/TR/css3-ui ■ Giá trị hình ảnh CSS w3. org/TR/css-images ■ Hình nền và đường viền CSS w3. org/TR/css-backgrounds ■ Hiệu ứng bộ lọc w3. org/TR/filter-effects ■ Tổng hợp và Trộn w3. org/TR/compositing ■ Chuyển đổi CSS w3. org/TR/css-transforms

    260

    CHƯƠNG 6. KINH NGHIỆM NGƯỜI DÙNG

    RELATED

    SPECS

    Cấu trúc & Bố cục

    7

    36

    Kích thước nội tại Vấn đề Như chúng ta đã biết, nếu chúng ta không đặt chiều cao cụ thể cho một phần tử, nó sẽ tự động điều chỉnh theo nội dung của nó. Điều gì sẽ xảy ra nếu chúng ta muốn một hành vi tương tự cho

    chiều rộng là tốt?

    Một số tiếp theo […]

    HTML

    Ngài Adam Catlace vĩ đại được đặt theo tên của Nữ bá tước Ada Lovelace, lập trình viên đầu tiên

    Thêm văn bản […]

    Cũng giả sử rằng chúng ta đang áp dụng một số kiểu dáng cơ bản cho chúng, chẳng hạn như đường viền xung quanh các hình. Theo mặc định, điều này trông giống như Hình 7. 1. Chúng tôi muốn làm cho các hình rộng bằng hình ảnh mà chúng chứa [có thể thay đổi 262

    CHƯƠNG 7. KẾT CẤU & BỐ CỤC

    về kích thước] và căn giữa chúng theo chiều ngang. Kết xuất hiện tại là khá xa

    Giả sử chúng ta có một số văn bản ở đây. Bacon ipsum dolor sit amet gà tây veniam shankle, culpa xương sườn ngắn kevin t-bone occaecat

    từ những gì chúng ta muốn. các dòng văn bản dài hơn nhiều so với hình ảnh. Làm cách nào để chúng tôi làm cho chiều rộng của hình được xác định bởi chiều rộng của hình ảnh chứa trong đó thay vì chiều rộng của hình gốc?* Trong suốt sự nghiệp của mình, có lẽ chúng tôi đã xây dựng danh sách các kiểu CSS của riêng mình dẫn đến hành vi chiều rộng như vậy

    Ngài Adam Catlace vĩ đại được đặt theo tên của Nữ bá tước Ada Lovelace, lập trình viên đầu tiên từng. Chúng tôi cũng có một số văn bản hơn ở đây. Thịt nai của Et workingum nostrud, ut veniam sint kielbasa ullamco pancetta

    HÌNH 7. 1

    ■ Làm nổi phần cho chúng ta chiều rộng phù hợp, nhưng cũng làm thay đổi đáng kể bố cục của hình, theo những cách mà chúng ta có thể không muốn [Hình 7. 2]

    Cách thức đánh dấu của chúng tôi được hiển thị mặc định, sau một chút CSS cho đường viền và phần đệm

    ■ Áp dụng hiển thị. inline-block vào hình sẽ điều chỉnh kích thước của nó dựa trên nội dung của nó, nhưng không phải theo cách chúng ta muốn [Hình 7. 3]. Ngoài ra, ngay cả khi

    Giả sử chúng ta có một số văn bản ở đây. Bacon ipsum dolor sit amet gà tây veniam shankle, culpa xương sườn ngắn kevin t-bone occaecat. Chúng tôi cũng có một số văn bản hơn ở đây. Thịt nai của Et workingum nostrud, ut veniam sint kielbasa ullamco pancetta

    tính toán chiều rộng ngang bằng với mong đợi của chúng tôi, sẽ rất khó để căn giữa các số liệu theo chiều ngang theo cách này. Chúng ta sẽ cần phải áp dụng văn bản-

    căn chỉnh. trung tâm đến cha mẹ của nó và căn chỉnh văn bản. để lại cho bất kỳ đứa con nào có thể có của cha mẹ đó [p, ul, ol, dl,. ]. ■ Phương án cuối cùng, các nhà phát triển thường áp dụng chiều rộng cố định hoặc chiều rộng tối đa cho các hình và áp dụng chiều rộng tối đa. 100% cho con số > img. Tuy nhiên, điều này

    Ngài Adam Catlace vĩ đại được đặt theo tên của Nữ bá tước Ada Lovelace, lập trình viên đầu tiên

    HÌNH 7. 2 Cố gắng giải quyết vấn đề về chiều rộng bằng cách tạo ra các vấn đề mới

    không sử dụng hết dung lượng có sẵn, vẫn có thể tắt đối với các số liệu quá nhỏ và không phản hồi

    Giả sử chúng ta có một số văn bản ở đây. Bacon ipsum dolor sit amet gà tây veniam shankle, culpa xương sườn ngắn kevin t-bone occaecat

    Có giải pháp CSS phù hợp nào cho vấn đề này hay chúng ta nên từ bỏ và bắt đầu mã hóa một tập lệnh để tự động đặt độ rộng của hình? . Chúng tôi cũng có một số văn bản hơn ở đây. Thịt nai của Et workingum nostrud, ut veniam sint kielbasa ullamco pancetta

    Giải pháp

    HÌNH 7. 3

    Một thông số kỹ thuật tương đối mới, CSS Intrinsic & Extrinsic Sizing Module Level 3 [w3. org/TR/css3-sizing], đã xác định một số chiều rộng mới và

    Trái với mong đợi của chúng tôi,

    trưng bày. khối nội tuyến không dẫn đến chiều rộng mà chúng tôi muốn

    chiều cao từ khóa, một trong những từ khóa hữu ích nhất là nội dung tối thiểu. Từ khóa này cung cấp cho chúng ta chiều rộng của phần tử không thể phá vỡ lớn nhất bên trong hộp [i. e. , từ hoặc hình ảnh rộng nhất hoặc hộp có chiều rộng cố định]. Đây chính xác là những gì chúng ta cần. Bây giờ, tạo cho các hình của chúng ta một chiều rộng thích hợp và căn giữa chúng theo chiều ngang đơn giản là hai dòng mã

    * Trong thuật ngữ đặc tả CSS, chúng ta cần xác định chiều rộng từ bên trong thay vì bên ngoài. BÍ MẬT #36. KÍCH THƯỚC BÊN TRONG

    263

    Một giá trị khác, nội dung tối đa, sẽ cho chúng ta chiều rộng giống như chúng ta

    nhân vật {

    cưa với màn hình. nội tuyến-

    chiều rộng. nội dung tối thiểu;

    chặn sớm hơn. Và nội dung phù hợp

    lề. tự động;

    cung cấp cho chúng tôi hành vi tương tự như float [thường giống như min-

    }

    nội dung, nhưng không phải luôn luôn]

    Bạn có thể xem kết quả trong Hình 7. 4. Để cung cấp một dự phòng duyên dáng cho các trình duyệt cũ hơn, chúng tôi có thể kết hợp kỹ thuật này với một

    chiều rộng, như vậy. Giả sử chúng ta có một số văn bản ở đây. Bacon ipsum dolor sit amet gà tây veniam shankle, culpa xương sườn ngắn kevin t-bone occaecat

    hình { chiều rộng tối đa. 300px; . nội dung tối thiểu; . tự động;

    Ngài Adam Catlace vĩ đại được đặt theo tên của Nữ bá tước Ada Lovelace, lập trình viên đầu tiên. Chúng tôi cũng có một số văn bản hơn ở đây. Thịt nai của Et workingum nostrud, ut veniam sint kielbasa ullamco pancetta

    }

    HÌNH 7. 4 Kết quả cuối cùng

    hình > img { chiều rộng tối đa. thừa kế;

    Trên một trình duyệt hiện đại, khai báo độ rộng tối đa sau sẽ ghi đè lên cái trước và nếu hình có kích thước nội tại, chiều rộng tối đa. kế thừa không có tác dụng. CHƠI. chơi. bí mật css. io/intrinsic-sizing Lời khuyên cho Dudley Storey [demosthenes. info] để đưa ra trường hợp sử dụng này [demosthenes. thông tin/blog/662/Thiết kế-Từ trong ra ngoài-Với-CSS-Nội dung tối thiểu]. MẸO HAY ■ Định cỡ CSS bên trong & bên ngoài w3. định cỡ org/TR/css3

    264

    CHƯƠNG 7. KẾT CẤU & BỐ CỤC

    RELATED

    SPECS

    37

    Điều chỉnh độ rộng cột của bảng Sự cố Mặc dù chúng tôi đã ngừng sử dụng bảng để bố trí từ lâu, nhưng các bảng vẫn có vị trí của chúng trên các trang web hiện đại, đối với dữ liệu dạng bảng như số liệu thống kê, email, danh sách các mục có nhiều siêu dữ liệu và nhiều thứ khác. Ngoài ra, chúng ta có thể làm cho các phần tử khác hoạt động giống như các phần tử liên quan đến bảng, bằng cách sử dụng các từ khóa liên quan đến bảng cho thuộc tính hiển thị. Tuy nhiên, đôi khi có vẻ thuận tiện, bố cục của chúng rất khó đoán đối với nội dung động. Điều này là do thực tế là các kích thước cột được điều chỉnh dựa trên nội dung của chúng và ngay cả các khai báo rõ ràng về chiều rộng cũng được xử lý giống như các gợi ý hơn, như Hình 7. 5 minh họa. Vì lý do này, chúng tôi thường kết thúc bằng việc sử dụng các yếu tố khác nhau ngay cả đối với dữ liệu dạng bảng hoặc chúng tôi chỉ chấp nhận tính không thể đoán trước của tất cả. Có cách nào chúng ta có thể khiến các bảng hoạt động bình thường không?

    Giải pháp Giải pháp có ở dạng CSS 2 ít được biết đến. 1 tài sản được gọi là

    bố trí bảng. Giá trị mặc định của nó là tự động, dẫn đến cái gọi là thuật toán bố trí bảng tự động, với hành vi quen thuộc được hiển thị trong 266

    CHƯƠNG 7. KẾT CẤU & BỐ CỤC

    chỉ định chiều rộng ô, chúng sẽ được chỉ định một ô tùy thuộc Nếu chúng ta không… vào nội dung của chúng. Lưu ý cách ô có nhiều nội dung hơn ở đây rộng hơn nhiều

    HÌNH 7. 5 Thuật toán bố trí bảng mặc định cho các bảng có 2 cột và nội dung đa dạng [vùng chứa của các bảng này được hiển thị bằng nét đứt

    chỉ định chiều rộng ô, chúng sẽ được chỉ định một Nếu chúng ta không…

    ranh giới]

    điều đó phụ thuộc vào nội dung của họ. Lưu ý cách ô có nhiều nội dung hơn ở đây rộng hơn nhiều

    Tất cả các hàng đều tham gia tính toán chiều rộng, không chỉ hàng đầu tiên

    Lưu ý cách kích thước ở đây khác với ví dụ trước

    Nếu chúng ta chỉ định chiều rộng, nó

    …và tôi có chiều rộng là 2000px. Bởi vì

    sẽ không phải lúc nào cũng vậy

    không có đủ dung lượng cho 3000px, chúng

    đã theo dõi. tôi có chiều rộng

    giảm tỷ lệ thuận, đến 33. 3% và 66. 6%

    của 1000px…

    của tổng chiều rộng

    Nếu chúng ta ngăn gói từ, bảng có thể trở nên

    …và tràn văn bản. dấu chấm lửng cũng không giúp được gì

    rộng nó phát triển vượt ra ngoài thùng chứa của nó

    Hình ảnh lớn và khối mã cũng có thể gây ra vấn đề tương tự

    BÍ MẬT #37. CHỈNH SỬA CHIỀU RỘNG CỘT BẢNG

    267

    Hình 7. 5. Tuy nhiên, có một giá trị thứ hai, cố định, dẫn đến hành vi dễ đoán hơn. Nó để lại nhiều hơn cho tác giả [bạn, đó là. ] và ít hơn tùy thuộc vào công cụ kết xuất. Kiểu dáng được tôn trọng và không được coi như một loại gợi ý nào đó, phần tràn hoạt động giống như bất kỳ phần tử nào khác [bao gồm phần tràn văn bản] và nội dung bảng chỉ ảnh hưởng đến chiều cao của mỗi hàng chứ không ảnh hưởng gì khác. Ngoài việc dễ dự đoán và thuận tiện hơn, thuật toán bố trí bảng cố định cũng nhanh hơn đáng kể. Vì nội dung của bảng không ảnh hưởng đến độ rộng của ô nên không cần vẽ lại/sơn lại trong khi trang đang tải xuống. Tất cả chúng ta đều quen thuộc với hình ảnh phá cách của một bảng liên tục điều chỉnh lại độ rộng của các cột khi trang đang tải xuống. Điều này không bao giờ xảy ra với cách bố trí bảng cố định. Để sử dụng nó, chúng ta áp dụng thuộc tính cho các phần tử và phần tử có hiển thị. cái bàn. Lưu ý rằng bạn cần chỉ định chiều rộng cho các bảng này [ngay cả khi đó là 100%] để điều kỳ diệu xảy ra. Ngoài ra, đối với văn bản-

    tràn ra. dấu chấm lửng để hoạt động, chúng ta cũng cần đặt chiều rộng cho cột đó. Đó là tất cả. Bạn có thể xem kết quả trong Hình 7. 6

    bảng { bố cục bảng. đã sửa; . 100%;

    CHƠI. chơi. bí mật css. io/table-column-widths Lời khuyên dành cho Chris Coyier [thủ thuật css. com] vì đã nghĩ ra kỹ thuật này [css-tricks. com/fixing-tables-long-strings]. ĐẦU MŨ

    268

    CHƯƠNG 7. KẾT CẤU & BỐ CỤC

    chỉ định chiều rộng ô, chúng sẽ được chỉ định một ô tùy thuộc vào

    Nếu chúng ta không…

    nội dung. Lưu ý cách ô có nhiều nội dung hơn ở đây rộng hơn nhiều

    HÌNH 7. 6 Các bảng tương tự như trong Hình 7. 5, nhưng với cách bố trí bảng. áp dụng cố định. Lưu ý những điều sau đây, theo thứ tự. ■ Khi chúng ta không xác định bất kỳ chiều rộng nào, tất cả các cột đều có cùng chiều rộng

    chỉ định chiều rộng ô, chúng sẽ được chỉ định một ô tùy thuộc vào

    Nếu chúng ta không…

    nội dung. Lưu ý cách ô có nhiều nội dung hơn ở đây rộng hơn nhiều

    Tất cả các hàng tham gia tính toán

    Chú ý kích thước ở đây như thế nào

    chiều rộng, không chỉ cái đầu tiên

    khác với ví dụ trước

    ■ Hàng thứ hai không ảnh hưởng đến độ rộng của cột. ■ Chiều rộng lớn được áp dụng nguyên trạng, không bị thu nhỏ. ■ Tràn và văn bản-

    thuộc tính tràn được tôn trọng. ■ Nội dung có thể tràn ra ngoài các ô của bảng [nếu

    tràn có thể nhìn thấy]

    Nếu chúng tôi chỉ định chiều rộng, nó sẽ không luôn được tuân theo. Tôi có chiều rộng là 1000px… Nếu chúng tôi ngăn gói từ, bảng có thể trở nên

    …và tràn văn bản. dấu chấm lửng không h…

    rộng nó phát triển vượt ra ngoài thùng chứa của nó

    Hình ảnh lớn và khối mã cũng có thể gây ra vấn đề tương tự

    BÍ MẬT #37. CHỈNH SỬA CHIỀU RỘNG CỘT BẢNG

    269

    38

    Tạo kiểu theo số lượng anh chị em Vấn đề Có nhiều trường hợp khi chúng ta cần tạo kiểu cho các phần tử khác nhau dựa trên tổng số anh chị em mà chúng có. Trường hợp sử dụng chính là cải thiện UX và bảo tồn diện tích màn hình trong danh sách mở rộng, bằng cách ẩn các điều khiển hoặc làm cho chúng nhỏ gọn hơn khi danh sách tăng lên. Đây là vài ví dụ. ■ Danh sách email hoặc các mục dựa trên văn bản tương tự. Nếu chúng tôi chỉ có một số mục, chúng tôi có thể hiển thị bản xem trước dài. Khi danh sách tăng lên, chúng tôi giảm các dòng xem trước mà chúng tôi có thể hiển thị. Khi độ dài của danh sách dài hơn chiều cao của chế độ xem, chúng tôi có thể chọn ẩn hoàn toàn các bản xem trước và làm cho bất kỳ nút nào nhỏ hơn, để giảm thiểu việc cuộn. ■ Một ứng dụng danh sách việc cần làm, trong đó chúng tôi hiển thị mọi mục với phông chữ lớn khi có ít mục hơn, nhưng dần dần làm cho kích thước phông chữ nhỏ hơn [cho tất cả các mục] khi tổng số mục tăng lên. ■ Một ứng dụng bảng màu, với các điều khiển được hiển thị trên mỗi màu. Người ta có thể muốn làm cho các điều khiển này nhỏ gọn hơn khi số lượng màu sắc tăng lên và không gian mà chúng chiếm giữ giảm đi tương ứng [Hình 7. 7]. ■ Một ứng dụng có nhiều s mà mỗi khi chúng tôi thêm một cái mới, chúng tôi sẽ làm cho tất cả chúng nhỏ hơn [như trong bytesizematters. com]

    270

    CHƯƠNG 7. KẾT CẤU & BỐ CỤC

    HÌNH 7. 7 Dần dần làm cho các điều khiển nhỏ hơn khi số lượng màu tăng lên và không gian khả dụng thu hẹp lại. Lưu ý cách xử lý đặc biệt đối với trường hợp chúng tôi chỉ có một màu. Sau đó chúng tôi ẩn nút xóa. Màu sắc được lấy từ Adobe Color [màu. adobe. com] bảng màu. ■ Cây thùa [màu. adobe. com/ agave-color-theme-387108] ■ Sushi Maki [màu. adobe. com/ Sushi-Maki-colortheme-350205]

    Tuy nhiên, việc nhắm mục tiêu các phần tử dựa trên tổng số anh chị em của họ là

    1

    không tầm thường với bộ chọn CSS. Ví dụ: giả sử chúng tôi muốn áp dụng các kiểu nhất định cho các mục của danh sách khi tổng số của chúng là 4. Chúng ta có thể sử dụng li. thứ n-

    con[4] để chọn mục thứ tư trong danh sách, nhưng đây không phải là mục chúng tôi cần; . Ý tưởng tiếp theo của chúng ta có thể là sử dụng tổ hợp anh chị em tổng quát [~] cùng với. con thứ n [], như li. con thứ n[4],

    5

    2 ✓

    6

    3 ✓

    7

    4 ✓

    8

    HÌNH 7. 8 Yếu tố nào được chọn với

    li. con thứ n[4], li. con thứ n[4] ~ li

    li. thứ n-

    con[4] ~ li. Tuy nhiên, điều này chỉ nhắm vào con thứ tư và các mục sau nó [Hình 7. 8], bất kể tổng số. Bởi vì không có bộ kết hợp nào có thể “nhìn ngược lại” và chọn các anh chị em trước đó, nên việc cố gắng thực hiện điều này với CSS chắc chắn sẽ thất bại?

    BÍ MẬT #38. PHONG CÁCH THEO SIBLING COUNT

    271

    Giải pháp Đối với trường hợp đặc biệt có chính xác một mục, có một giải pháp rõ ràng. . con một, được tạo ra chính xác cho mục đích này. Điều này không chỉ hữu ích như một điểm khởi đầu, mà còn có một số trường hợp sử dụng cho nó, đó là lý do tại sao nó được thêm vào thông số kỹ thuật. Ví dụ, lưu ý trong Hình 7. 7 rằng chúng tôi đang ẩn nút xóa khi chúng tôi chỉ có một màu; . con một. Chúng tôi sẽ sử dụng. bộ chọn nth-child[] xuyên suốt phần này, nhưng ev-

    li. con một {

    mọi thứ được thảo luận áp dụng cho. thứ n-

    of-type[] bộ chọn như nhau, thường phù hợp hơn, vì chúng ta

    /* Các kiểu khi chúng ta chỉ có 1 mục */ }

    thường có anh chị em thuộc các loại khác nhau và chúng tôi chỉ quan tâm đến một loại. Chúng tôi sẽ sử dụng danh sách

    Tuy nhiên,. con một tương đương với. con đầu lòng. con cuối cùng,

    các mục trong các ví dụ, nhưng những gì chúng tôi

    vì lý do rõ ràng. nếu mục đầu tiên cũng là mục cuối cùng, nó sẽ theo sau một cách hợp lý

    thảo luận được áp dụng cho các yếu tố thuộc bất kỳ loại nào

    rằng nó là mục duy nhất. Tuy nhiên,. con cuối cùng cũng là một phím tắt, để. thứ n-

    đứa con cuối cùng[1]. li. con đầu lòng. nth-last-con[1] { /* Tương tự như li. con một */ }

    Tuy nhiên, bây giờ 1 là một tham số và chúng ta có thể điều chỉnh nó theo ý thích của mình. bạn có thể đoán những gì li. con đầu lòng. mục tiêu thứ n-con cuối cùng [4]? . con một bằng cách nhắm mục tiêu các mục trong danh sách khi tổng số của chúng là bốn, bạn có thể hơi lạc quan quá mức. Chúng tôi chưa đến đó, nhưng chúng tôi đang đi đúng hướng. Hãy suy nghĩ riêng về cả hai lớp giả. chúng tôi đang tìm kiếm các yếu tố phù hợp với cả hai. con đầu lòng và. con thứ n[4]. Do đó, các phần tử đồng thời là con đầu tiên của cha mẹ chúng được tính từ đầu và con thứ tư được tính từ cuối. Yếu tố nào sẽ đáp ứng tiêu chí này? . 9]. Đây không hoàn toàn là những gì chúng tôi muốn, nhưng nó rất gần. bởi vì 272

    CHƯƠNG 7. KẾT CẤU & BỐ CỤC

    bây giờ chúng tôi có một cách để nhắm mục tiêu con đầu tiên của danh sách như vậy, chúng tôi có thể sử dụng

    1

    2

    3

    2

    3

    4

    1

    2

    3

    4

    5

    6

    7

    8

    bộ kết hợp anh chị em chung [~] để nhắm mục tiêu mọi anh chị em theo sau đứa con đầu lòng như vậy, nhắm mục tiêu hiệu quả mọi mục danh sách trong danh sách khi và chỉ khi mục đó

    1

    chứa tổng cộng bốn mục, đó chính xác là những gì chúng tôi đang cố gắng thực hiện

    li. con đầu lòng. con thứ n[4], li. con đầu lòng. con thứ n[4] ~ li {

    HÌNH 7. 9

    /* Các mục danh sách mục tiêu ngoài danh sách

    Những yếu tố nào được chọn với

    chứa chính xác bốn mục */

    li. con đầu lòng. nth-lastchild[4] trong danh sách ba, bốn và

    }

    tám yếu tố

    Để tránh tính dài dòng và lặp lại của giải pháp vừa trình bày, có thể sử dụng một bộ tiền xử lý, chẳng hạn như SCSS, mặc dù cú pháp của các bộ tiền xử lý hiện có cho điều này khá vụng về. SCSS

    /* Xác định mixin */ @mixin n-items[$n] { &. con đầu lòng. con thứ n[#{$n}], &. con đầu lòng. nth-last-child[#{$n}] ~ & { @content; . */ li { @include n-items[4] { /* Thuộc tính và giá trị */ } }

    BÍ MẬT #38. PHONG CÁCH THEO SIBLING COUNT

    273

    Lời khuyên dành cho André Luís [andr3. net] vì đã nảy ra ý tưởng truyền cảm hứng cho kỹ thuật này [andr3. mạng/blog/bài đăng/142]. ĐẦU MŨ

    Chọn theo phạm vi số lượng anh chị em MẸO

    Nó có thể khó khăn để quấn đầu của một người

    xung quanh. bộ chọn thứ n-*. Nếu bạn

    Trong hầu hết các ứng dụng thực tế, chúng tôi không muốn nhắm mục tiêu số lượng mục cụ thể, nhưng phạm vi của chúng. Có một thủ thuật hữu ích mà chúng ta có thể sử dụng để

    gặp sự cố, bạn có thể sử dụng một

    chế tạo. bộ chọn nth-child[] nhắm mục tiêu phạm vi, chẳng hạn như “chọn mọi thứ

    kiểm tra dòng để thử nghiệm với một vài

    sau đứa con thứ tư. ” Bên cạnh các số đơn giản là tham số, chúng ta cũng có thể

    biểu thức. Tôi đã viết một lúc. verou. tôi/bản trình diễn/thứ n. html,

    sử dụng biểu thức an+b [e. g. ,. con thứ n[2n+1]], trong đó n là viết tắt của a

    nhưng có rất nhiều người khác

    biến nằm trong khoảng từ 0 đến +∞ theo lý thuyết [trong thực tế, các giá trị sau một giá trị nhất định

    xung quanh

    point đừng chọn gì nữa vì số phần tử ta có là hữu hạn]. Nếu chúng ta sử dụng một biểu thức có dạng n+b [trong đó a được ngụ ý là 1], thì không có số nguyên dương nào cho n có thể cho chúng ta một giá trị nhỏ hơn b. Do đó, có thể sử dụng biểu thức dạng n+b để chọn mọi con từ bth trở đi; . nth-child[n+4] chọn mọi phần tử con ngoại trừ phần tử thứ nhất, thứ hai và thứ ba [Hình 7. 10]

    HÌNH 7. 10 Yếu tố nào được chọn với

    1

    2

    3

    1

    2

    3

    4

    1

    2

    3

    4

    li. con thứ n[n+4] trong danh sách ba, bốn và tám phần tử

    5

    6

    7

    8

    Chúng ta có thể tận dụng điều này để chọn các mục trong danh sách khi tổng số mục từ bốn mục trở lên [Hình 7. 11]. Trong trường hợp này, chúng ta có thể sử dụng n+4 làm biểu thức bên trong. nth-con-cuối[]

    li. con đầu lòng. con thứ n-cuối cùng[n+4], li. con đầu lòng. nth-last-child[n+4] ~ l { /* Mục tiêu trong danh sách ngoài danh sách chứa ít nhất bốn mục */ }

    274

    CHƯƠNG 7. KẾT CẤU & BỐ CỤC

    Tương tự, các biểu thức có dạng -n+b có thể được sử dụng để chọn b đầu tiên

    1

    2

    3

    yếu tố. Do đó, để chọn tất cả các mục trong danh sách khi và chỉ khi có bốn hoặc ít hơn trong cùng một danh sách [Hình 7. 12], chúng tôi sẽ viết

    li. con đầu lòng. con thứ n[-n+4],

    1

    1

    li. con đầu lòng. con thứ n[-n+4] ~ li { 5

    /* Các mục danh sách mục tiêu ngoài danh sách chứa tối đa bốn mục */

    2

    2 6

    3

    3 7

    4

    4 8

    HÌNH 7. 11

    }

    Những yếu tố nào được chọn với

    Tất nhiên, chúng tôi có thể kết hợp cả hai, nhưng mã bây giờ thậm chí còn khó sử dụng hơn. Giả sử chúng tôi muốn nhắm mục tiêu các mục danh sách khi danh sách chứa

    li. con đầu lòng. con thứ n-cuối cùng[n+4], li. con đầu lòng. con thứ n[n+4] ~ l trong danh sách ba, bốn và tám phần tử

    giữa 2–6 mục

    li. con đầu lòng. con thứ n-cuối cùng[n+2]. con thứ n[-n+6],

    1

    li. con đầu lòng. con thứ n-cuối cùng[n+2]. nth-last-child[-n+6] ~ li { /* Mục tiêu trong danh sách nếu danh sách

    1

    2

    2

    3

    3

    4

    chứa 2-6 mục */ }

    CHƠI. chơi. bí mật css. io/styling-sibling-count

    1

    2

    3

    4

    5

    6

    7

    8

    HÌNH 7. 12 Yếu tố nào được chọn với

    ■ Bộ chọn w3. org/TR/bộ chọn

    RELATED

    SPECS

    li. con đầu lòng. con thứ n[-n+4], li. con đầu lòng. con thứ n[-n+4] ~ l trong danh sách ba, bốn và tám phần tử

    BÍ MẬT #38. PHONG CÁCH THEO SIBLING COUNT

    275

    39

    Nền linh hoạt, nội dung cố định Vấn đề Trong vài năm qua, có một xu hướng thiết kế web đang ngày càng phổ biến. đó là cái mà tôi gọi là “chiều rộng nền linh hoạt, chiều rộng nội dung cố định. ” Các đặc điểm tiêu biểu của mẫu này là. ■ Có nhiều phần, mỗi phần chiếm toàn bộ chiều rộng của khung nhìn

    HÌNH 7. 13 Trang web chia sẻ nhà nổi tiếng airbnb. com sử dụng mẫu này ở chân trang của nó

    và mỗi người có một nền tảng khác nhau. ■ Nội dung có chiều rộng cố định, ngay cả khi chiều rộng đó thay đổi ở các độ phân giải khác nhau vì chiều rộng cố định nói trên được sửa đổi bởi các truy vấn phương tiện. Trong một số trường hợp, các phần khác nhau cũng có độ rộng nội dung khác nhau. Đôi khi toàn bộ trang web bao gồm các phần được tạo kiểu theo cách này [Hình 7. 15, hoặc tinh tế hơn, Hình 7. 14]. Thường xuyên hơn, chỉ các phần cụ thể tuân theo mẫu này, đặc biệt là phần chân trang [Hình 7. 13]

    276

    CHƯƠNG 7. KẾT CẤU & BỐ CỤC

    HÌNH 7. 14 Website đặt tour du lịch nổi tiếng chèo thuyền kayak. com sử dụng mẫu này trên khắp trang chủ của mình theo một cách rất tinh tế

    Cách phổ biến nhất để thực hiện điều gì đó như thế này là sử dụng hai yếu tố cho mỗi phần, một cho nền linh hoạt và một cho chiều rộng nội dung cố định. Cái sau được căn giữa theo chiều ngang thông qua lề

    tự động. Ví dụ: đánh dấu cho một chân trang như vậy có thể trông như thế này. HTML

    Dolore reprehenderit ex, người làm thịt viên giao hàng tận nơi cho món sườn nướng. Ad aliqua kevin, chuck exceptioneur minim et cow esse ham hock Landjaeger. Bacon ipsum dolor sit amet gà tây veniam shankle, Alcatra bresaola dolore tempor do, ngoại lệ trong velit culpaofficia sườn dolore ngắn kevin t-bone occaecat. Et workingum sườn bánh mì thịt bò picanha. Eu venison nostrud, ut veniam sintaute kielbasa ullamco pancetta brisket eiusmod xúc xích ipsum, culpa pancetta. Qui dùi đùi thịt xông khói thịt nai leberkas sed vai mông vai trừ đuôi, nostrud thịt heo capicolalaborum. Thịt thăn lao động nhuyễn thể tối thiểu. Tempor proident do ipsum magna bacon, xay tròn. Thịt chân giò Út t-bon bán thịt bò ba chỉ, thịt nai. frankfurter et veniam dolore. Xúc xích heo eiusmod shankle sọcse bít tết. sườn bò kevin, doner t-bone bài tập magna shankle

    Tên trang web

    © 2015 Không có quyền

    Được tạo bằng ♥ bởi một người làm bánh ngọt ẩn danh

    Chúng tôi cũng đã áp dụng một số kiểu dáng cơ bản cho nó, bao gồm nền ở chân trang. Bạn có thể thấy nó trông như thế nào trong Hình 7. 23. Bây giờ, hãy giảm nội dung xuống một chút. Bạn có thể thấy những gì xảy ra sau đó, trong Hình 7. 24. Đây là vấn đề chân trang dính trong tất cả vinh quang của nó. Tuyệt vời, chúng tôi đã tạo lại sự cố, nhưng chúng tôi giải quyết nó như thế nào?

    Bò enim ngoại lệ, boudin dolore lorem magna Flank anim chuck boudin id consectetur bresaola ham fugiatloin hậu quả là bay hơi. Picanha gà fugiat Proident, thịt lợn cupim andouille frankfurter. do ball cupim aliquip filet mignon prosciutto ut tip nostrud nullamagna sed, frankfurter ut commodo corned nostrud. Kielbasa frankfurter thịt bò muối. thịt bò ut. Ex aute in,mỡ heo deserunt sườn bò turducken Andouillette in cillum et picanha pastrami ball tip deserunt, sườn heo sườn heo xúc xích Landjaeger hoạt hình. Tôi. Chickentongue sunt nisi tempor sed. Trong eiusmod non fatback tempor thăn pastrami adipisizing bò lorem ut đuôi giật cupidat thịt nai. Jowl dosequat thăn lợn thông thường ipsum bụng lợn prosciutto thịt bò aute. Bóng đầu vai aliqua, fugiat landjaeger kevin sườn heo sườn bò leberkas hamburger cillum thổ nhĩ kỳ ut doner culpa

    © 2015 Không có quyền. Được tạo bằng ♥ bởi một người làm bánh ngọt ẩn danh

    Nếu chúng tôi cho rằng văn bản chân trang của chúng tôi sẽ không bao giờ ngắt dòng, chúng tôi có thể suy ra độ dài CSS cho chiều cao của nó

    HÌNH 7. 23

    2 dòng × chiều cao dòng + 3 × lề đoạn + đệm dọc =

    Trang đơn giản của chúng tôi trông như thế nào khi nội dung của nó đủ dài

    2×1. 5em + 3 × 1em + 1em = 7em

    BÍ MẬT #41. CHÂN DÍNH

    289

    Tên trang web Bacon ipsum dolor sit amet gà tây veniam shankle, culpa xương sườn ngắn kevin t-bone occaecat. Et workingum thịt nai nostrud, ut veniam sint

    Tương tự, chiều cao tiêu đề là 2. 5 em. Do đó, bằng cách sử dụng các đơn vị tương đối của chế độ xem và calc[], chúng ta có thể “dán” chân trang của mình xuống dưới cùng về cơ bản chỉ bằng một dòng CSS

    © 2015 Không có quyền. Được tạo bằng ♥ bởi một người làm bánh ngọt ẩn danh

    chính { chiều cao tối thiểu. calc[100vh - 2. 5em - 7em];

    HÌNH 7. 24

    /* Tránh phần đệm/đường viền làm tăng chiều cao của chúng ta. */

    Vấn đề chân trang dính trong tất cả các vấn đề của nó

    kích thước hộp. hộp viền;

    vinh quang

    }

    !

    Hãy cẩn thận khi sử dụng calc[] với phép trừ hoặc phép cộng

    các toán tử + và - yêu cầu khoảng trắng xung quanh chúng. Điều này rất kỳ quặc

    Ngoài ra, chúng tôi có thể áp dụng một trình bao bọc xung quanh và

    quyết định đã được đưa ra cho tương lai

    các phần tử để chúng ta chỉ cần tính chiều cao của chân trang

    khả năng chịu đựng. Nếu tại một số điểm, từ khóa được cho phép trong calc[], trình phân tích cú pháp CSS cần có khả năng phân biệt giữa dấu gạch nối trong từ khóa và

    #wrapper { chiều cao tối thiểu. calc[100vh - 7em];

    một toán tử trừ

    } Tên trang web Bacon ipsum dolor sit amet gà tây veniam shankle, culpa xương sườn ngắn kevin t-bone occaecat. Et workingum thịt nai nostrud, ut veniam sint

    Điều này hoạt động [Hình 7. 25] và nó có vẻ tốt hơn một chút so với các giải pháp chiều cao cố định hiện có, chủ yếu là do tính tối giản của nó. Tuy nhiên, ngoại trừ các bố cục rất đơn giản, điều này không thực tế chút nào. Nó đòi hỏi chúng ta phải giả định rằng

    © 2015 Không có quyền. Được tạo bằng ♥ bởi một người làm bánh ngọt ẩn danh

    văn bản chân trang sẽ không bao giờ ngắt dòng, chúng tôi cần chỉnh sửa chiều cao tối thiểu mỗi khi chúng tôi thay đổi số liệu chân trang [i. e. , nó không KHÔ], và trừ khi chúng ta

    HÌNH 7. 25

    sẵn sàng thêm phần tử HTML bao quanh tiêu đề và nội dung của chúng tôi,

    Phần chân trang sau khi chúng tôi đã áp dụng CSS

    chúng ta cần thực hiện các tính toán và sửa đổi tương tự cho tiêu đề như

    để làm cho nó dính

    ổn. Chắc chắn, trong thời đại ngày nay chúng ta có thể làm tốt hơn, phải không? . chơi. bí mật css. io/sticky-footer-fixed

    Giải pháp linh hoạt Flexbox hoàn hảo cho các loại vấn đề này. Chúng ta có thể đạt được sự linh hoạt hoàn hảo chỉ với một vài dòng CSS và không cần những phép tính kỳ quặc

    290

    CHƯƠNG 7. KẾT CẤU & BỐ CỤC

    hoặc các phần tử HTML bổ sung. Đầu tiên, chúng ta cần áp dụng màn hình. uốn cong để

    phần tử, vì nó là phần tử gốc của cả ba khối chính của chúng tôi, để chuyển đổi

    Tên trang web

    Bố cục hộp linh hoạt [Flexbox] cho cả ba. Chúng ta cũng cần thiết lập

    flex-flow vào cột, nếu không chúng sẽ được bố trí theo chiều ngang trên một hàng [Hình 7. 26]

    Bacon ipsum dolor sit amet gà tây veniam shankle, culpa xương sườn ngắn kevin tbone occaecat. Et workingum thịt nai nostrud, ut veniam sint

    © 2015 Không có quyền. Được tạo bằng ♥ bởi một người làm bánh ngọt ẩn danh

    HÌNH 7. 26 Áp dụng flex mà không áp dụng

    thân thể {

    bất cứ điều gì khác sắp xếp các em

    trưng bày. uốn cong;

    của phần tử của chúng tôi theo chiều ngang

    dòng chảy linh hoạt. cột;

    Tại thời điểm này, trang của chúng tôi trông giống như trước tất cả nội dung Flexbox, vì mọi phần tử chiếm toàn bộ chiều rộng của chế độ xem và kích thước của nó được xác định bởi nội dung của nó. Vì vậy, chúng tôi chưa thực sự tận dụng lợi thế của Flexbox. Để điều kỳ diệu xảy ra, chúng ta cần chỉ định chiều cao tối thiểu là

    100vh on , để nó chiếm ít nhất toàn bộ chiều cao của khung nhìn. Đến đây thì bố cục vẫn y như hình 7. 24, bởi vì mặc dù chúng tôi đã chỉ định chiều cao tối thiểu cho toàn bộ thành phần cơ thể, chiều cao của mỗi hộp vẫn được xác định bởi nội dung của chúng [i. e. , về bản chất chúng được xác định, theo cách nói đặc tả CSS]. Những gì chúng ta cần ở đây là chiều cao của đầu trang và chân trang được xác định nội tại, nhưng chiều cao của nội dung phải linh hoạt kéo dài đến tất cả không gian còn lại. Chúng ta có thể làm điều đó bằng cách áp dụng giá trị flex lớn hơn 0 [1 sẽ hoạt động] cho vùng chứa

    cơ thể { hiển thị. uốn cong; . cột; . 100vh; . 1;

    TIP

    Thuộc tính flex thực sự là một cách viết tắt của

    flex-grow, flex-shrink và flex-basis. Bất kỳ phần tử nào có giá trị flex lớn hơn 0 đều trở nên linh hoạt và flex kiểm soát tỷ lệ giữa các kích thước của các phần tử linh hoạt khác nhau. Ví dụ, trong trường hợp của chúng tôi, nếu có flex. 2 và có flex. 1, chiều cao của chân trang sẽ gấp đôi chiều cao của nội dung. Tương tự nếu các giá trị là 4 và 2 thay vì 2 và 1, vì mối quan hệ của chúng mới quan trọng

    BÍ MẬT #41. CHÂN DÍNH

    291

    Thế là xong, không cần thêm mã nào nữa. Chân trang cố định hoàn hảo [kết quả trực quan giống như trong Hình 7. 25], chỉ với bốn dòng mã đơn giản. Flexbox có đẹp không? . chơi. bí mật css. io/sticky-footer Lời khuyên dành cho Philip Walton [philipwalton. com] vì đã nghĩ ra kỹ thuật này [philipwalton. github. io/solve-by-flexbox/demos/sticker-footer]. MẸO HAY ■ Bố cục hộp linh hoạt CSS w3. org/TR/css-flexbox ■ Đơn vị và Giá trị CSS w3. giá trị org/TR/css

    292

    CHƯƠNG 7. KẾT CẤU & BỐ CỤC

    RELATED

    SPECS

    Chuyển tiếp & Hoạt ảnh

    8

    42

    Chuyển đổi đàn hồi Điều kiện tiên quyết Chuyển đổi CSS cơ bản, hoạt hình CSS cơ bản

    Vấn đề Chuyển tiếp đàn hồi và hoạt ảnh [i. e. , hiệu ứng chuyển tiếp "nảy ra"] là một cách phổ biến để làm cho giao diện trở nên thú vị và chân thực hơn—khi các đối tượng đang di chuyển trong đời thực, chúng hiếm khi đi từ A đến B mà không có độ co giãn. Tại sao lại sử dụng biến đổi chứ không phải một số thuộc tính CSS khác, như top hoặc

    lề trên?

    Từ quan điểm kỹ thuật, hiệu ứng nảy là khi quá trình chuyển đổi đạt đến giá trị cuối cùng, sau đó tua lại một chút, sau đó đạt đến giá trị cuối cùng

    ing, biến đổi có xu hướng mượt mà hơn,

    giá trị một lần nữa, một hoặc nhiều lần giảm dần, cho đến khi nó kết thúc

    trong khi các thuộc tính CSS khác thường

    tốt. Ví dụ: giả sử chúng ta đang tạo hoạt ảnh cho một phần tử được tạo kiểu giống như

    bám vào ranh giới pixel

    bóng rơi xuống [xem Hình 8. 1], bằng cách chuyển biến đổi từ không sang

    dịchY[350px]. Tất nhiên, số lần bị trả lại không chỉ là về chuyển động theo vị trí. Họ có thể tăng cường đáng kể hầu hết mọi loại chuyển đổi, bao gồm cả

    294

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    ■ Chuyển tiếp kích thước [e. g. , làm cho một phần tử lớn hơn trên. di chuột, hiển thị cửa sổ bật lên phát triển từ biến đổi. tỷ lệ [0], làm động các thanh trong biểu đồ thanh] ■ Chuyển động góc [e. g. , xoay, biểu đồ hình tròn có các lát phát triển từ 0 thông qua hoạt ảnh] Khá nhiều thư viện JavaScript cung cấp khả năng hoạt ảnh với độ nảy được tích hợp sẵn. Tuy nhiên, ngày nay chúng ta không cần viết kịch bản cho hoạt ảnh và chuyển tiếp nữa. Tuy nhiên, cách tốt nhất để viết mã thoát trong CSS là gì?

    HÌNH 8. 1 Một chuyển động nảy ngoài đời thực

    Hoạt ảnh nảy lên Linh cảm đầu tiên của chúng tôi có thể là sử dụng hoạt ảnh CSS, với các khung hình chính như sau

    BÍ MẬT #42. CHUYỂN ĐỔI ĐÀN HỒI

    295

    @keyframes trả lại { 60%, 80%, thành { biến đổi. dịchY[350px]; . dịchY[250px]; . dịchY[300px]; . bóng { /* Kích thước, màu sắc, v.v. */ hoạt hình. nảy 3s;

    Các khung hình chính trong mã trước chỉ định chính xác các bước giống như [50%, 80%]

    trong Hình 8. 1. Tuy nhiên, nếu bạn chạy hoạt ảnh này, bạn sẽ nhận thấy rằng nó trông rất giả tạo. Một trong những lý do cho điều này là mỗi khi quả bóng đổi hướng, nó tiếp tục tăng tốc, trông không tự nhiên. Các

    TIẾN TRÌNH

    lý do là chức năng thời gian của nó giống nhau trên tất cả các khung hình chính này. “Đó là thời gian… cái gì?” . Mỗi quá trình chuyển đổi và hoạt ảnh được liên kết với một đường cong xác định cách thức tiến triển theo thời gian [còn được gọi là "nới lỏng" trong một số ngữ cảnh]. Nếu bạn không chỉ định chức năng hẹn giờ,

    THỜI GIAN

    HÌNH 8. 2 Chức năng định thời gian mặc định [dễ dàng] cho tất cả các hiệu ứng chuyển tiếp và hoạt ảnh

    nó sẽ lấy cái mặc định, không giống như những gì bạn có thể mong đợi, nó không tuyến tính và được hiển thị trong Hình 8. 2. Lưu ý [như thể hiện bởi điểm màu hồng trong Hình 8. 2] làm thế nào khi một nửa thời gian đã trôi qua, quá trình chuyển đổi đạt khoảng 80% trên đường đi. Chức năng thời gian mặc định cũng có thể được chỉ định rõ ràng với từ khóa easy, trong tốc ký hoạt hình/chuyển tiếp hoặc

    hoạt hình-thời gian-chức năng/chuyển đổi-thời gian-chức năng longhands. Tuy nhiên, vì dễ dàng là chức năng định thời gian mặc định nên nó không hữu dụng lắm. Có thêm bốn đường cong được nung sẵn mà bạn có thể sử dụng để thay đổi cách hoạt ảnh tiến triển, như trong Hình 8. 3. Như bạn có thể thấy, thả lỏng là mặt trái của thả lỏng. Đây chính xác là những gì chúng tôi muốn cho hiệu ứng thoát của chúng tôi. chúng tôi muốn đảo ngược chức năng thời gian mỗi khi hướng đảo ngược. Do đó, chúng tôi có thể chỉ định chức năng thời gian chính trong thuộc tính hoạt hình và ghi đè lên nó trong khung hình chính. Chúng tôi muốn chức năng thời gian của hướng chính là

    296

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    HÌNH 8. 3 Các từ khóa có sẵn tương ứng với thời gian định trước

    TIẾN TRÌNH

    [50%, 32%]

    dễ dàng trong

    TIẾN TRÌNH

    [50%, 68%]

    THỜI GIAN

    chức năng

    thời gian dễ dàng

    thời gian dễ dàng ra vào

    [50%, 50%] TIẾN TRÌNH

    TIẾN TRÌNH

    [50%, 50%]

    THỜI GIAN tuyến tính

    tăng tốc một [dễ dàng ra] và một trong những hướng ngược lại được giảm tốc [dễ dàng vào]

    @keyframes trả lại { 60%, 80%, thành { biến đổi. dịchY[400px]; . thả lỏng; . dịchY[300px]; . dịchY[360px]; . trái bóng {

    BÍ MẬT #42. CHUYỂN ĐỔI ĐÀN HỒI

    297

    /* Phần còn lại của kiểu dáng ở đây */ hoạt hình. trả lại 3 giây dễ dàng;

    Nếu bạn kiểm tra mã, bạn sẽ thấy rằng ngay cả thay đổi đơn giản này cũng ngay lập tức dẫn đến kết quả thoát thực tế hơn đáng kể. Tuy nhiên, giới hạn bản thân trong năm đường cong được xác định trước này là vô cùng hạn chế. Nếu chúng ta có thể chọn các hàm thời gian tùy ý, chúng ta sẽ có thể đạt được kết quả thực tế hơn nhiều. Ví dụ: nếu hoạt ảnh nảy dành cho vật thể đang rơi, thì gia tốc cao hơn [chẳng hạn như gia tốc được cung cấp bởi sự dễ dàng] sẽ tạo ra kết quả chân thực hơn. Nhưng làm thế nào chúng ta có thể tạo ra nghịch đảo của

    dễ dàng, khi không có từ khóa cho nó? . Đường cong Bézier là loại đường cong bạn làm việc với bất kỳ ứng dụng véc-tơ nào [e. g. , Adobe Illustrator]. Chúng được xác định bởi một số đoạn đường dẫn, với một chốt ở mỗi đầu để kiểm soát độ cong của chúng [các chốt này thường được gọi là điểm kiểm soát]. Các đường cong phức tạp chứa một số lượng lớn các đoạn như vậy, được nối với nhau tại các điểm cuối của chúng [Hình 8. 4]. Hàm thời gian CSS-

    HÌNH 8. 4

    các đường cong Bézier chỉ có một đoạn, vì vậy chúng chỉ có hai

    Một đường cong Bézier lập phương cho một hình xoắn ốc, với

    Điểm kiểm soát. Ví dụ, bạn có thể thấy chức năng thời gian mặc định

    các nút và điểm kiểm soát của nó hiển thị

    [dễ dàng] với các điểm kiểm soát của nó được hiển thị trong Hình 8. 5. Ngoài năm đường cong được xác định trước mà chúng ta đã thảo luận trong phần trước, còn có một hàm cube-bezier[] cho phép chúng ta chỉ định một hàm thời gian tùy chỉnh. Cần bốn đối số, là tọa độ của hai điểm kiểm soát, để tạo đường cong Bézier mà chúng ta đang chỉ định, với dạng cube-bezier[x1, y1, x2, y2] trong đó [x1,

    TIẾN TRÌNH

    y1] là tọa độ của điểm kiểm soát thứ nhất và [x2, y2] của điểm kiểm soát thứ hai. Các điểm cuối của đoạn thẳng được cố định tại [0,0], là điểm bắt đầu của quá trình chuyển đổi [thời gian trôi qua bằng không, tiến trình bằng không] và [1,1], là điểm kết thúc của nó [thời gian đã trôi qua 100%, tiến trình 100%

    THỜI GIAN

    HÌNH 8. 5 Chức năng hẹn giờ dễ dàng với các nút và điểm kiểm soát được hiển thị

    Lưu ý rằng hạn chế về việc có một phân khúc duy nhất có điểm cuối cố định không phải là hạn chế duy nhất. Giá trị x của cả hai điểm kiểm soát được giới hạn trong phạm vi [0, 1] [i. e. , chúng ta không thể di chuyển các núm điều khiển bên ngoài biểu đồ theo chiều ngang]. Hạn chế này không tùy tiện. Vì chúng ta không thể [chưa?] du hành xuyên thời gian nên chúng ta không thể chỉ định quá trình chuyển đổi bắt đầu trước khi nó được kích hoạt

    298

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    hoặc kết thúc sau thời hạn của nó. Hạn chế thực sự duy nhất ở đây là số lượng nút. Việc giới hạn đường cong chỉ ở hai nút sẽ giới hạn kết quả khá nhiều, nhưng nó cũng giúp sử dụng hàm cube-bezier[] đơn giản hơn. Bất chấp những hạn chế này, cube-bezier[] cho phép chúng ta tạo một tập hợp các hàm thời gian rất đa dạng. Theo logic, chúng ta có thể đảo ngược bất kỳ chức năng thời gian nào bằng cách hoán đổi tọa độ ngang với tọa độ dọc cho cả hai điểm kiểm soát của nó. Điều này cũng áp dụng cho các từ khóa; . Ví dụ, easy tương đương với cube-bezier[. 25,. 1,. 25,1], do đó, mặt trái của nó là lập phương-bezier[

    1,. 25,1,. 25] và được thể hiện trong Hình 8. 6. Bằng cách này, hoạt ảnh nảy của chúng ta giờ đây có thể sử dụng dễ dàng và trông thậm chí còn chân thực hơn. @keyframes trả lại { 60%, 80%, thành { biến đổi. dịchY[400px];

    hoạt hình-thời gian-chức năng. xoa dịu; . dịchY[300px]; . dịchY[360px];

    [50%, 30%]

    THỜI GIAN

    }. trái bóng {

    HÌNH 8. 6

    /* Tạo kiểu */

    Chức năng đảo ngược thời gian để dễ dàng

    hoạt hình. nảy 3s khối-bezier[. 1,. 25,1,. 25];

    Sử dụng công cụ đồ họa như cube-bezier. com [Hình 8. 7] chúng tôi có thể thử nghiệm thêm và cải thiện hoạt ảnh thoát của mình hơn nữa. CHƠI. chơi. bí mật css. io/thoát

    BÍ MẬT #42. CHUYỂN ĐỔI ĐÀN HỒI

    299

    HÌNH 8. 7 đường cong Cubic Bézier nổi tiếng là khó xác định và hiểu nếu không có hình ảnh trực quan, đặc biệt khi chúng đóng vai trò là các hàm thời gian cho quá trình chuyển đổi; . com [được hiển thị ở đây], được thực hiện bởi bạn

    trong hoạt hình. thư viện hoạt hình css của Dan Eden [daneden. me], hàm thời gian được sử dụng là cube-bezier[. 215,. 61,. 355,1] và

    khối bezier[. 755,. 05,. 855,. 06] thay vì ngược lại, đó là HAT TIP

    dốc hơn, để tăng tính hiện thực

    Chuyển đổi linh hoạt Giả sử chúng ta muốn hiển thị chú thích mỗi khi trường văn bản được đặt tiêu điểm, để cung cấp thông tin bổ sung, chẳng hạn như các giá trị được phép. Đánh dấu có thể trông như thế này

    TIP

    Nếu bạn đang sử dụng một

    chiều cao và không phải là một trans-

    biểu mẫu để hiển thị chú thích, bạn sẽ nhận thấy rằng quá trình chuyển đổi từ

    Chiều cao. 0 [hoặc bất kỳ giá trị nào khác] đến chiều cao. auto không hoạt động, vì auto là một từ khóa và không thể được biểu thị dưới dạng giá trị có thể hoạt ảnh

    tên người dùng của bạn

    Chỉ cho phép các chữ cái, số, dấu gạch dưới [_] và dấu gạch nối [-]

    Trong những trường hợp đó, hãy sử dụng chiều cao tối đa thay vì chiều cao đủ lớn

    300

    HTML

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    HÌNH 8. 8 Ban đầu quá trình chuyển đổi của chúng tôi trông như thế nào

    Và CSS để chuyển đổi màn hình có thể giống như sau [chúng tôi đã bỏ qua mọi thứ liên quan đến kiểu dáng hoặc bố cục]

    đầu vào. không phải[. tập trung] +. chú thích { biến đổi. tỷ lệ [0]; . chú thích { chuyển tiếp. . 5s biến hình; . 1. 4em -. 4em;

    Như hiện tại, khi người dùng tập trung vào trường văn bản của chúng tôi, sẽ có một quá trình chuyển đổi nửa giây trông giống như Hình 8. 8. Không có gì sai với điều đó, nhưng nó sẽ trông tự nhiên và vui tươi hơn nếu nó phóng đại một chút ở đoạn cuối [e. g. , nếu nó tăng kích thước lên 110% và sau đó quay trở lại 100%]. Chúng ta có thể làm điều này bằng cách chuyển đổi quá trình chuyển đổi sang hoạt ảnh và áp dụng những gì chúng ta đã học trong phần trước

    @keyframes đàn hồi phát triển { từ { biến đổi. tỷ lệ [0]; . tỷ lệ [1. 1]; . khối bezier[. 1,. 25,1,. 25];

    BÍ MẬT #42. CHUYỂN ĐỔI ĐÀN HỒI

    301

    } } đầu vào. không phải[. tập trung] +. chú thích { biến đổi. tỷ lệ [0]; . tập trung +. chú thích { hoạt hình. đàn hồi-tăng trưởng. 5s; . chú thích { biến đổi nguồn gốc. 1. 4em -. 4em;

    Nếu chúng tôi dùng thử, chúng tôi sẽ thấy rằng nó thực sự hoạt động. Bạn có thể thấy nó trông như thế nào trong Hình 8. 9 và so sánh nó với quá trình chuyển đổi trước đó. Tuy nhiên, về cơ bản, chúng tôi đã sử dụng hoạt ảnh khi chúng tôi thực sự cần chuyển đổi. Hoạt ảnh có thể rất mạnh mẽ, nhưng trong trường hợp như thế này, khi tất cả những gì chúng tôi cần là thêm một số tính linh hoạt cho quá trình chuyển đổi của mình, thì có vẻ hơi quá mức cần thiết, giống như sử dụng cưa máy để tự cắt một lát bánh mì. Có cách nào để thực hiện điều gì đó như thế này với quá trình chuyển đổi không? . Cho đến nay, chúng ta chỉ thảo luận về các đường cong có điểm kiểm soát nằm trong phạm vi 0–1. Như chúng tôi đã đề cập trong phần trước, chúng tôi không thể vượt quá phạm vi này theo chiều ngang, mặc dù điều này có thể thay đổi trong tương lai nếu cỗ máy thời gian được phát minh. Tuy nhiên, chúng tôi được phép vượt quá phạm vi 0–1 theo chiều dọc và khiến quá trình chuyển đổi của chúng tôi tiến triển dưới 0% hoặc trên 100%. Bạn có đoán được điều đó có nghĩa là gì không?

    tỷ lệ [1. 1], hoặc thậm chí nhiều hơn, tùy thuộc vào độ dốc mà chúng tôi thực hiện chức năng định giờ

    HÌNH 8. 9 Giao diện người dùng của chúng tôi cảm thấy thực tế và vui tươi hơn nếu chúng tôi thêm một số tính linh hoạt vào quá trình chuyển đổi của mình

    302

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    Trong trường hợp này, chúng tôi chỉ muốn độ co giãn rất ít, vì vậy chúng tôi muốn chức năng thời gian của mình đạt cấp độ 110% [tương ứng với tỷ lệ [1. 1]] và sau đó bắt đầu chuyển đổi trở lại 100%. Hãy bắt đầu từ chức năng định thời gian dễ dàng ban đầu [cubic-bezier[. 25,. 1,. 25,1]] và di chuyển điểm điều khiển thứ hai về phía trên cùng cho đến khi chúng ta đạt được thứ gì đó giống như hình khối-

    bezier[. 25,. 1,. 3,1. 5]. Như bạn có thể thấy trong Hình 8. 10, quá trình chuyển đổi hiện đạt tiến trình 100% với khoảng 50% tổng thời lượng của nó. Thế nào-

    [70%, 110%]

    bao giờ hết, nó không dừng lại ở đó;

    [50%, 100%]

    còn lại 30% thời gian khả dụng của nó chuyển đổi trở lại giá trị cuối cùng, dẫn đến quá trình chuyển đổi rất giống với hoạt ảnh của chúng tôi, nhưng đã đạt được

    đầu vào. không phải[. tập trung] +. chú thích { biến đổi. tỷ lệ [0];

    TIẾN TRÌNH

    chỉ với một dòng mã. Để so sánh, mã của chúng tôi bây giờ là

    THỜI GIAN

    chú thích { biến đổi nguồn gốc. 1. 4em -. 4em;

    HÌNH 8. 10

    chuyển tiếp. . 5s khối bezier[. 25,. 1,. 3,1. 5];

    Chức năng thời gian tùy chỉnh với tọa độ dọc bên ngoài 0–1

    }

    phạm vi

    Tuy nhiên, mặc dù quá trình chuyển đổi của chúng ta trông như mong đợi khi chúng ta tập trung vào trường văn bản và chú thích xuất hiện, nhưng kết quả có thể không chính xác như mong đợi khi trường văn bản mất tiêu điểm và chú thích co lại và biến mất [Hình 8. 11]. Điều gì đã xảy ra ở đây?. Kết quả có thể trông kỳ lạ, nhưng nó thực sự được mong đợi. khi chúng tôi tab ra khỏi trường đầu vào, quá trình chuyển đổi kích hoạt có tỷ lệ [1] là giá trị bắt đầu và tỷ lệ [0] là giá trị cuối cùng của nó. Do đó, do chức năng định thời tương tự được áp dụng, quá trình chuyển đổi vẫn sẽ đạt tiến trình 110% sau 350 mili giây. Chỉ lần này, lũy tiến 110% không chuyển thành tỷ lệ [1. 1], nhưng theo tỷ lệ [-0. 1]. Mặc dù vậy, đừng bỏ cuộc, vì khắc phục sự cố này chỉ thêm một dòng mã nữa. Giả sử chúng ta chỉ muốn một chức năng định thời dễ dàng thông thường khi chú thích co lại, chúng ta có thể làm điều đó bằng cách ghi đè hàm định thời hiện tại trong quy tắc CSS xác định trạng thái đóng của nó

    BÍ MẬT #42. CHUYỂN ĐỔI ĐÀN HỒI

    303

    HÌNH 8. 11 Điều gì đã xảy ra ở đây?

    đầu vào. không phải[. tập trung] +. chú thích { biến đổi. tỷ lệ [0]; . xoa dịu; . chú thích { biến đổi nguồn gốc. 1. 4em -. 4em; . . 5s khối bezier[. 25,. 1,. 3,1. 5];

    Nếu bạn thử lại, bạn sẽ thấy rằng bây giờ nó đóng giống hệt như cách nó đã làm trước hàm cube-bezier[] tùy chỉnh của chúng ta, nhưng khi nó mở ra, nó có hiệu ứng co giãn đẹp mắt mà chúng ta đang thực hiện. Những độc giả thận trọng nhất cũng sẽ nhận thấy một vấn đề khác. đóng chú thích cảm thấy rất chậm. Tại sao vậy? . Khi nó đang phát triển, nó đạt 100% kích thước cuối cùng với tốc độ 50% [i. e. , sau 250ms]. Tuy nhiên, khi nó đang co lại, việc chuyển từ 0% sang 100% sẽ chiếm toàn bộ thời gian chúng tôi đã chỉ định cho quá trình chuyển đổi [500 mili giây], do đó, nó sẽ nhanh hơn một nửa. Để khắc phục sự cố cuối cùng đó, chúng tôi cũng có thể ghi đè thời lượng bằng cách sử dụng thời lượng chuyển tiếp hoặc bằng cách sử dụng tốc ký chuyển đổi và ghi đè mọi thứ. Nếu chúng tôi làm điều sau, chúng tôi không phải chỉ định rõ ràng dễ dàng, bởi vì đó là giá trị ban đầu

    304

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    đầu vào. không phải[. tập trung] +. chú thích { biến đổi. tỷ lệ [0]; . . 25s; . chú thích { biến đổi nguồn gốc. 1. 4em -. 4em; . . 5s khối bezier[. 25,. 1,. 3,1. 5];

    HÌNH 8. 12 Sự chuyển đổi màu đàn hồi từ

    rgb[100%, 0%, 40%] sang màu xám [rgb[50%, 50%, 50%]] với chức năng định thời của khối bezier[. 25,. 1,. 2,3]. Mỗi tọa độ RGB nội suy riêng lẻ, vì vậy chúng tôi đạt được các màu kỳ lạ như

    rgb[0%, 100%, 60%]

    kiểm tra chơi. bí mật css. io/ màu đàn hồi

    Mặc dù chuyển tiếp đàn hồi có thể là một điểm nhấn thú vị trong nhiều loại chuyển tiếp [một số trong đó chúng tôi đã đề cập trong phần “Vấn đề” của bí mật này], nhưng chúng lại là một ý tưởng tồi đối với những loại chuyển tiếp khác. Trường hợp điển hình mà bạn không muốn chuyển đổi đàn hồi là màu sắc. Mặc dù sự chuyển đổi đàn hồi về màu sắc có thể khá thú vị [xem Hình 8. 12], chúng thường không được mong muốn đối với giao diện người dùng. Để tránh việc vô tình áp dụng các hiệu ứng chuyển tiếp đàn hồi cho màu sắc, hãy cố gắng hạn chế các hiệu ứng chuyển tiếp đối với các thuộc tính cụ thể, thay vì không chỉ định bất kỳ điều gì như chúng tôi đã làm trước đây. Khi chúng tôi không chỉ định bất kỳ thuộc tính nào trong

    tốc ký chuyển đổi, thuộc tính chuyển tiếp nhận giá trị mặc định của nó. tất cả các. Điều này có nghĩa là bất cứ điều gì có thể được chuyển đổi, sẽ được chuyển đổi. Do đó, nếu sau này chúng tôi thêm thay đổi nền vào quy tắc được áp dụng cho chú thích mở, thì chuyển đổi đàn hồi giờ đây cũng sẽ được áp dụng cho quy tắc đó. Mã cuối cùng trông như thế này

    đầu vào. không phải[. tập trung] +. gọi ra {

    BÍ MẬT #42. CHUYỂN ĐỔI ĐÀN HỒI

    305

    Nói về hạn chế

    TIP

    biến đổi. tỷ lệ [0];

    chuyển tiếp cụ thể

    thuộc tính, bạn thậm chí có thể xếp hàng chuyển đổi cho các thuộc tính khác nhau, thông qua độ trễ chuyển đổi,

    chuyển tiếp. . 25s biến hình;

    đó là giá trị lần thứ hai trong

    tốc ký chuyển tiếp. Ví dụ: nếu cả chiều rộng và chiều cao đều

    gọi ra {

    đang chuyển đổi và bạn muốn

    biến đổi nguồn gốc. 1. 4em -. 4em;

    chiều cao để đi đầu tiên và chiều rộng sec-

    chuyển tiếp. . 5s khối bezier[. 25,. 1,. 3,1. 5] biến hình;

    ond [một hiệu ứng được phổ biến bởi nhiều tập lệnh hộp đèn], bạn có thể thực hiện điều đó với một số thứ như quá trình chuyển đổi. . chiều cao 5s,. 8s. chiều rộng 5s; . e. , độ trễ của quá trình chuyển đổi chiều rộng bằng với thời lượng của chiều cao

    }

    CHƠI. chơi. bí mật css. io/đàn hồi

    chuyển tiếp]

    ■ Chuyển tiếp CSS w3. org/TR/css-transitions ■ CSS Animations w3. org/TR/css-animations

    306

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    RELATED

    SPECS

    43

    Hoạt ảnh theo từng khung Điều kiện tiên quyết Hoạt ảnh CSS cơ bản, bí mật “Chuyển đổi đàn hồi” ở trang 294

    Vấn đề Khá thường xuyên, chúng ta cần một hình ảnh động khó hoặc không thể đạt được bằng cách chuyển đổi các thuộc tính CSS trên các phần tử. Ví dụ: phim hoạt hình đang chuyển động hoặc chỉ báo tiến độ phức tạp. Trong trường hợp này, hoạt hình theo từng khung hình dựa trên hình ảnh là hoàn hảo, nhưng lại là một thách thức đáng ngạc nhiên để thực hiện trên Web một cách linh hoạt. Tại thời điểm này, bạn có thể tự hỏi, "Chúng ta không thể chỉ sử dụng GIF động sao?" . Thế nào-

    HÌNH 8. 13

    bao giờ hết, họ có một vài thiếu sót có thể là một công cụ giải quyết vấn đề nhất định

    Một tiến trình nửa trong suốt

    trường hợp sử dụng

    chỉ báo [trên dabblet. com];

    308

    ■ Chúng được giới hạn trong bảng màu 256, được chia sẻ trên tất cả các khung

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    ■ Chúng không thể có độ trong suốt alpha, đây có thể là một vấn đề lớn khi chúng ta không biết điều gì sẽ ở bên dưới GIF động của mình. Ví dụ, điều này rất phổ biến với các chỉ báo tiến độ [xem Hình 8. 13]. ■ Không có cách nào để sửa đổi một số khía cạnh từ bên trong CSS, chẳng hạn như thời lượng, số lần lặp lại, tạm dừng, v.v. Khi GIF được tạo, mọi thứ sẽ được đưa vào tệp và chỉ có thể thay đổi bằng cách sử dụng trình chỉnh sửa hình ảnh và tạo một tệp khác. Điều này là tuyệt vời cho tính di động, nhưng không phải cho thử nghiệm. Trở lại năm 2004, Mozilla đã có một nỗ lực để giải quyết hai vấn đề đầu tiên bằng cách cho phép hoạt ảnh theo từng khung hình trong các tệp PNG, giống như

    Để biết thêm thông tin về APNG, xem wikipedia. org/wiki/APNG

    cách chúng ta có thể có cả tệp GIF tĩnh và động. Nó được gọi là APNG và được thiết kế để tương thích ngược với những người xem PNG không hỗ trợ, bằng cách mã hóa khung hình đầu tiên giống như các tệp PNG truyền thống, vì vậy những người xem cũ ít nhất sẽ hiển thị nội dung đó. Hứa hẹn như vậy, APNG chưa bao giờ có đủ lực kéo và cho đến ngày nay, hỗ trợ trình duyệt và trình chỉnh sửa hình ảnh rất hạn chế. Các nhà phát triển thậm chí đã sử dụng JavaScript để đạt được hoạt ảnh linh hoạt theo từng khung hình trong trình duyệt, bằng cách sử dụng một hình ảnh sprite và tạo hoạt ảnh cho vị trí nền của nó bằng JS. Bạn thậm chí có thể tìm thấy các thư viện nhỏ để tạo điều kiện thuận lợi cho việc này. Có cách nào đơn giản để đạt được điều này chỉ với mã CSS đẹp, dễ đọc không?

    Giải pháp Giả sử chúng ta có tất cả các khung hoạt hình của mình ở dạng PNG sprite giống như trong Hình 8. 14

    HÌNH 8. 14 Tám khung của spinner của chúng tôi [kích thước. 800×100]

    Chúng tôi cũng có một phần tử sẽ giữ trình tải [đừng quên bao gồm một số văn bản, để có thể truy cập. ], mà chúng tôi đã áp dụng các kích thước của một khung hình

    BÍ MẬT #43. HÌNH ẢNH ĐỘNG TỪNG KHUNG

    309

    Đang tải…

    HTML

    bộ nạp { chiều rộng. 100px; . 100px; . url[img/loader. png] 0 0; . 200%; . cái bọc; . ẩn giấu;

    Hiện tại kết quả như hình 8. 15. khung hình đầu tiên được hiển thị, nhưng không có hoạt ảnh. Tuy nhiên, nếu chúng ta chơi với nền khác-

    giá trị vị trí, chúng tôi sẽ nhận thấy rằng -100px 0 cung cấp cho chúng tôi khung hình thứ hai, -200px 0 cung cấp cho chúng tôi khung hình thứ ba, v.v. Suy nghĩ đầu tiên của chúng tôi có thể là áp dụng một hình ảnh động như thế này

    trình tải @keyframes { đến { vị trí nền. -800px 0;

    HÌNH 8. 15

    bộ nạp { chiều rộng. 100px; . 100px;

    Khung đầu tiên của trình tải của chúng tôi hiển thị,

    lai lịch. url[img/loader. png] 0 0;

    nhưng vẫn chưa có hoạt hình

    hoạt hình. bộ nạp 1s tuyến tính vô hạn; . 200%; . cái bọc; . ẩn giấu;

    310

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    Tuy nhiên, như bạn có thể thấy trong các ảnh tĩnh sau [được chụp sau mỗi 167 mili giây], điều này không thực sự hiệu quả

    HÌNH 8. 16 Nỗ lực ban đầu của chúng tôi đối với hoạt hình theo khung hình không thành công, vì chúng tôi không cần nội suy giữa các khung hình chính

    Có vẻ như chúng ta sẽ chẳng đi đến đâu, nhưng thực ra chúng ta đang ở rất gần giải pháp. Bí quyết ở đây là sử dụng chức năng định thời của các bước [], thay vì chức năng dựa trên Bézier. “Chức năng thời gian nào?. ” bạn có thể hỏi. Như chúng ta đã thấy trong chương trước, tất cả các chức năng định thời dựa trên Bézier sẽ nội suy giữa các khung hình chính để giúp chúng ta chuyển tiếp mượt mà. Điều đó thật tuyệt; . Rất không giống như các hàm định thời Bézier, các bước [] chia toàn bộ hoạt ảnh thành các khung theo số bước bạn chỉ định và chuyển đổi đột ngột giữa chúng mà không cần nội suy. Thông thường, loại đột ngột này là không mong muốn, vì vậy các bước [] không được nói đến nhiều. Theo như các chức năng định thời gian của CSS, những chức năng dựa trên Bézier là những đứa trẻ nổi tiếng được mời đến tất cả các bữa tiệc và đáng buồn thay, các bước [] là một chú vịt con xấu xí mà không ai muốn ăn trưa cùng. Tuy nhiên, trong trường hợp này, đó chính xác là những gì chúng ta cần. Một lần

    TIẾN TRÌNH

    thực sự là lý do chúng tôi đang sử dụng hiệu ứng chuyển tiếp hoặc hoạt ảnh CSS. Tuy nhiên, trong này

    THỜI GIAN

    HÌNH 8. 17 So sánh các bước[8],

    tuyến tính và chức năng thời gian mặc định, dễ dàng

    chúng tôi chuyển đổi hoạt ảnh của mình thành như sau, trình tải của chúng tôi đột nhiên bắt đầu hoạt động theo cách chúng tôi muốn

    hoạt hình. trình tải 1s bước vô hạn [8];

    Hãy nhớ rằng các bước [] cũng chấp nhận tham số thứ hai tùy chọn,

    bắt đầu hoặc kết thúc [mặc định] chỉ định thời điểm chuyển đổi diễn ra trong mỗi khoảng thời gian [xem Hình 8. 17 cho hành vi mặc định của kết thúc], nhưng điều đó hiếm khi BÍ MẬT #43. HÌNH ẢNH ĐỘNG TỪNG KHUNG

    311

    cần thiết. Nếu chúng ta chỉ cần một bước, cũng có những con đường tắt. step-start và step-end, tương đương với các bước [1,

    bắt đầu] và

    các bước [1, kết thúc], tương ứng. CHƠI. chơi. bí mật css. io/frame-by-frame Mẹo mũ cho Simurai [simurai. com/] vì đã nghĩ ra kỹ thuật hữu ích này trong hoạt hình Sprite sheet với các bước[] [simurai. com/blog/ 2012/12/03/step-animation]. MẸO HAY ■ Ảnh động CSS w3. org/TR/css-animations

    312

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    RELATED

    SPECS

    44

    Nhấp nháy Điều kiện tiên quyết Hoạt ảnh CSS cơ bản, bí mật “Hoạt ảnh theo từng khung hình” ở trang 308

    Sự cố Nhớ thẻ cũ? . Nó đã trở thành một biểu tượng văn hóa trong ngành của chúng tôi, nhắc nhở chúng tôi về sự khởi đầu khiêm tốn, vụng về của ngành học và luôn sẵn sàng đóng vai trò như một trò đùa nội tâm giữa những người xưa. Nó bị mọi người coi thường, cả vì nó vi phạm sự tách biệt giữa cấu trúc và phong cách, nhưng chủ yếu là vì việc lạm dụng nó khiến bất kỳ ai duyệt Web vào cuối những năm 90 trở nên khó chịu. Ngay cả nhà phát minh của chính nó, Lou Montulli, đã nói “[Tôi coi] thẻ chớp mắt là điều tồi tệ nhất mà tôi từng làm cho Internet. ” Tuy nhiên, giờ đây khi cơn ác mộng về thẻ đã ở phía sau chúng ta từ lâu, đôi khi chúng ta vẫn thấy mình cần một hoạt ảnh nhấp nháy. Lúc đầu, nó cảm thấy kỳ lạ, hơi giống như khám phá ra một loại biến thái kỳ lạ nào đó bên trong chúng ta

    314

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    mà chúng tôi không bao giờ biết chúng tôi đã có. Cuộc khủng hoảng danh tính dừng lại khi chúng tôi nhận ra rằng có một vài trường hợp sử dụng trong đó tính năng nháy mắt có thể nâng cao khả năng sử dụng thay vì giảm bớt. Một mẫu UX phổ biến đang nhấp nháy một vài lần [không quá ba. ] để cho biết rằng một thay đổi đã được áp dụng ở đâu đó trong giao diện người dùng hoặc để đánh dấu mục tiêu liên kết hiện tại [phần tử có id khớp với URL #hash]. Được sử dụng theo cách hạn chế như vậy, nhấp nháy có thể rất hiệu quả để thu hút sự chú ý của người dùng vào một khu vực, nhưng do số lần lặp hạn chế, nó không có tác dụng phụ mà thẻ đã gây ra. Một cách khác để duy trì lợi ích của việc chớp mắt [hướng sự chú ý của người dùng] mà không có tác hại [làm mất tập trung, khó chịu, gây động kinh] là “làm mịn” nó [i. e. , thay vì xen kẽ giữa trạng thái “bật” và “tắt” đột ngột, để có sự tiến triển suôn sẻ giữa hai trạng thái]. Tuy nhiên, làm thế nào để chúng tôi thực hiện tất cả điều này? . nháy mắt, quá hạn chế để cho phép chúng tôi làm những gì chúng tôi muốn và ngay cả khi nó đủ mạnh, hỗ trợ trình duyệt của nó rất kém. Chúng tôi có thể sử dụng hoạt ảnh CSS cho việc này không, hay JS là hy vọng duy nhất của chúng tôi?

    Giải pháp Thực tế có nhiều cách để sử dụng hoạt ảnh CSS để đạt được bất kỳ kiểu nhấp nháy nào. trên toàn bộ phần tử [thông qua độ mờ], trên màu văn bản [thông qua

    color], trên đường viền của nó [thông qua màu đường viền], v.v. Trong phần còn lại của phần này, chúng tôi sẽ giả sử rằng chúng tôi chỉ muốn nhấp nháy văn bản, vì đó là trường hợp sử dụng phổ biến nhất. Tuy nhiên, giải pháp cho các phần khác của một phần tử là tương tự. Đạt được một chớp mắt mượt mà là khá dễ dàng. Nỗ lực đầu tiên của chúng tôi có thể sẽ như thế này

    @keyframes nhấp nháy mượt mà { đến { color. trong suốt } }. đánh dấu {hoạt hình. 1s nhấp nháy mượt mà 3;

    BÍ MẬT #44. nhấp nháy

    315

    Điều này gần như hoạt động. Văn bản của chúng tôi mờ dần từ màu văn bản sang trong suốt, tuy nhiên, sau đó nó đột ngột nhảy trở lại màu văn bản ban đầu. Biểu đồ sự thay đổi màu chữ theo thời gian giúp chúng ta hiểu tại sao điều này lại xảy ra [Hình 8. 18]

    HÌNH 8. 18 Sự tiến triển của màu văn bản của chúng tôi trong ba giây [ba lần lặp lại]

    Điều này thực sự có thể được mong muốn. Trong trường hợp đó, chúng tôi đã hoàn thành. Tuy nhiên, khi chúng tôi muốn nhấp nháy mượt mà cả khi văn bản mờ dần và khi nó mờ dần, chúng tôi có nhiều việc phải làm hơn. Một cách để đạt được điều này là thay đổi các khung hình chính để thực hiện chuyển đổi ở giữa mỗi lần lặp lại

    @keyframes nhấp nháy mượt mà { 50% { color. trong suốt } }. đánh dấu {hoạt hình. 1s nhấp nháy mượt mà 3;

    Điều này trông giống như kết quả chúng tôi muốn. Tuy nhiên, mặc dù nó không hiển thị trong hoạt ảnh cụ thể này [vì rất khó để phân biệt giữa các chức năng định thời gian với chuyển đổi màu sắc/độ mờ], điều quan trọng cần lưu ý là hoạt ảnh đang tăng tốc cả khi nó mờ dần và khi nó mờ dần, . g. , hình ảnh động rung động]. Trong trường hợp đó, chúng tôi có thể lấy một công cụ khác ra khỏi hộp công cụ của mình

    hướng hoạt hình. Mục đích duy nhất của hướng hoạt hình là đảo ngược tất cả các lần lặp [đảo ngược], mọi bước chẵn [thay thế] hoặc mọi bước lặp lẻ [xen kẽ-đảo ngược]. Điều tuyệt vời ở nó là nó cũng đảo ngược chức năng thời gian, tạo ra những hình ảnh động thực tế hơn nhiều. Chúng ta có thể thử nó trên phần tử nhấp nháy của mình như vậy

    @keyframes nhấp nháy mượt mà { đến { color. trong suốt } }

    316

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    đánh dấu {hoạt hình. . 5s chớp liên tục 6 luân phiên;

    Lưu ý rằng chúng ta phải tăng gấp đôi số lần lặp lại [thay vì thời lượng, như phương pháp trước đó], vì bây giờ một cặp tăng dần/giảm dần bao gồm hai lần lặp. Vì lý do tương tự, chúng tôi cũng cắt giảm một nửa thời lượng hoạt ảnh

    luân phiên bình thường luân phiên đảo ngược đảo ngược

    HÌNH 8. 19 Tất cả bốn giá trị của hoạt hình-

    hướng và hiệu ứng của chúng đối với hoạt ảnh màu từ đen sang trong suốt qua ba lần lặp lại

    xen kẽ-đảo ngược xen kẽ-đảo ngược Nếu chúng ta muốn có một hoạt ảnh nhấp nháy mượt mà, chúng ta đã hoàn thành tại thời điểm này. Tuy nhiên, nếu chúng ta muốn một cái cổ điển thì sao?

    @keyframes nhấp nháy { thành { color. trong suốt } }. đánh dấu {hoạt hình. 1s nhấp nháy 3 bước [1];

    Tuy nhiên, điều này sẽ thất bại một cách ngoạn mục. hoàn toàn sẽ không có gì xảy ra. Lý do là các bước [1] về cơ bản tương đương với các bước [1,

    kết thúc], có nghĩa là quá trình chuyển đổi giữa màu hiện tại và trong suốt sẽ xảy ra trong một bước và chuyển đổi giá trị sẽ xảy ra ở cuối [Hình 8. 20]. Do đó, chúng ta sẽ thấy giá trị bắt đầu cho toàn bộ thời lượng của hoạt ảnh, ngoại trừ một điểm cực kỳ ngắn

    BÍ MẬT #44. nhấp nháy

    317

    trong thời gian cuối cùng. Nếu chúng ta thay đổi nó thành các bước [1, bắt đầu] thì điều ngược lại sẽ xảy ra. chuyển đổi sẽ xảy ra khi bắt đầu, vì vậy chúng tôi sẽ chỉ thấy văn bản trong suốt, không có hình ảnh động hoặc nhấp nháy. Bước hợp lý tiếp theo sẽ là thử các bước [2] theo cả hai cách [bắt đầu PROGRESSION

    Và kết thúc]. Bây giờ, chúng tôi thấy một số nhấp nháy, nhưng đó là giữa văn bản nửa trong suốt và trong suốt hoặc nửa trong suốt và bình thường tương ứng, vì lý do tương tự. Thật không may, bởi vì chúng tôi không thể định cấu hình các bước [] để thực hiện chuyển đổi ở giữa mà chỉ ở đầu và cuối, giải pháp duy nhất

    THỜI GIAN

    HÌNH 8. 20 Bước [1] thực sự làm gì để

    Giải pháp ở đây sẽ là điều chỉnh các khung hình chính hoạt ảnh để thực hiện chuyển đổi ở mức 50%, giống như chúng tôi đã làm trước đó

    hoạt hình của chúng tôi

    @keyframes nhấp nháy { 50% { color. trong suốt } }. đánh dấu {hoạt hình. 1s nhấp nháy 3 bước [1];

    Điều này cuối cùng hoạt động. Ai có thể đoán được rằng một cái chớp mắt đột ngột cổ điển lại khó thực hiện hơn một cái chớp mắt mượt mà, hiện đại? . CHƠI. chơi. bí mật css. io/nháy mắt

    ■ Ảnh động CSS w3. org/TR/css-animations

    318

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    RELATED

    SPECS

    45

    Nhập hoạt ảnh Điều kiện tiên quyết Hoạt ảnh CSS cơ bản, bí mật “Hoạt hình theo từng khung hình” ở trang 308, bí mật “Nhấp nháy” ở trang 314

    Sự cố Đôi khi chúng tôi muốn làm cho văn bản xuất hiện từng ký tự một để mô phỏng việc nhập. Hiệu ứng này đặc biệt phổ biến trên các trang web công nghệ, sử dụng phông chữ đơn cách để giống với dấu nhắc lệnh đầu cuối. Được sử dụng đúng cách, nó thực sự có thể đóng góp cho phần còn lại của thiết kế. Thông thường, điều này được thực hiện với mã JS dài, rắc rối và phức tạp. Mặc dù đây là bản trình bày thuần túy, nhưng việc sử dụng CSS cho loại hiệu ứng này có vẻ như là một giấc mơ viển vông. Hoặc nó có thể là có thể?

    320

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    HÌNH 8. 21 Chúng tôi đã sử dụng một biến thể của loại hoạt hình này tại CERN, khi tạo một mô phỏng dựa trên web của trình duyệt chế độ dòng đầu tiên [linemode. cern. ch]

    Giải pháp Ý tưởng chính là tạo hiệu ứng động cho chiều rộng của phần tử chứa văn bản của chúng ta từ 0 đến chiều rộng nội dung của nó từng ký tự một. Bạn có thể đã nhận ra hạn chế của phương pháp này là gì. nó sẽ không hoạt động đối với văn bản nhiều dòng. Rất may, hầu hết thời gian, bạn chỉ muốn sử dụng kiểu dáng như vậy trên văn bản một dòng, chẳng hạn như tiêu đề. Một điều khác cần lưu ý là mọi hiệu ứng hoạt hình đều có

    Về mặt lý thuyết, chúng tôi có thể làm cho điều này hoạt động với văn bản nhiều dòng, nhưng nó sẽ liên quan đến việc gói từng dòng trong phần tử riêng của nó và duy trì độ trễ hoạt ảnh phù hợp [i. e. , đó là loại giải pháp tồi tệ hơn vấn đề]

    lợi nhuận giảm dần khi thời lượng của nó tăng lên. hoạt ảnh thời lượng ngắn làm cho giao diện trông bóng bẩy hơn và trong một số trường hợp thậm chí có thể cải thiện khả năng sử dụng. Tuy nhiên, thời lượng của hoạt ảnh càng dài thì nó càng gây khó chịu cho người dùng. Do đó, ngay cả khi kỹ thuật này có thể được sử dụng trên văn bản dài hơn, nhiều dòng, thì trong hầu hết các trường hợp, đó không phải là một ý kiến ​​hay. Hãy bắt đầu với mã. Giả sử chúng tôi muốn áp dụng điều này cho tiêu đề cấp cao nhất [] mà chúng tôi đã tạo kiểu bằng văn bản đơn cách và trông giống như sau

    BÍ MẬT #45. Gõ HOẠT HÌNH

    321

    CSS thật tuyệt vời

    CSS thật tuyệt vời

    HTML

    HÌNH 8. 22 Xuất phát điểm của chúng ta

    Chúng ta có thể dễ dàng thêm một hình ảnh động đi từ 0 đến chiều rộng cuối cùng của tiêu đề, như vậy

    @keyframes gõ { từ { chiều rộng. 0 } } h1 { chiều rộng. 7. 7em; . gõ 8s;

    CSS thật tuyệt vời

    Nó có ý nghĩa hoàn hảo, phải không? . 23, đó là một vụ đắm tàu ​​không liên quan gì đến những gì chúng tôi muốn. Bạn có thể đoán vấn đề là gì. Đầu tiên, chúng tôi quên

    CSS thật tuyệt vời

    áp dụng khoảng trắng. cái bọc;

    CSS thật tuyệt vời

    hình ảnh động của chúng tôi được phát hiện [Hình 8. 24]. cụ thể là

    HÌNH 8. 23 Nỗ lực đầu tiên của chúng tôi về hoạt hình đánh máy không giống với đánh máy

    phát triển, số dòng của nó thay đổi. Thứ hai, chúng tôi quên áp dụng tràn

    ẩn;, vì vậy không có clipping. Nếu chúng tôi khắc phục những vấn đề này, vấn đề thực sự với ■ Vấn đề rõ ràng là hoạt ảnh mượt mà thay vì để lộ từng ký tự văn bản. ■ Vấn đề ít rõ ràng hơn là cho đến nay chúng ta đã xác định chiều rộng

    ở tất cả

    bằng ems, cách này tốt hơn so với tính bằng pixel, nhưng vẫn chưa tối ưu. Ở đâu

    CSS thật tuyệt vời

    đã làm điều này 7. 7 đến từ đâu?

    CSS thật tuyệt vời

    Chúng ta có thể khắc phục sự cố đầu tiên bằng cách sử dụng các bước[], giống như trong bí mật “Hoạt hình theo từng khung hình” trên trang 308 và bí mật “Nhấp nháy” trên

    CSS thật tuyệt vời

    trang 314. Thật không may, số bước chúng ta cần là số

    HÌNH 8. 24

    các ký tự trong chuỗi của chúng tôi, điều này rất khó duy trì hoặc hoàn toàn không phù hợp

    Nỗ lực thứ hai của chúng tôi gần hơn, nhưng vẫn

    hiển thị cho văn bản động. Tuy nhiên, sau này chúng ta sẽ thấy rằng chúng ta có thể tự động hóa

    không hoàn toàn ở đó

    322

    điều này với một đoạn mã JavaScript nhỏ

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    Vấn đề thứ hai có thể được giảm bớt bằng cách sử dụng đơn vị ch. Đơn vị ch là một trong những đơn vị mới được giới thiệu trong Đơn vị và Giá trị CSS Cấp 3 [w3. org/TR/css3-values] và biểu thị chiều rộng của ký tự “0”. Đây là một trong những đơn vị mới chưa được biết đến nhiều nhất, bởi vì trong hầu hết các trường hợp, chúng tôi không quan tâm đến việc định cỡ mọi thứ so với chiều rộng của 0 glyph. Tuy nhiên, phông chữ đơn cách là đặc biệt. Trong các phông chữ đơn cách, chiều rộng của glyph "0" bằng với chiều rộng của mọi glyph. Do đó, chiều rộng trong ch là số ký tự. 15 trong ví dụ của chúng tôi. Hãy tập hợp tất cả những thứ này lại với nhau

    @keyframes gõ { từ { chiều rộng. 0; . 15ch; . ẩn giấu; . cái bọc; . gõ 6s bước[15];

    Như bạn có thể thấy trong các khung ở Hình 8. 25, bây giờ chúng tôi cuối cùng đã có kết quả mong đợi. văn bản của chúng tôi được tiết lộ từng ký tự. Tuy nhiên, nó vẫn không thực tế. Bạn có thể phát hiện những gì còn thiếu? . Chúng ta đã thấy cách tạo hoạt ảnh nhấp nháy trong bí mật “Blinking” ở trang 314. Trong trường hợp này, chúng tôi có thể triển khai dấu mũ thông qua phần tử giả và sử dụng độ mờ cho phần nhấp nháy hoặc chúng tôi có thể lưu các phần tử giả giới hạn của mình trong trường hợp chúng tôi cần chúng cho một số trường hợp-

    CS CSS là một CSS tuyệt vời HÌNH 8. 25 Bây giờ văn bản được tiết lộ từng ký tự, nhưng vẫn còn thiếu một cái gì đó

    thứ khác và thay vào đó hãy sử dụng đường viền bên phải

    @keyframes gõ { từ { chiều rộng. 0 } }

    BÍ MẬT #45. Gõ HOẠT HÌNH

    323

    @keyframes dấu mũ { 50% { màu viền. trong suốt; . 15ch; . ẩn giấu; . cái bọc; . . rắn 05em; . gõ 6s bước[15], dấu mũ 1s bước[1] vô hạn;

    CS

    Lưu ý rằng không giống như hoạt ảnh tiết lộ văn bản, dấu mũ cần nhấp nháy

    CSS là một

    vô thời hạn [ngay cả sau khi tất cả các văn bản đã được tiết lộ], do đó

    từ khóa vô hạn. Ngoài ra, chúng tôi không phải chỉ định màu đường viền, vì chúng tôi

    CSS thật tuyệt vời

    muốn nó tự động lấy màu chữ. Bạn có thể thấy một vài ảnh tĩnh từ

    HÌNH 8. 26

    kết quả trên Hình 8. 26. Bây giờ hoạt hình của chúng tôi hoạt động hoàn hảo, mặc dù nó vẫn chưa chính lắm-

    Hình ảnh động của chúng tôi hiện đã hoàn tất với một dấu mũ nhấp nháy thực tế

    có thể đạt được. nó yêu cầu đặt các kiểu khác nhau trên mỗi tiêu đề, tùy thuộc vào số lượng ký tự trong nội dung và phải cập nhật chúng mỗi khi chúng tôi chỉnh sửa nội dung đã nói. Đây chính xác là loại nhiệm vụ mà JS hoàn hảo cho

    $$['h1']. forEach[hàm[h1] {

    JS

    var len = h1. văn bảnnội dung. chiều dài, s = h1. Phong cách; . chiều rộng = len + 'ch'; . animationTimingFunction = "bước["+len+"],bước[1]";

    Chỉ với vài dòng JS này, giờ đây chúng ta có thể có bánh và ăn nó. hoạt hình của chúng tôi không chỉ thực tế mà còn có thể duy trì được

    324

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    Tất cả điều này thật tuyệt và bảnh bao, nhưng điều gì sẽ xảy ra với các trình duyệt không hỗ trợ hoạt ảnh CSS?

    h1 { chiều rộng. 15ch; . ẩn giấu; . cái bọc; . . rắn 05em;

    HÌNH 8. 27

    CSS thật tuyệt vời. CSS thật tuyệt vời

    Dự phòng tiềm năng cho các trình duyệt không hỗ trợ hoạt hình CSS [trên cùng. với giá đỡ thiết bị ch, phía dưới. không có hỗ trợ đơn vị ch]

    Tùy thuộc vào việc họ có hỗ trợ thiết bị ch hay không, họ sẽ thấy một trong các dự phòng trong Hình 8. 27. Nếu bạn muốn tránh cái dưới cùng, bạn cũng có thể cung cấp dự phòng trong đơn vị em. Nếu bạn không muốn có dấu nháy không nhấp nháy trong dự phòng của mình, bạn có thể thay đổi hoạt ảnh dấu nháy để bao gồm đường viền trong khung hình chính, để khi nó bị loại bỏ, bạn chỉ nhận được đường viền trong suốt không nhìn thấy được, như vậy

    @keyframes dấu mũ { 50% { màu viền. màu hiện tại; . */ đường viền bên phải. . 05em rắn suốt; . gõ 6s bước[15], dấu mũ 1s bước[1] vô hạn;

    BÍ MẬT #45. Gõ HOẠT HÌNH

    325

    Điều này khá tốt khi dự phòng nhận được. trong các trình duyệt cũ hơn, không có hình ảnh động, nhưng không có gì bị hỏng cả và văn bản hoàn toàn có thể truy cập được và thậm chí được tạo kiểu theo cùng một cách. CHƠI. chơi. bí mật css. io/đang gõ

    ■ Ảnh động CSS w3. org/TR/css-animations ■ Đơn vị và Giá trị CSS w3. giá trị org/TR/css

    326

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    RELATED

    SPECS

    46

    Hoạt ảnh trạng thái mượt mà Điều kiện tiên quyết Hoạt ảnh CSS cơ bản, hướng hoạt ảnh [được đề cập ngắn gọn trong bí mật “Nhấp nháy” trên trang 314]

    Sự cố Ảnh động không phải lúc nào cũng bắt đầu khi tải trang. Thông thường, chúng tôi muốn sử dụng hoạt ảnh để phản hồi hành động của người dùng, chẳng hạn như di chuột qua một phần tử hoặc giữ chuột trên phần tử đó [. tích cực]. Trong trường hợp đó, chúng tôi có thể không kiểm soát được số lần lặp lại thực tế, vì hoạt động của người dùng có thể buộc hoạt ảnh dừng lại trước khi có cơ hội hoàn thành số lần lặp lại mà chúng tôi đã chỉ định. Ví dụ, người dùng có thể kích hoạt một ưa thích. hoạt ảnh di chuột và di chuột ra khỏi phần tử trước khi hoạt ảnh kết thúc. Bạn mong đợi điều gì sẽ xảy ra trong những trường hợp này? . Theo mặc định, hoạt ảnh

    328

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    HÌNH 8. 28 Cuối cùng tôi quyết định tìm giải pháp cho vấn đề này khi làm việc trên một trang web đơn giản chỉ có một trang làm quà sinh nhật cho bạn tôi Julian [juliancheal. đồng. anh]. Chú ý hình tròn bên phải. Tệp hình ảnh tôi có thực sự là phong cảnh. Vòng tròn cắt phần bên phải của nó, nhưng khi người dùng di chuột qua nó, nó sẽ từ từ bắt đầu cuộn sang trái, để lộ phần bị cắt. Theo mặc định, khi người dùng di chuyển con trỏ của họ đi, nó đột ngột quay trở lại vị trí ban đầu, khiến giao diện người dùng có cảm giác bị hỏng. Bởi vì đây là một trang web nhỏ và bức ảnh này là tâm điểm, tôi quyết định không thể nhắm mắt làm ngơ trước vấn đề này.

    sẽ chỉ dừng lại và đột ngột quay trở lại trạng thái trước khi hoạt hình. Điều này đôi khi có thể được chấp nhận trong trường hợp hoạt ảnh rất tinh tế. Tuy nhiên, trong hầu hết các trường hợp, nó chỉ dẫn đến trải nghiệm người dùng rất khó hiểu. chúng ta có thể

    Đây là một lý do khác để sử dụng hiệu ứng chuyển tiếp khi có thể. Thay vì đột ngột chuyển sang trạng thái chuẩn bị hoạt hình, các chuyển đổi phát ngược lại để chuyển đổi trở lại một cách suôn sẻ

    thay đổi hành vi này?

    về giá trị ban đầu

    Giải pháp Giả sử chúng ta có một bức ảnh phong cảnh rất dài, chẳng hạn như bức ảnh trong Hình 8. 29, nhưng không gian chúng tôi có sẵn để hiển thị nó là hình vuông 150 × 150 pixel. Một cách để giải quyết vấn đề là hoạt hình. hiển thị cạnh trái của hình ảnh theo mặc định và làm cho nó cuộn để hiển thị phần còn lại khi người dùng

    BÍ MẬT #46. HOẠT HÌNH TRẠNG THÁI MƯỢT

    329

    HÌNH 8. 29 Toàn bộ naxos-hy lạp. jpg, được sử dụng trong các ví dụ xuyên suốt bí mật này [ảnh do Chris Hutchison chụp]

    đang tương tác với nó [e. g. , di chuột qua nó]. Chúng tôi sẽ sử dụng một phần tử duy nhất cho hình ảnh và làm động vị trí nền của nó

    toàn cảnh { chiều rộng. 150px; . 150px; . url["img/naxos-hy lạp. jpg"]; kích thước nền. tự động 100%;

    Hiện tại, nó giống như Hình 8. 30 và không có hoạt ảnh hay tương tác. Tuy nhiên, nếu chúng tôi thử nghiệm, chúng tôi có thể thấy rằng việc thay đổi thủ công

    vị trí nền từ 0 0 ban đầu đến 100% 0 cuộn qua toàn bộ hình ảnh. Chúng tôi vừa tìm thấy khung hình chính của mình

    @keyframes toàn cảnh { đến { vị trí nền. 100% 0; . toàn cảnh { chiều rộng. 150px; . 150px; . url["img/naxos-hy lạp. jpg"];

    HÌNH 8. 30

    kích thước nền. tự động 100%;

    Hình ảnh của chúng tôi được cắt

    hoạt hình. toàn cảnh 10s thay thế vô hạn tuyến tính;

    330

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    Điều này làm việc tuyệt vời. Nó giống như một cái nhìn toàn cảnh và gần như có cảm giác như đang ở một nơi và nhìn sang trái hoặc phải. Tuy nhiên, hoạt ảnh được kích hoạt khi tải trang, điều này có thể gây mất tập trung trong ngữ cảnh, chẳng hạn như trang web du lịch, nơi người dùng có thể đang cố gắng tập trung đọc văn bản về Naxos, thay vì nhìn vào bức tranh toàn cảnh tuyệt đẹp. Sẽ tốt hơn nếu bật hoạt ảnh khi người dùng di chuột qua hình ảnh. Vì vậy, suy nghĩ đầu tiên của chúng tôi sẽ là thế này

    toàn cảnh { chiều rộng. 150px; . 150px; . url["img/naxos-hy lạp. jpg"]; kích thước nền. tự động 100%; . toàn cảnh. bay lượn,. toàn cảnh. tập trung {hoạt hình. toàn cảnh 10s thay thế vô hạn tuyến tính;

    Điều này không hoạt động như mong đợi khi chúng tôi di chuột qua hình ảnh. nó bắt đầu từ trạng thái ban đầu hiển thị phần ngoài cùng bên trái của hình ảnh và từ từ cuộn để hiển thị phần bên phải của nó. Tuy nhiên khi ta rê chuột ra thì nó lại đột ngột nhảy sang vị trí bên trái [hình 8. 31]. Chúng tôi vừa vấp phải vấn đề bí mật này là về

    HÌNH 8. 31 Di chuột qua rất trơn tru, nhưng di chuột ra đột ngột và có cảm giác đứt quãng

    BÍ MẬT #46. HOẠT HÌNH TRẠNG THÁI MƯỢT

    331

    Để khắc phục điều này, chúng ta cần nghĩ khác về những gì chúng ta đang cố gắng đạt được ở đây. Những gì chúng ta cần là không áp dụng một hình ảnh động trên. di chuột, vì điều này có nghĩa là không có ký ức về vị trí trước đó của nó. Những gì chúng ta cần là tạm dừng nó khi không có. di chuột xảy ra. Rất may, chúng tôi có một thuộc tính chỉ với mục đích tạm dừng hoạt ảnh hiện có. hoạt hình-phát-trạng thái

    HÌNH 8. 32 Giờ đây, việc di chuột ra chỉ tạm dừng hoạt ảnh—không còn nhảy đột ngột nữa

    Do đó, chúng tôi sẽ áp dụng hoạt ảnh ban đầu của mình cho. toàn cảnh, nhưng tạm dừng ban đầu, cho đến khi. di chuột áp dụng. Bởi vì nó không còn là vấn đề áp dụng và hủy hoạt ảnh, mà chỉ cần tạm dừng và tiếp tục hoạt ảnh hiện có, không có việc tua lại đột ngột. Mã cuối cùng trông như thế này và bạn có thể xem kết quả trong Hình 8. 32

    @keyframes toàn cảnh { đến { vị trí nền. 100% 0; . toàn cảnh { chiều rộng. 150px; . 150px; . url["img/naxos-hy lạp. jpg"]; kích thước nền. tự động 100%; . toàn cảnh 10s thay thế vô hạn tuyến tính; . tạm dừng; . toàn cảnh. bay lượn,. toàn cảnh. tiêu điểm { hoạt hình-phát-trạng thái. đang chạy;

    332

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    CHƠI. chơi. bí mật css. io/state-animations

    ■ Ảnh động CSS w3. org/TR/css-animations

    RELATED

    SPECS

    BÍ MẬT #46. HOẠT HÌNH TRẠNG THÁI MƯỢT

    333

    47

    Hoạt ảnh dọc theo một đường tròn Điều kiện tiên quyết Hoạt ảnh CSS, biến đổi CSS, bí mật “Hình bình hành” ở trang 84, bí mật “Hình ảnh kim cương” ở trang 90, bí mật “Nhấp nháy” ở trang 314

    Vấn đề Cách đây vài năm, khi hoạt hình CSS cơ bản vẫn còn mới và thú vị, Chris Coyier [css-tricks. com] đã hỏi tôi liệu tôi có thể nghĩ ra cách nào để tạo hiệu ứng động cho một phần tử trên đường dẫn hình tròn bằng hoạt ảnh CSS không. Vào thời điểm đó, nó chỉ là một bài tập CSS thú vị, nhưng trong tương lai, tôi đã tình cờ phát hiện ra nhiều trường hợp sử dụng thực tế. Ví dụ: Google+ sử dụng hình ảnh động như vậy khi một

    HÌNH 8. 33 Google+ sử dụng hoạt ảnh trên đường dẫn hình tròn để cho biết rằng một thành viên mới đã được thêm vào “vòng kết nối”

    thành viên được thêm vào vòng kết nối có hơn 11 thành viên. các hình đại diện hiện có hoạt hình trên một đường tròn để tạo khoảng trống cho hình đại diện mới. Một ví dụ thú vị khác có thể được nhìn thấy trên trang web công nghệ nổi tiếng của Nga habrahabr. ru [Figure 8. 34]. Như thường lệ với các trang 404, nó cung cấp menu điều hướng đến một số khu vực chính của trang web

    334

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    HÌNH 8. 34 Trang 404 của trang web công nghệ nổi tiếng của Nga habrahabr. ru

    Tuy nhiên, mỗi mục menu được trình bày dưới dạng một hành tinh quay quanh một vòng tròn và dòng chữ ở trên có nội dung “Bay tới các hành tinh khác trong vũ trụ của chúng ta. ” Tất nhiên, thật hợp lý khi chỉ di chuyển các hành tinh trên một đường tròn và không xoay chúng, điều này sẽ khiến văn bản của chúng gần như không thể đọc được. Đây chỉ là một vài trong số rất nhiều ví dụ có thể. Nhưng làm cách nào chúng ta có thể đạt được hiệu ứng như vậy với hoạt ảnh CSS? . Đánh dấu sẽ trông như thế này. HTML

    Trước khi chúng tôi bắt đầu nghĩ về hoạt hình của mình, chúng tôi sẽ áp dụng một số kiểu dáng cơ bản cho nó [kích thước, hình nền, lề, v.v. ], sao cho giống như Hình 8. 35. Bởi vì kiểu dáng này khá cơ bản nên nó không được bao gồm ở đây, nhưng

    Nếu bạn không chắc chắn về cách tạo hình tròn bằng CSS, hãy xem bí quyết “Hình elip linh hoạt” ở trang 76

    nếu bạn gặp khó khăn với nó, bạn có thể tìm thấy nó trong ví dụ trực tiếp. Điều chính cần lưu ý là đường kính của đường dẫn là 300px, vì vậy bán kính là 150px. Sau khi hoàn thành việc tạo kiểu cơ bản, chúng ta có thể bắt đầu nghĩ về hoạt ảnh của mình. Chúng tôi muốn di chuyển hình đại diện trong một vòng tròn, dọc theo con đường màu cam. BÍ MẬT #47. HOẠT HÌNH THEO ĐƯỜNG ĐƯỜNG TRÒN

    335

    Làm thế nào chúng ta có thể sử dụng hoạt hình CSS để làm điều này?

    @keyframes quay { thành { biến đổi. xoay [1 lượt];

    HÌNH 8. 35

    hình đại diện {

    Điểm xuất phát của chúng tôi, sau khi áp dụng

    hoạt hình. quay 3s tuyến tính vô hạn;

    một số kiểu dáng cơ bản—bây giờ chúng ta có thể nhận được

    biến đổi nguồn gốc. 50% 150px;

    tay của chúng tôi bị bẩn với một số hoạt ảnh CSS

    }

    Mặc dù đây là một bước đi đúng hướng, nhưng nó không chỉ di chuyển hình đại diện trên một đường tròn mà còn xoay hình đại diện xung quanh chính nó [Hình 8. 36]. Ví dụ, hãy chú ý khi hình đại diện được nửa chừng, nó cũng bị lộn ngược. Nếu nó có văn bản, văn bản cũng sẽ bị lộn ngược, đây có thể là một vấn đề về khả năng đọc. Chúng tôi chỉ muốn nó di chuyển dọc theo vòng tròn, trong khi vẫn duy trì cùng một hướng so với chính nó

    HÌNH 8. 36 Một vài ảnh tĩnh từ nỗ lực thất bại của chúng tôi trong việc tạo hoạt ảnh trên đường tròn

    Hồi đó, cả tôi và Chris đều không thể nghĩ ra một cách hợp lý nào. Cách tốt nhất mà chúng tôi có thể nghĩ ra là chỉ định nhiều khung hình chính để tính gần đúng một vòng tròn, đây rõ ràng không phải là một ý tưởng hay theo bất kỳ định nghĩa khả thi nào về một vòng tròn. Phải có một cách tốt hơn, phải không?

    336

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    Giải pháp hai yếu tố Cuối cùng tôi đã tìm ra giải pháp cho thách thức của Chris vài tháng sau đó, sau khi suy nghĩ về vấn đề này như một quá trình cơ bản trong một thời gian dài. Ý tưởng chính đằng sau giải pháp này giống như trong bí mật “Hình bình hành” ở trang 84 hoặc bí mật “Hình kim cương” ở trang 90. biến đổi lồng nhau triệt tiêu lẫn nhau. Tuy nhiên, thay vì thực hiện điều này một cách tĩnh, trong trường hợp này, nó xảy ra trên mọi khung hình của hoạt ảnh. Xin lưu ý rằng, giống như những bí mật đã nói ở trên, điều này đòi hỏi hai yếu tố. Do đó, chúng tôi cần sửa đổi HTML sạch ban đầu của mình bằng div trình bao bọc bổ sung. HTML

    Hãy áp dụng hoạt hình ban đầu mà chúng tôi đã thử trước đó cho. trình bao bọc hình đại diện. Bây giờ, như chúng ta đã thấy trong Hình 8. 36, điều này không hoạt động vì nó cũng tự xoay phần tử. Nhưng điều gì sẽ xảy ra nếu chúng ta áp dụng một cách xoay khác cho hình đại diện và xoay nó xung quanh chính nó theo cùng một độ theo hướng ngược lại? . Dù vậy vẫn có một vấn đề. chúng tôi không có một vòng quay tĩnh mà chúng tôi có thể hủy bỏ, nhưng một hình ảnh động trải qua nhiều góc độ. Ví dụ: nếu là 60deg thì ta hủy bằng -60deg [hoặc 300deg], nếu là 70deg thì ta hủy bằng -70deg [hoặc 290deg]. Nhưng bây giờ nó nằm trong khoảng từ 0-360 độ [hoặc 0-1 lượt, cũng giống như vậy], chúng ta sẽ hủy nó bằng gì? . Chúng tôi chỉ tạo hiệu ứng trên phạm vi đảo ngược [360-0deg], như vậy

    BÍ MẬT #47. HOẠT HÌNH THEO ĐƯỜNG ĐƯỜNG TRÒN

    337

    @keyframes quay { thành { biến đổi. xoay [1 lượt]; . xoay [1 lượt]; . hình đại diện { hoạt hình. quay 3s tuyến tính vô hạn; . 50% 150px; . hình đại diện > img { hoạt hình. spin-reverse 3s tuyến tính vô hạn;

    Bây giờ, tại bất kỳ thời điểm nào, khi hoạt ảnh đầu tiên được xoay x độ, hoạt ảnh thứ hai được xoay 360 – x độ, bởi vì một trong số chúng đang tăng và hoạt ảnh kia đang giảm. Đây chính xác là những gì chúng tôi muốn và như bạn có thể thấy trong Hình 8. 37, nó tạo ra hiệu ứng mong muốn. Tuy nhiên, mã có thể sử dụng một số cải tiến. Đối với một, chúng tôi đang lặp lại tất cả các tham số của hoạt ảnh hai lần. Nếu chúng tôi cần điều chỉnh thời lượng của nó, chúng tôi sẽ cần thực hiện hai lần, điều này không KHÔ lắm. Chúng ta có thể dễ dàng giải quyết vấn đề này bằng cách kế thừa tất cả các thuộc tính hoạt ảnh từ cha mẹ và ghi đè tên hoạt ảnh

    HÌNH 8. 37 Bây giờ chúng tôi đã đạt được hình ảnh động mà chúng tôi muốn, nhưng mã này khó sử dụng

    338

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    @keyframes quay { thành { biến đổi. xoay [1 lượt]; . xoay [1 lượt]; . hình đại diện { hoạt hình. quay 3s tuyến tính vô hạn; . 50% 150px; . hình đại diện > img { hoạt ảnh. thừa kế; . quay ngược;

    Tuy nhiên, chúng ta không cần một hoạt ảnh hoàn toàn mới chỉ để đảo ngược hoạt ảnh ban đầu. Bạn có nhớ thuộc tính hướng hoạt ảnh từ bí mật “Blinking” ở trang 314 không?

    giá trị thay thế là hữu ích. Ở đây, chúng ta sẽ sử dụng giá trị đảo ngược, để có được một bản sao đảo ngược của hoạt ảnh gốc, do đó loại bỏ nhu cầu về giá trị thứ hai

    @keyframes quay { thành { biến đổi. xoay [1 lượt]; . hình đại diện { hoạt hình. quay 3s tuyến tính vô hạn; . 50% 150px; . hình đại diện > img {

    BÍ MẬT #47. HOẠT HÌNH THEO ĐƯỜNG ĐƯỜNG TRÒN

    339

    hoạt hình. thừa kế; . đảo ngược;

    Và chúng ta đi. Nó có thể không lý tưởng, do yêu cầu phần tử bổ sung, nhưng chúng tôi đã đạt được một hình ảnh động khá phức tạp, với ít hơn 10 dòng CSS. CHƠI. chơi. bí mật css. io/circular-2elements

    Giải pháp một yếu tố Bạn có thể đọc toàn bộ cuộc thảo luận tại danh sách. w3. org/Archives/Public/ www-style/2012Feb/0201. html

    Kỹ thuật được mô tả trong phần trước hoạt động, nhưng không tối ưu vì nó yêu cầu sửa đổi HTML. Khi tôi lần đầu tiên nghĩ ra kỹ thuật đó, tôi đã viết thư cho danh sách gửi thư của Nhóm làm việc CSS [lúc đó tôi không phải là thành viên] và gợi ý rằng có thể chỉ định nhiều nguồn gốc biến đổi cho cùng một phần tử. Điều đó sẽ làm cho nó có thể thực hiện một cái gì đó như thế này với một yếu tố duy nhất và nó có vẻ như là một điều hợp lý để yêu cầu nói chung. Cuộc thảo luận đang diễn ra sôi nổi thì tại một thời điểm nào đó, Aryeh Gregor, một trong những biên tập viên của đặc tả CSS Transforms vào thời điểm đó, đã đưa ra một tuyên bố thoạt nghe có vẻ khó hiểu. “transform-origin chỉ là đường cú pháp. Thay vào đó, bạn luôn có thể sử dụng translate[]. ” — Aryeh Gregor

    Tuy nhiên, hóa ra mọi nguồn gốc biến đổi đều có thể được mô phỏng bằng hai biến đổi translate[]. Ví dụ: hai đoạn mã sau là tương đương

    biến đổi. xoay [30 độ]; . 200px 300px;

    340

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    biến đổi. dịch [200px, 300px] xoay [30 độ] dịch [-200px, -300px]; . 0 0;

    Điều này thoạt nghe có vẻ lạ, nhưng sẽ trở nên rõ ràng hơn nếu chúng ta lưu ý rằng các hàm biến đổi không độc lập. Mỗi trong số chúng không chỉ biến đổi phần tử mà nó được áp dụng, nó biến đổi toàn bộ hệ tọa độ của phần tử đó, do đó ảnh hưởng đến tất cả các phép biến đổi sau nó. Đây chính xác là lý do tại sao thứ tự biến đổi lại quan trọng và các thứ tự khác nhau của cùng một biến đổi có thể tạo ra các kết quả hoàn toàn khác nhau. Nếu điều này vẫn chưa rõ ràng, Hình 8. 38 sẽ giúp loại bỏ mọi nhầm lẫn. Do đó, chúng ta có thể sử dụng cùng một nguồn gốc biến đổi cho cả hai hoạt ảnh trước đây của mình bằng cách sử dụng ý tưởng này [chúng ta sẽ sử dụng lại các hoạt ảnh riêng biệt vì các khung hình chính của chúng hiện đã hoàn toàn khác]

    biến đổi. xoay [30 độ]; . 100px 50px;

    HÌNH 8. 38 Làm thế nào chúng ta có thể thay thế một gốc biến đổi bằng hai phép tịnh tiến. Màu đỏ

    50px

    30

    dấu chấm đại diện cho nguồn gốc biến đổi

    de

    g

    mỗi lần. Hàng đầu. Sử dụng biến đổi nguồn gốc. Đáy. Sử dụng hai

    100px

    dịch từng bước

    50

    px

    100px 10

    0p

    50px

    x

    30 độ

    biến đổi. dịch[100px,50px]; . 0 0;

    biến đổi. dịch [100px,50px] xoay [30deg]; . 0 0;

    biến đổi. dịch[100px,50px] xoay[30deg] dịch[-100px,-50px]; . 0 0;

    BÍ MẬT #47. HOẠT HÌNH THEO ĐƯỜNG ĐƯỜNG TRÒN

    341

    @keyframes quay { từ { biến đổi. dịch[50%, 150px] xoay[0turn] dịch[-50%, -150px]; . dịch[50%, 150px] xoay[1 lượt] dịch[-50%, -150px]; . dịch[50%,50%] xoay[1 lượt] dịch[-50%,-50%]; . dịch [50%,50%] xoay [0 lượt] dịch [-50%, -50%]; . hình đại diện { hoạt hình. quay 3s tuyến tính vô hạn; . hình đại diện > img { hoạt ảnh. thừa kế; . quay ngược;

    342

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    Điều này có vẻ cực kỳ khó sử dụng, nhưng đừng lo lắng, vì chúng tôi sẽ cải thiện nó rất nhiều vào cuối phần này. Lưu ý rằng bây giờ chúng ta không còn có các nguồn gốc biến đổi khác nhau, đó là lý do duy nhất chúng ta cần hai yếu tố và hai hoạt ảnh trước đó. Bây giờ mọi thứ đều sử dụng cùng một nguồn gốc, chúng ta có thể kết hợp hai hoạt ảnh thành một và chỉ hoạt động với. hình đại diện

    @keyframes quay { từ { biến đổi. dịch[50%, 150px] xoay[0 lượt] dịch[-50%, -150px] dịch[50%,50%] xoay[1 lượt] dịch[-50%,-50%] } sang { biến đổi. dịch[50%, 150px] xoay[1 lượt] dịch[-50%, -150px] dịch[50%,50%] xoay[0 lượt] dịch[-50%, -50%]; . hình đại diện { hoạt hình. quay 3s tuyến tính vô hạn;

    Mã chắc chắn đang được cải thiện, nhưng vẫn còn dài và khó hiểu. Chúng ta có thể làm cho nó ngắn gọn hơn một chút? . Kết quả treo thấp là kết hợp các phép biến đổi translate[] liên tiếp, cụ thể là translate[-50%, -150px] và translate[50%,

    Lưu ý rằng chúng ta không cần hai phần tử HTML nữa. chúng ta chỉ có thể áp dụng lớp hình đại diện cho chính hình ảnh, vì chúng ta không còn tạo kiểu riêng cho chúng nữa

    50%]. Thật không may, không thể kết hợp tỷ lệ phần trăm và độ dài tuyệt đối [trừ khi chúng tôi sử dụng calc[] cũng khá khó sử dụng]. Tuy nhiên, các bản dịch ngang triệt tiêu lẫn nhau, vì vậy về cơ bản chúng ta có hai bản dịch trên trục Y [translateY[-150px] translateY[50%]]. Cũng thế,

    BÍ MẬT #47. HOẠT HÌNH THEO ĐƯỜNG ĐƯỜNG TRÒN

    343

    bởi vì các phép quay triệt tiêu lẫn nhau, chúng ta cũng có thể loại bỏ các phép tịnh tiến ngang trước và sau và kết hợp các phép tịnh tiến dọc. Chúng tôi hiện có các khung hình chính này

    @keyframes spin { from { transform. translateY[150px] translateY[-50%] rotate[0turn] translateY[-150px] translateY[50%] rotate[1turn]; } to { transform. translateY[150px] translateY[-50%] rotate[1turn] translateY[-150px] translateY[50%] rotate[0turn]; } } . avatar { animation. spin 3s infinite linear; }

    Điều này ngắn hơn một chút và ít lặp lại hơn, nhưng vẫn không tuyệt vời. Can we do any better? If we start from the avatar in the center of the circle [like in Figure 8. 39], we can eliminate the first two translations, which essentially just place it at the center. Sau đó, hình ảnh động trở thành

    @keyframes quay { từ { biến đổi. xoay[0 lượt] dịchY[-150px] dịchY[50%] xoay[1 lượt];

    344

    CHƯƠNG 8. CHUYỂN TIẾP & HOẠT HÌNH

    transform. xoay[1 lượt] dịchY[-150px] dịchY[50%] xoay[0 lượt]; . hình đại diện { hoạt hình. quay 3s tuyến tính vô hạn;

    HÌNH 8. 39 This seems to be the best we can do today. It’s not the DRY-est possible

    If we center the avatar as the starting point, our keyframes become a bit

    mã, nhưng nó khá ngắn. There is now minimal repetition and no re-

    shorter; however, note that this state

    dundant HTML elements. Để làm cho nó KHÔ hoàn toàn và tránh lặp lại

    cũng sẽ là dự phòng của chúng tôi trong trường hợp

    the path radius, we could use a preprocessor, which is left as an exercise for

    hình ảnh động không được hỗ trợ, điều này có thể được mong muốn hoặc không

    độc giả. CHƠI. play. bí mật css. io/thông tư

    ■ Ảnh động CSS w3. org/TR/css-animations

    RELATED

    SPECS

    ■ Chuyển đổi CSS w3. org/TR/css-transforms

    BÍ MẬT #47. HOẠT HÌNH THEO ĐƯỜNG ĐƯỜNG TRÒN

    345

    Biểu tượng chỉ mục

    acceleration, timing function and, 296-299

    [giả] nguồn gốc ngẫu nhiên, 62-65

    khả năng chi trả, 225

    avatar, 337-340, 343

    align-items, vertical centering and, 286

    hộp đèn, 235

    dấu và, ưa thích, 188-193

    Xoay 3D, cho hình thang, 109-113

    Anderson, James, 280

    phông nền, để làm mờ, 238

    GIF động, thiếu sót của, 308

    lớp giả thứ n[], 178, 271-275

    hoạt hình, 294-345

    con một, 272

    dọc theo một con đường tròn, 334-345

    , 314

    nhấp nháy, 314-318

    phần tử, 182

    nảy, 295-299

    , 173-177

    chuyển đổi sang chuyển đổi, 301

    , 238

    thời lượng so với. hiệu quả, 321

    , 252

    chuyển tiếp đàn hồi, 294-305

    , 173-177

    cho biểu đồ hình tròn, 119-121

    , 229

    từng khung hình, 308-312

    , 241

    trạng thái mịn, 328-332

    , 211

    đánh máy, 320-326

    phần tử, 182

    hướng hoạt hình, 316, 339

    , 189, 210

    hoạt hình-playstate, 332

    , 211

    hoạt hình-thời gian-chức năng, 296

    @phông-mặt, 189

    APNG, 309

    [gạch nối mềm], 168

    giả định, xxiv

    A

    Hệ thống bản đồ, xxii

    định vị tuyệt đối, để định tâm theo chiều dọc, 281

    347

    thuật toán bố trí bảng tự động, 266

    giới hạn của, 68 với độ dốc, 73

    B

    bán kính đường viền

    tầng lớp]

    cho hình elip, 76-81

    [giả]ngẫu nhiên, 62-65 và đường viền tròn bên trong, 37

    đối với biểu đồ hình tròn, 116 đường viền, 24

    và các đường sọc ngựa vằn, 180

    ảnh liên tục, 68-74

    bàn cờ, 55-60

    làm tròn trong của, 36-38

    mẫu phức tạp, 50-60

    nhiều, 28-30

    sọc chéo, 43-47

    mờ, 24-26

    định vị linh hoạt, 32-35

    Bos, Bert, 5

    chất lỏng có hàm lượng cố định, 276-279

    hình ảnh động nảy, 295-299

    lưới, 52

    hiệu ứng nảy, 294

    chấm bi, 53

    bóng hộp

    sọc, 40-48

    và mở rộng khu vực có thể nhấp, 226

    sọc dọc, 43

    và đường viền tròn bên trong, 37

    tệp đính kèm nền, 246

    để làm mờ, 237

    chế độ hòa trộn nền, 141

    cho nhiều đường viền, 29

    clip nền, 26, 70, 225

    đối với bóng một bên, 130

    hình nền, gạch chân văn bản và, 196

    với bóng đổ không đều, 134

    nguồn gốc nền, 33

    kích thước hộp, 30

    vị trí nền, 33, 310, 330

    ngắn gọn, khả năng bảo trì vs. , 12

    kích thước nền

    bộ lọc độ sáng[], 242

    đối với hình nền [giả] ngẫu nhiên, 62-65

    hỗ trợ trình duyệt, xxxx-xxxiv

    cho sọc, 43

    nút, 10-12

    vát góc, 96, 157-159

    hình bình hành và, 84

    Đường cong Bézier, 298

    thường xuyên v. chuyển đổi, 232

    chế độ hòa trộn

    nút chuyển đổi, 231

    bộ lọc so với. , 142 cho pha màu, 141-143

    C

    để so sánh hình ảnh tương tác, 259

    calc[] [hàm]

    nhấp nháy, 314-318

    và định tâm dọc, 282

    dấu mũ nhấp nháy, 323

    để định vị nền linh hoạt, 35

    phần tử khối, 173

    cho chân trang cố định, 290

    bộ lọc blur[], 149

    chú thích, chuyển tiếp linh hoạt cho, 300-304

    làm mờ, để giảm nhấn mạnh, 240-243

    dấu mũ, nhấp nháy, 323

    viền dưới, 195

    con trỏ ô, 219

    hộp viền, 26

    Tập trung vào cái không biết [Chris Coyier], 281

    hình ảnh đường viền

    định tâm, dọc, 280-286

    đối với các góc cắt cong, 102-105

    348

    MỤC LỤC

    đơn vị ch, 323

    hộp kiểm

    chấm bi, 53

    tùy chỉnh, 228-232

    đường viền hình ảnh liên tục, 68-74

    nút chuyển đổi so với. , 232

    bộ lọc tương phản [], 242

    đã kiểm tra [lớp giả], 229

    điểm kiểm soát, 298

    bàn cờ, 55-60

    góc, cắt bỏ, 96-107

    Nguyên lý ve sầu, The, 63, 65

    Coyier, Chris, 281, 334

    đường tròn, hình ảnh động dọc theo, 334-345

    CSS

    văn bản tròn, 210-214

    sự phát triển và biến đổi gần đây của, xvii

    khu vực có thể nhấp, mở rộng, 224-227

    tiêu chuẩn/thông số kỹ thuật, 2-8

    đường dẫn clip

    CSS1, 5

    đối với các góc bị cắt, 105-107

    CSS2, 5

    cho hình ảnh kim cương, 93

    CSS3, 6

    viền trên được cắt bớt, 73

    Nhóm công tác CSS [CSS WG], 2-8

    sao chép mã, giảm thiểu, 9-12

    hàm cube-bezier[], 298-299, 302

    mẹo mã hóa, 22-9

    Màu hiện tại, 13

    và hành vi của mắt, 15

    con trỏ

    và Thiết kế web đáp ứng, 15-17

    tích hợp, 218-221

    Màu hiện tại, 13

    trốn, 221

    thừa kế, 13

    cho biết trạng thái bị vô hiệu hóa, 220

    khả năng bảo trì so với. ngắn gọn, 12

    góc cắt cong, 100

    giảm thiểu mã trùng lặp, 9-12

    góc cắt, 96-107

    tiền xử lý, 19-22

    phương pháp cắt đường dẫn cho, 105-107

    sử dụng tốc ký, 17-19

    cong, 100

    màu, 11

    độ dốc cho, 97

    và chuyển tiếp đàn hồi, 305 màu hiện tại, 13

    phương pháp SVG/hình ảnh đường viền nội tuyến, 102-105

    cho biểu đồ hình tròn, 115

    D

    với các góc cắt cong, 104

    không nhấn mạnh

    với các sọc tinh tế linh hoạt, 48 điểm dừng màu

    bằng cách làm mờ, 240-243 bằng cách làm mờ, 234-238

    và các mẫu bàn cờ, 56

    danh sách định nghĩa, ngắt dòng cho, 172

    và nền sọc, 44

    sọc chéo, 43-47

    cho lưới, 52

    hình ảnh kim cương, 90-94

    pha màu, 138-143

    mờ đi

    chế độ hòa trộn cho, 141-143

    phương pháp phông nền, 238

    bộ lọc cho, 139

    giảm nhấn mạnh bởi, 234-238

    chiều rộng cột, bảng, 266-268 mẫu nền phức tạp, 50-60

    phương thức phần tử giả, trạng thái bị vô hiệu hóa 236, con trỏ, 220

    bàn cờ, 55-60

    chữ ghép tùy ý, 184

    lưới, 52

    trưng bày. uốn cong

    MỤC LỤC

    349

    và căn giữa theo chiều dọc, 285 cho chân trang cố định, 291

    nền mở rộng cho, 33 hình elip linh hoạt, 76-81

    đổ bóng, không đều, 134-137

    sọc tinh tế linh hoạt, 48

    bộ lọc bóng đổ [], 135, 137

    nền linh hoạt, nội dung cố định với, 276-279

    Lập trình DRY, xviii

    hiệu ứng góc gấp, 156-165

    sao chép mã, giảm thiểu, 9-12

    cho các góc 45º, 157-159 cho các góc khác 45º, 159-165

    E

    cỡ chữ, 10

    dễ dàng [từ khóa], 296

    khai báo họ phông chữ, 189

    Eden, Đan, 300

    biến thể phông chữ chữ ghép, 185

    chuyển tiếp đàn hồi, 294-305

    chân trang, cố định, 288-292

    hình ảnh động nảy, 295-299

    biên giới chú thích, 73

    cho chú thích, 300-304

    định dạng và quy ước, xxvi

    hình elip

    hình ảnh động theo từng khung hình, 308-312

    linh hoạt, 76-81

    hiệu ứng kính mờ, 146-154

    một nửa, 79-81

    phần tương lai, xxviii

    quý, 81 phương pháp vị trí nền mở rộng, 33

    G

    mở rộng vùng có thể nhấp, 224-227

    Gallagher, Nicolas, 87, 156

    văn bản ép đùn, 206

    Thuật toán làm mờ Gaussian, 131

    mắt, con người, 15

    GIF, hoạt hình, thiếu sót của, 308 văn bản phát sáng, 205

    F

    glyphs, chữ ghép như, 184

    điền [từ khóa], 103

    Trình đọc Google, 244

    lấp đầy. không có, 213

    Google+, 334

    [các] bộ lọc

    các mẫu dựa trên độ dốc, 71

    chế độ hòa trộn vs. , 142

    độ dốc, cho các góc bị cắt, 97

    pha màu, 139

    Thuật toán tham lam, 169

    để so sánh hình ảnh tương tác, 259

    Gregor, Aryeh, 340

    với bóng đổ không đều, 135 Luật Fitts, 224

    H

    Phù hợp, Paul, 224

    habrahabr. ru, 334

    nội dung cố định, hình nền linh hoạt với, 276-279

    nửa hình elip, 79-81

    thuật toán bố trí bảng cố định, 268

    Hattab, Hakim El, 243

    dòng chảy linh hoạt, 291

    ẩn con trỏ, 221

    Hộp linh hoạt

    bộ lọc hue-rotate[], 140

    để định tâm theo chiều dọc, 285 định vị nền linh hoạt, 32-35 phương pháp nền gốc cho, 33 calc[] phương pháp cho, 35

    350

    MỤC LỤC

    gạch nối, 168-170

    gạch nối. ô tô, 169

    bội số chung nhỏ nhất [LCM], cho các nền ngẫu nhiên [giả], 64

    I

    hiệu ứng dập chữ, 201

    so sánh hình ảnh, tương tác, 250-259

    Nói dối, Håkon Wium, 5

    Phương pháp thay đổi kích thước CSS cho, 251-254

    chữ ghép, 184-186

    phương pháp nhập phạm vi cho, 255-259

    Lille, Chris, 5

    hình ảnh, làm đường viền, 68

    ngắt dòng, chèn, 172-177

    vô hạn [từ khóa], 324

    độ dốc tuyến tính

    kế thừa [từ khóa], 13

    và lưới, 52

    thừa kế, 13

    và nền sọc, 41

    SVG nội tuyến, 102-105, 211

    đối với các góc bị cắt, 97

    bán kính viền trong, 100

    dòng, văn bản, sọc ngựa vằn, 178-181

    làm tròn trong [viền], 36-38

    hàm cục bộ[], 190

    so sánh hình ảnh tương tác, 250-259

    bàn tay dài, 18

    kích thước nội tại, 262-264 đổ bóng không đều, 134-137

    M khả năng bảo trì, ngắn gọn so với. , 12

    J

    biên giới kiến ​​diễu hành, 72

    Jacobs, Ian, 5

    lề. ô tô, 277, 285

    JavaScript

    chiều rộng tối đa, 264

    cho hình ảnh động theo từng khung hình, 309

    McClellan, Drew, 193

    để gõ hoạt hình, 324

    truy vấn phương tiện, 15-17

    biện minh, văn bản, 168 biện minh-nội dung, 286

    Meyer, Eric, 66 nội dung tối thiểu [từ khóa], 263 chế độ hòa trộn, 141

    Thuật toán Knuth-Pass, 169 Komarov, Roman, 249

    hộp thoại phương thức, 238 Montulli, Lou, 314 con trỏ chuột, 218 Mozilla, 309

    Độ trễ L, 20

    nhiều đường viền, 28-30 hộp bóng cho, 29

    Law of Leaky Abstractions, 20

    phác thảo cho, 30

    bố cục, 262-292 nền linh hoạt với nội dung cố định, kích thước nội tại 276-279, chân trang cố định 262-264, kiểu dáng 288-292 theo số lượng anh chị em, chiều rộng cột bảng 270-275, 266-268

    N độ trễ hoạt ảnh âm, 119-121 phần tử lồng nhau, cho hình bình hành, 85 phép biến đổi lồng nhau, 337

    định tâm dọc, 280-286

    MỤC LỤC

    351

    con trỏ không được phép, 220

    cho các góc cắt cong, 103

    O

    Q

    bóng một bên, 130-133

    hình elip phần tư, 81

    ảo ảnh quang học, 15, 200 độ lệch phác thảo, 30

    R

    phác thảo, cho nhiều đường viền, 30

    độ dốc xuyên tâm

    tràn ra. ẩn, 116, 152

    đối với các góc cắt cong, 100

    tràn ra. có thể nhìn thấy, 213

    cho chấm bi, 53 nền ngẫu nhiên, 62-65

    P

    khả năng đọc, biện minh và, 168

    hình bình hành, 84-87

    lặp lại tuyến tính-gradient[], 45-47

    hoa văn, làm đường viền, 68

    lặp lại-radial-gradient[], 45

    biểu đồ hình tròn

    thay đổi kích thước, để so sánh hình ảnh tương tác, 251-254

    Giải pháp SVG cho, 122-128

    Thiết kế web đáp ứng [RWD], 15-17

    giải pháp dựa trên biến đổi cho, 115

    xoay [] chuyển đổi

    biểu đồ hình tròn, đơn giản, 114-128

    cho hình ảnh động dọc theo đường tròn, 337-340

    Hoạt hình ma quỷ PNG, 309-312

    cho hình ảnh kim cương, 91

    hình nền chấm bi, 53

    cho hình bình hành, 87

    đa giác [], cho hình ảnh kim cương, 93

    cho biểu đồ hình tròn, 117

    Chức vụ. tương đối/tuyệt đối, 86 tiền xử lý, 19-22

    làm tròn, bên trong [viền], 36-38

    đối với các mẫu nền phức tạp, 50

    S

    cho hiệu ứng góc gấp, 165

    Saly, Martijn, 105

    điều kiện tiên quyết, xxv

    bộ lọc bão hòa [], 139

    số nguyên tố, cho nguồn gốc [giả] ngẫu nhiên, 65

    biến đổi tỷ lệ []

    phần tử giả để làm mờ, 236

    đối với hình ảnh kim cương, 92 đối với chuyển tiếp đàn hồi, 302

    cho hình bình hành, 86

    cuộn, 244-249

    cho biểu đồ hình tròn, 116, 117

    Seddon, Ryan, 231

    cho hình thang, 110

    bóng tối

    nắm bắt tương tác chuột bằng, 226 định lý Pythagore, 160

    giảm không đều, 134-137 một bên, 130-132

    và đường viền tròn bên trong, 38

    ở hai cạnh kề nhau, 132

    và nền sọc, 44

    trên hai mặt đối diện, 133 hình một mặt, 130-133, góc cắt 76-128, hình thoi 96-107, hình elip linh hoạt 90-94, 76-81

    352

    MỤC LỤC

    nửa hình elip, 79-81

    văn bản ép đùn, 206

    hình bình hành, 84-87

    văn bản phát sáng, 205

    biểu đồ hình tròn, 114-128

    in thư, 201

    hình elip phần tư, 81

    thực tế, 200-208

    tab hình thang, 108-113

    nét chữ, 203

    viết tắt, sử dụng, số lượng anh chị em 17-19, tạo kiểu bởi, 270-275

    gõ hoạt hình, 320-326 văn bản biện minh, 168

    biểu đồ hình tròn đơn giản, 114-128

    dòng văn bản, sọc ngựa vằn, 178-181

    Simurai, 312

    gạch dưới văn bản, tùy chỉnh, 194-197

    kích thước, nội tại, 262-264

    trang trí văn bản. nháy mắt, 315

    phép biến đổi skew[], 84

    bóng văn bản

    điều khiển thanh trượt, 256-259

    và văn bản ép đùn, 207

    hình ảnh động trạng thái mượt mà, 328-332

    và văn bản phát sáng, 205

    dấu gạch nối mềm [], 168

    và hiệu ứng letterpress, 202

    bán kính trải rộng, 29, 131

    và nét chữ, 203

    hoạt hình sprite, 309-312

    và gạch chân văn bản, 197

    các bước [] chức năng thời gian, 311, 317, 322

    với bóng đổ không đều, 137

    chân trang cố định, 288-292

    xoay ba chiều [3D], cho hình thang, 109-113

    Tầng, Dudley, 66, 144, 259, 264

    chức năng hẹn giờ, 296-299

    nền sọc, 40-48

    pha màu, 138-143

    sọc chéo, 43-47

    nút chuyển đổi, 231

    sọc tinh tế linh hoạt, 48

    [các] biến đổi

    sọc dọc, 43

    và hình bình hành, 86

    dòng văn bản sọc, 178-181

    cho hình ảnh kim cương, 91

    đột quỵ-dasharray, 122-126

    cho biểu đồ hình tròn, 115, 117

    nét chữ, 203

    cho hình thang, 109-113

    các yếu tố phong cách, số lượng anh chị em và, 270-275

    sự phụ thuộc lẫn nhau của các hàm biến đổi, 341

    SVG cho mẫu bàn cờ, 59 cho biểu đồ hình tròn, 122-128

    biến đổi nguồn gốc, 163 cho hình thang, 111 translate[] so với. , 340 kiểu biến đổi, định tâm theo chiều dọc và, 283

    T

    thời lượng chuyển tiếp, 304

    điều chỉnh độ rộng tab, 182

    thuộc tính chuyển tiếp, 305

    kích thước tab, 183

    chức năng thời gian chuyển tiếp, 296

    bố cục bảng [thuộc tính], 266

    chuyển tiếp và hình ảnh động, 294-345

    những cái bàn

    hoạt ảnh dọc theo đường tròn, 334-345

    chiều rộng cột, 266-268

    nhấp nháy, 314-318

    dòng sọc ngựa vằn trong, 178-181

    chuyển đổi hoạt ảnh thành chuyển tiếp, 301

    hiệu ứng văn bản văn bản tròn, 210-214

    chuyển tiếp linh hoạt, 294-305 hình ảnh động theo từng khung hình, 308-312

    MỤC LỤC

    353

    hình ảnh động trạng thái mượt mà, 328-332

    so sánh hình ảnh tương tác, 250-259

    gõ hoạt hình, 320-326

    cuộn, 244-249

    translate[] và căn giữa theo chiều dọc, 282

    nút chuyển đổi, 231

    cho hình ảnh động dọc theo đường tròn, 343

    V

    nguồn gốc biến đổi vs. , 340

    tiền tố nhà cung cấp, 6-8

    viền mờ, 24-26

    định tâm dọc, 280-286 định vị tuyệt đối cho, 281

    minh bạch, mô hình bàn cờ màu xám để mô tả,

    Flexbox cho, 285

    55

    đơn vị khung nhìn cho, 284

    tab hình thang, 108-113

    sọc dọc, 43

    hiệu ứng hình tam giác và góc gấp, 156-165

    xemBox, 212

    cho các mẫu bàn cờ, 55

    đơn vị khung nhìn, 237

    gõ hoạt hình, 320-326

    đường viền theo chủ đề phong bì cổ điển, 71

    kiểu chữ, 168-214

    hiệu ứng hình ảnh, pha màu 130-165, 138-143

    văn bản tròn, gạch chân tùy chỉnh 210-214, 194-197

    hiệu ứng góc gấp, 156-165

    hiệu ứng chữ ép đùn, 206

    hiệu ứng kính mờ, 146-154

    dấu và ưa thích, 188-193

    đổ bóng không đều, 134-137

    hiệu ứng chữ phát sáng 205

    bóng một bên, 130-133

    gạch nối, chèn ngắt dòng 168-170, hiệu ứng ép chữ 172-177, chữ ghép 201, hiệu ứng văn bản thực tế 184-186, 200-208

    W W3C [World Wide Web Consortium], 2 Walker, Alex, 63, 65 chuẩn web, 2-8 và tiến hóa CSS, 5

    hiệu ứng chữ nét, 203

    và tiền tố nhà cung cấp, 6-8

    điều chỉnh độ rộng tab, 182 dòng văn bản sọc ngựa vằn, 178-181

    U

    quy trình tạo, lập trình 2-4 WET, khoảng trắng xviii. , 174

    gạch chân, tùy chỉnh, 194-197

    Wichary, Marcin, 198

    bộ mô tả phạm vi unicode, 191

    gói từ, 169

    trải nghiệm người dùng, 218-259

    gói, từ, 169

    lựa chọn con trỏ, 218-221 hộp kiểm tùy chỉnh, 228-232 giảm nhấn mạnh bằng cách làm mờ, 240-243 giảm nhấn mạnh bằng cách làm mờ, 234-238 mở rộng vùng có thể nhấp, 224-227

Chủ Đề