<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Diana Le</title>
    <description>The latest articles on DEV Community by Diana Le (@dianale).</description>
    <link>https://dev.to/dianale</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F700453%2F116717e0-f22d-4c75-a6cf-671bdc3b8cac.jpg</url>
      <title>DEV Community: Diana Le</title>
      <link>https://dev.to/dianale</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dianale"/>
    <language>en</language>
    <item>
      <title>Better Accessibility: My Path to the CPACC</title>
      <dc:creator>Diana Le</dc:creator>
      <pubDate>Tue, 09 Dec 2025 17:00:00 +0000</pubDate>
      <link>https://dev.to/dianale/better-accessibility-my-path-to-the-cpacc-37d3</link>
      <guid>https://dev.to/dianale/better-accessibility-my-path-to-the-cpacc-37d3</guid>
      <description>&lt;p&gt;I took the Certified Professional in Accessibility Core Competencies (CPACC) exam offered by the International Association of Administrative Professionals (IAAP) in August of this year, and aside from PSATs/SATs in high school, I have never studied so much for one exam in my life. I have also never &lt;strong&gt;PAID&lt;/strong&gt; as much for an exam in my life. I found people's shared online experiences helpful when I was debating taking this test, so I'm adding my thoughts as well. Overall I'm glad that I decided to take the test, but the entire process had some surprising steps and was not entirely smooth.&lt;/p&gt;

&lt;p&gt;This is not a direct how-to guide. I may have &lt;del&gt;failed&lt;/del&gt; passed, but people are different in how they learn; I'm just hoping some added context is helpful to anyone else looking to take the exam because I researched as much as I could before registering.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why Take the Test&lt;/li&gt;
&lt;li&gt;
My Background

&lt;ul&gt;
&lt;li&gt;Why Focus on Accessibility&lt;/li&gt;
&lt;li&gt;Previous Lack of Management Buy-in&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

A Condensed Timeline

&lt;ul&gt;
&lt;li&gt;Deque University&lt;/li&gt;
&lt;li&gt;Book of Knowledge&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Second Thoughts

&lt;ul&gt;
&lt;li&gt;Going Old School&lt;/li&gt;
&lt;li&gt;Slow and Steady&lt;/li&gt;
&lt;li&gt;An Unexpected but Relevant Roadblock&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Taking the Test

&lt;ul&gt;
&lt;li&gt;The Application Process&lt;/li&gt;
&lt;li&gt;Scheduling&lt;/li&gt;
&lt;li&gt;Test Day&lt;/li&gt;
&lt;li&gt;The Exam&lt;/li&gt;
&lt;li&gt;Total Time Spent Studying&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Exam Criticisms

&lt;ul&gt;
&lt;li&gt;Wide Range of Topics and Specificity&lt;/li&gt;
&lt;li&gt;Not Following their Own Recommendations&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Post-Exam Reflection

&lt;ul&gt;
&lt;li&gt;Lack of Confidence&lt;/li&gt;
&lt;li&gt;The Wait&lt;/li&gt;
&lt;li&gt;Lingering Questions&lt;/li&gt;
&lt;li&gt;One Tool&lt;/li&gt;
&lt;li&gt;A Needed Boost&lt;/li&gt;
&lt;li&gt;Recommendations in Hindsight&lt;/li&gt;
&lt;li&gt;Online Resources&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Take the Test &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;I got laid off earlier this year so I had plenty of time each day to study (albeit not while in the happiest mood), although after going through this process I feel it's better to spread out the information over more days because getting a good night's sleep helped me retain the knowledge.&lt;/p&gt;

&lt;p&gt;There is also a lack of certifications for web development / front-end engineering. This certification felt at least somewhat universally known and I wanted to learn more about accessibility anyway. There are also more job postings that mention accessibility and ones that have specifically mentioned IAAP and their certifications — not a lot total but more than I've seen in the past.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Background &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;I've been a front-end web developer for 12+ years. I started focusing more on accessibility 7-8 years ago after learning more about the topic from conferences and from other web developers I follow, but this effort has always been non-critical to my jobs. I’ve proactively made the effort to learn and to be accessible as I can within the budget, particularly regarding using the proper semantic tags in HTML, making sure form labels are appropriate, ensuring contrast is sufficient, and interactive states are captured by ARIA, etc. I also run through my sites using VoiceOver on MacOS. But overall the jobs I've had never required or had specific criteria to check against. I would give and receive feedback from other accessibility-minded developers at work, but this was nothing official. Accessibility was a nice-to-have and something to strive for, but the on-work training and executive buy-in for a standardized process was never there.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Focus on Accessibility &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;What kickstarted my focus the most was during a talk on accessibility, the presenter said that it's highly unlikely that designers/developers were specifically trying to make life harder for people with disabilities, but rather they lacked that extra viewpoint when navigating web sites. I try to be as empathetic as I can, and this opened my eyes to all the things that HTML natively provides that a developer can unintentionally break.&lt;/p&gt;

&lt;p&gt;Earlier on in my career I really had to fight to keep things accessible. Project managers would ask to remove focus outlines from input fields just because they didn't like the look but I would argue to keep them because of the accessibility issues of removing them. It was one thing to not follow checklists, but proactively spending time to remove useful if visually displeasing things was mind-blowing to me.&lt;/p&gt;

&lt;h3&gt;
  
  
  Previous Lack of Management Buy-in &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The biggest argument I had was when a client wanted to remove all keyboard focus states off their web site because my company never designed the native focus outlines provided by the browser, so the outline colors were the browser defaults. For my client these outlines didn't match the color scheme of their branding. I told my project manager that I would choose a more appropriate color and updated the CSS. The client came back and said they still wanted them removed. I told my project manager to wait, and then talked to my director. I told him what the client wanted, why this was bad — both from an accessibility perspective and from a potential lawsuit perspective — and also linked relevant articles on why focus states should never be removed. He responded with, "But the client doesn't like them," and that was the end of the conversation.&lt;/p&gt;

&lt;p&gt;I felt incredibly dejected that day. I've had plenty of bad experiences at work, but this one particularly bothered me because it felt especially wrong to exclude people with disabilities from functionally navigating the site for the sole reason that one person didn't like it for aesthetic reasons. And I had substantial evidence for why they shouldn't be removed, but my managers seemed to only want the path of least resistance.&lt;/p&gt;

&lt;p&gt;With an accessibility certification though, I feel like I would be empowered and have credibility to argue my positions. If this certification had existed back then, maybe I would have had more power in that exchange. The environment now is also much different than it was 5 years ago, with more accessibility laws in existence across the globe and more general awareness of its importance.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Condensed Timeline &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Deque University &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;I already knew of Deque University from a previous job where my coworkers were trying to complete the Web Accessibility Specialist (WAS) course outside of project work to get certified (this wound up being an untenable goal due to the nature of client work unfortunately). But since I had heard good things about the platform, I decided to purchase. The IAAP exam dates are arranged into sessions, and ideally I would have preferred an additional two weeks to prepare, but since I had no idea what my job situation would be like by the time of the next exam session, I decided to register even if the timeline felt rushed.&lt;/p&gt;

&lt;p&gt;My goal was to finish the Deque course and finish my own separate notes on the course at least a couple days before applications closed on July 16. If I reached that critical goal I would apply and register for the exam. I received access to the Deque course on June 17. I planned to take the exam near the end of the period which was August 12. That would give me a little less than two months to prepare for the exam. &lt;/p&gt;

&lt;p&gt;Because Deque has a progress tracker on the course depending on how far you've clicked through the lessons, I used this to set a mini-goal to achieve a certain percentage each day. The problem with this strategy is that Deque seems to base this on number of pages rather than total content. So if you're reading through lessons with one or two paragraphs per page, it will seem like you're progressing further than you actually are. Once I reached pages with 10+ paragraphs and tabbed sections, I felt demoralized at how slow I was going.&lt;/p&gt;

&lt;h3&gt;
  
  
  Book of Knowledge &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Once I finished the Deque course, I read through the IAAP Book of Knowledge (BOK) and cross-referenced my notes from the course and filled in any missing information or better-worded concepts. That took another full week. By the end my converted PDF of notes was 160+ pages long. I was surprised how short some sections in the BOK were compared to Deque, but I suppose that's why you pay for the course.&lt;/p&gt;

&lt;h2&gt;
  
  
  Second Thoughts &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Once I got deeper into the Deque course I wondered if I had made the right choice in taking the CPACC versus the WAS, which would have been more in line with what I've already been doing for years. I appreciated the background information and context that I was learning on &lt;strong&gt;why&lt;/strong&gt; we should do things certain ways on the web. But it was so much new information and the diversity of topics made it harder for me too. Information like the disability models and types of disabilities, while mostly new information, made sense. Web accessibility and universal design were the most familiar topics but still a lot of new information.&lt;/p&gt;

&lt;p&gt;Once I reached universal design for learning, which was so different from anything I've learned during work, I hit my first stumbling block in terms of retaining information. I would read the same sentence over and over but it would not sink in. And the terminology for the guidelines seemed bizarre. The description and the guidelines just didn't seem to tie together; I could only imagine how difficult this topic is for people who can't take this test in their native language. When I got to accessibility laws, it became too much — just so much diverse information I couldn't remember all of it after re-reading it multiple times.&lt;/p&gt;

&lt;h3&gt;
  
  
  Going Old School &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;People online mentioned using flashcards to study and once I only had two weeks until my test date, I decided to make an account on Brainscape where there were already a few sets dedicated to CPACC. At this point I knew that reading the material over and over was not going to help me. I tried a few of the CPACC flashcard sets on Brainscape but none of the answers satisfactorily matched my notes so I basically took one already built CPACC class and slowly replaced every single answer card, deleted many cards, and added my own. You probably would be better off just creating your own set of cards from scratch.&lt;/p&gt;

&lt;p&gt;I hadn't used flashcards since high school when I had to write them out by hand, and I really enjoyed the paced repetition on Brainscape that can only happen because it's digital. For every card, you rank on a confidence scale of 1-5 how well you knew the answer. The less confident you are on a card, the more often that card will show up. But the app also doesn't just keep throwing new cards at you; you have to reach a certain confidence level before it starts slowly testing new cards you haven't studied yet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Slow and Steady &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;I organized my cards into sections based on the Deque course, and I would re-read my notes on a section, then do flashcards pertaining only to that section for a day. The next day I would read a new section, then do the flashcards on the previous section until I surpassed a certain percentage, then do flashcards on the section I just read. Slowly but surely I increased my confidence levels. Some of the more comprehensive sections I would revisit over and over but still continue my reading on new sections. For instance, disabilities, universal design for learning, and laws all stayed around 40% for days while other sections quickly increased to 70-80%. I opted to do this method because I didn't want to just know the subject well enough to pass a multiple choice test, I wanted to be able to rattle off as much as I could about a specific topic as if I needed to explain it to someone.&lt;/p&gt;

&lt;h3&gt;
  
  
  An Unexpected but Relevant Roadblock &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;I made a goal to hit 80% in Brainscape by the Saturday before my test. Since level 5 is for cards that you feel you'll know "forever," it's unlikely you'll hit 100%. I then was hoping to cycle through all the cards in the final 3 days before the test. On Saturday however, my mom fell and fractured her wrist, and I had to spend the next 3 days watching her like a hawk, driving her to multiple doctors, cutting her food for her, helping her to shower, and doing other things she couldn't do by herself. &lt;/p&gt;

&lt;p&gt;On the one hand, watching all the limitations she encountered without being able to use her dominant hand made me see directly how much daily life is impacted by disabilities. On the other hand I started to panic at this point, wondering if I should cancel my test because the scheduled studying I had planned to do the final 3 days was out the window. But the test fee was not refundable and I had already put in so much effort that I decided to proceed. I studied wherever I could. I brought my iPad to my mom's doctors' appointments so I could study in the waiting room. I studied at night after she went to bed. By the time of test day I had reached 97.6%. I almost cried with relief that final night.&lt;/p&gt;

&lt;h2&gt;
  
  
  Taking the Test &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Although you can take the exam at home from your own computer, based on Reddit threads most people recommended taking it in-person at an exam center, with the main reason being that the online proctors could be especially strict, and if something happens where the exam becomes nullified (bad internet connection, loud noises, etc.), it's on you to argue. Whereas at Pearson in-person they're responsible for making sure the exam runs correctly and are obligated to fix problems. After taking the exam at Pearson, I can confirm that it was a nice quiet environment for concentrating.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Application Process &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The process from registering with IAAP to scheduling the test is actually much more manual than I thought it would be, and some of the steps do take time, so keep that in mind:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Register with IAAP and submit an application for the exam you want to take. According to the web site, approval can take up to 5 business days but mine was approved by the next day via email. I'm assuming this was quicker because the requirements for CPACC are lenient compared to WAS.&lt;/li&gt;
&lt;li&gt;Once approved, submit payment for the exam online at IAAP.&lt;/li&gt;
&lt;li&gt;Once paid, wait for the "Authorization to Test" email from Pearson VUE. You cannot schedule an exam until you are authorized. This took 5 days (including the weekend) for me to receive the email.&lt;/li&gt;
&lt;li&gt;Create an account and schedule your exam on the Pearson VUE site.&lt;/li&gt;
&lt;li&gt;Take the exam.&lt;/li&gt;
&lt;li&gt;Wait 4-6 weeks after the exam close date for results.&lt;/li&gt;
&lt;li&gt;If you passed, wait another week for your Credly badge and IAAP documents.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Scheduling &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The Pearson scheduling experience was terrible if you signed up later like I did. Be aware that because there are so many different tests administered by Pearson, people may have scheduled exams months in advance, and when you take the test it’s this mixture of people in the room with you. Because I scheduled this exam later in the schedule, most days weren’t available at all until one to two weeks before at four of the test centers near my house (probably because people were rescheduling their exams), and each time you reschedule costs an additional $50. I begrudgingly paid the reschedule fee to get my ideal date and time which luckily opened up 9 days before. I recommend registering earlier to have more openings for the test.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Day &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Check-in for the test was very smooth. I was actually planning to do an additional run through of my flashcards in the waiting room but the employee waved me in since the policy seemed to be to let people into the room on a rolling basis as other people finished. I had to turn off my phone in front of them, show my ID, scan both my palms a couple of times each, take a photograph, and then store items in my locker. At the testing station they provided me with a laminated scratchpad for notes, and noise-canceling headphones were available at each desk.&lt;/p&gt;

&lt;p&gt;The computer had nice options for the interface. You could change the color scheme and had 10+ options at any point (which is very accessible). I tried to do white on black text but then the highlighting didn't look clear enough to me. You could use strikethrough on text on the answer options, although depending how you clicked, you could wind up accidentally selecting an answer as well. There was also an option to write feedback comments on every question, which I did on several; however be aware this does take away from your exam time. You could flag any question you wanted to return to, which was useful when using the navigation button, or at the end when you review, as it shows you a list of all questions with statuses on completion and on flagging.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Exam &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;I did a first pass through the test which took 70 minutes. I flagged 15-20 questions, but I decided to also double-check and re-read every single question and this took up the rest of the two hours. I probably could have spent another 15 minutes. There were at least 5 questions that referenced things I did not encounter at all in my studying, and another 10 questions that I could have flipped a coin between two choices. Maybe I felt sure about 30 questions and "pretty sure" about 20 more. Overall I felt good... but also would not have been entirely shocked if I didn't make the cutoff. I can understand why many of the people writing about their experiences say they didn't feel particularly confident afterwards. There were a few questions that felt not exactly random, but you would have had to go &lt;strong&gt;DEEP&lt;/strong&gt; into material to know the answer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Total Time Spent Studying &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The IAAP site recommends that people spend anywhere from 30-80 hours in preparation for this test. Because of the statistics from the Brainscape site, I know that I spent 29 hours on flashcard studying alone. This did not include the time I spent creating the flashcards, which probably took another 10 hours. I probably spent at least another 20-30 hours on the Deque course and on writing out my notes. So my total time was definitely on the higher end of the scale. I also consulted other sites and blogs which are listed at the end of this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exam Criticisms &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Wide Range of Topics and Specificity &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Having read through both the BOK (but not every externally-linked reading) and having completed Deque's course, those covered ~90% of the material on the test. Maybe with luck you might get a test that matches everything exactly. Most likely if you want full knowledge, you'll need to read through all the supplemental materials on both, however the net is especially wide. It was pretty demoralizing to click on an external link that led to 20 subpages. On the exam there were references to laws or medical conditions that felt &lt;strong&gt;too&lt;/strong&gt; specific and not in the spirit of what this overall certification is trying to accomplish. There was a question on the test about the global numbers of a specific disability. I happened to know the answer, but only because when I read it while studying I thought, “This is such a random specific statistic that there’s no way they’re going to ask this on the exam.” Well they did.&lt;/p&gt;

&lt;p&gt;There were also a few questions on the exam regarding a specific law which I had never heard of. I found this surprising because I made a huge effort to memorize all the accessibility laws that I could (and for many countries outside the US). When I got home and looked it up I realized I did study that law and knew it well, however I only knew it by its official, technical name, not the friendlier "common" term for it. I don't recall in any of the questions where it had the technical name in parentheses, so my thought at the time was, "How is there &lt;strong&gt;another&lt;/strong&gt; law that seems to overlap with existing laws?" I felt this was another example of the test questions relying too much on unguided direct memorization.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not Following their Own Recommendations &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The biggest irony was the format of the test itself. Universal design for learning emphasizes that using one method to demonstrate knowledge proficiency is not enough (the principle of multiple means of action and expression) because some learners may have barriers with certain methods, and others may just need to express themselves in different ways... and yet this test is offered in one format of multiple choice answers. In the Deque course, they used multiple choice tests as a specific example of a format that may cause issues for certain learners. I understand the added complexity of administering multiple formats for a global exam, but it was ironic nonetheless.&lt;/p&gt;

&lt;h2&gt;
  
  
  Post-Exam Reflection &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Lack of Confidence &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;I researched people's experiences with the test online before I signed up, and a lot of people mentioned that they were uncertain on how well they did afterwards. I felt exactly the same way, which is an odd feeling about a multiple choice test. There were enough questions that I either had no idea about because I didn't know the topic at all, and other questions that felt specifically tricky between two answers. I was expecting to pass but also would not have been surprised if I barely made the cutoff.&lt;/p&gt;

&lt;p&gt;To be clear, I felt extremely confident in my knowledge about all of the topics, but not about how I did on the test itself. I don't think I've ever taken a test where I felt that much uncertainty afterwards, which was not a great feeling. Some of this may also have been due to me knowing that IAAP uses a modified Angoff scoring method, which requires subject-matter experts to review each question. So while taking the exam I was unintentionally also thinking about whether each question seemed "easy" or "hard."&lt;/p&gt;

&lt;h3&gt;
  
  
  The Wait &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The results can take 4-6 weeks from the end of the exam period, which lasts about a month. I took my exam the second to last day, and even then the wait felt like forever. I would watch jobs get posted wanting the CPACC certification and debated whether to wait to apply after I got the certification (if I even got it), or to apply as soon as possible. I also wanted to start studying for the WAS certification, but not if I failed the CPACC. While it felt frustrating to wait for all the reviewing, I told myself it's better than getting a strict cutoff immediately after finishing the test.&lt;/p&gt;

&lt;p&gt;Finally, 5 weeks and 5 days after the exam period ended, I found out that I had passed with "Above Standard" in each domain, with a scaled score of 724/800. Being laid off this year and struggling in the job search has been very demoralizing every day, but the day I found out I passed, I felt a joy I hadn't felt in months. Knowledge in web development can feel nebulous, and there are points where you can feel you know a lot until you learn more and realize all of what you don’t know. But here was something that I put the effort to learn and felt validated by the results.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lingering Questions &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;There are still scenarios regarding web accessibility or universal design that I still don't know which concept fits the most. For example on a web site, let's say you have a word game where a banner will display only if you lose or win the game. Following the rules of interaction, you will need to create an &lt;code&gt;aria-live&lt;/code&gt; region for screen readers so that users will know without being able to look at the content that they won or lost. But which of the web accessibility principles (perceivable, operable, understandable, robust) does this apply to?&lt;/p&gt;

&lt;p&gt;Deque had this type of alert listed as both perceivable (able to perceive through sight, sound, or touch) and robust (compatibility including with assistive technologies). Is it both or is one case stronger than the other? I could also argue this would be under understandable because if you kept trying to play the game even after the game is over, you are going to be confused. This was frustrating because as a developer, I know why this solution needs to be implemented, but when you're limited to a multiple choice test you have to know exactly which principle fit the best.&lt;/p&gt;

&lt;h3&gt;
  
  
  One Tool &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;I had to remind myself that while this was an accessibility certification, like every other certification out there, it's only as good as what you make of it. There are plenty of people who know accessibility without being certified, but for me I liked having some structure in which to guide my learning. And as I had mentioned earlier, I wanted some official credibility if I have to fight to keep something accessible in an environment that doesn't proactively support it.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Needed Boost &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;I intend to keep accessibility as a priority in my front-end career whether or not it’s a specific requirement of my job, and being a CPACC is just one part of it. While I had qualms with some of the questions on the CPACC exam, and there are certain details I won’t need in my career, I’m still glad that I learned this information and now understand the larger context that accessibility plays in this world. And I'm glad this certification exists to motivate people like myself to learn more. I plan to keep learning accessibility from online courses and conferences, and also plan on taking the WAS exam so I can become in combination with CPACC a Certified Professional in Web Accessibility (CPWA).&lt;/p&gt;

&lt;h3&gt;
  
  
  Recommendations in Hindsight &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Online sites that have example multiple choice tests are useful, but I would make sure that you can answer the questions open-ended just because of how varied and encompassing the subject is. I did maybe 5 runs of multiple choice tests but spent the bulk of my time with flashcards&lt;/li&gt;
&lt;li&gt;Deque University only allows one active subscription at a time. If you are considering taking both the CPACC and WAS, then I would pay for the combined course. I only signed up for the CPACC course and had to contact customer service in order to switch over to the WAS course and wound up paying more than if I had just signed up for the combined CPACC/WAS to begin with.&lt;/li&gt;
&lt;li&gt;If you are reading and re-reading the same content and it is not sinking in for you, consider watching some YouTube videos for a different way for the information to be presented. After being stuck on universal design for learning for days, I listened to a portion of a YouTube video and this cemented the basics for me immediately — all because the information was presented in an auditory manner.&lt;/li&gt;
&lt;li&gt;Apply and register for the test early so that you will have more options for scheduling in-person at Pearson.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Online Resources &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Deque University: &lt;a href="https://dequeuniversity.com/online-courses/" rel="noopener noreferrer"&gt;https://dequeuniversity.com/online-courses/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;IAAP Book of Knowledge (Oct 2023): &lt;a href="https://www.accessibilityassociation.org/sfsites/c/resource/CPACCBoK" rel="noopener noreferrer"&gt;https://www.accessibilityassociation.org/sfsites/c/resource/CPACCBoK&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;CPACC preparation and blog: &lt;a href="https://chelsea11y.com/cpacc/index.html" rel="noopener noreferrer"&gt;https://chelsea11y.com/cpacc/index.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Practice multiple choice tests: &lt;a href="https://a11yconsultant.com/" rel="noopener noreferrer"&gt;https://a11yconsultant.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Brainscape Flashcards: &lt;a href="https://www.brainscape.com/" rel="noopener noreferrer"&gt;https://www.brainscape.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;CPACC subject overview video: &lt;a href="https://youtu.be/a01vcZMTJqU?si=HA4B6_Xo2KSqk4mK" rel="noopener noreferrer"&gt;https://youtu.be/a01vcZMTJqU?si=HA4B6_Xo2KSqk4mK&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>a11y</category>
      <category>webdev</category>
      <category>html</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Use the new ARIA landmark &lt;search&gt; for search forms and filters</title>
      <dc:creator>Diana Le</dc:creator>
      <pubDate>Tue, 29 Apr 2025 16:44:54 +0000</pubDate>
      <link>https://dev.to/dianale/use-the-new-aria-landmark-for-search-forms-and-filters-1288</link>
      <guid>https://dev.to/dianale/use-the-new-aria-landmark-for-search-forms-and-filters-1288</guid>
      <description>&lt;p&gt;ARIA landmark roles are sections of a web site that are so important to the page that they warrant their own dynamically generated navigation in assistive technologies. There are eight total landmarks, but there were previously only seven semantic HTML tags to correspond to those landmarks. Now finally the missing semantic tag &lt;code&gt;&amp;lt;search&amp;gt;&lt;/code&gt; is available in browsers and is compatible under Baseline 2023 Newly Available.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use
&lt;/h2&gt;

&lt;p&gt;Wrap the &lt;code&gt;&amp;lt;search&amp;gt;&lt;/code&gt; tag around your search form (and any relevant filters or quick search results). The full search results should not be within the &lt;code&gt;&amp;lt;search&amp;gt;&lt;/code&gt; but rather within the main body of the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;search&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;form&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"search-input"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Search&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"search-input"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"search-input"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/search&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- Search Results Below --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Older method using the attribute &lt;code&gt;role="search"&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Before the &lt;code&gt;&amp;lt;search&amp;gt;&lt;/code&gt; element, you could use the "search" role on a form to designate it as a landmark:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"search"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"search-input"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Search&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"search-input"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"search-input"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'll admit I wasn't aware I was missing &lt;code&gt;role="search"&lt;/code&gt; at first until I had built many search forms, but using that or the newer &lt;code&gt;&amp;lt;search&amp;gt;&lt;/code&gt; element is a very easy change to implement.&lt;/p&gt;

&lt;h2&gt;
  
  
  ARIA landmarks and corresponding HTML tags
&lt;/h2&gt;

&lt;p&gt;Here's the complete list of landmarks and their respective tags/elements. Be sure if you use the &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; tag that you use an ARIA label with it, such as tying it to the ID of the highest heading within.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ARIA landmark&lt;/th&gt;
&lt;th&gt;Corresponding HTML&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Main&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;main&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Banner&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;header&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Navigation&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Contentinfo&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;footer&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complementary&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;aside&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Region&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;&amp;lt;section aria-labelledby=""&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;section aria-label=""&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Form&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;form aria-label=""&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;search&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  For more information
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://alvaromontoro.com/blog/68033/new-html-element-search" rel="noopener noreferrer"&gt;https://alvaromontoro.com/blog/68033/new-html-element-search&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.scottohara.me/blog/2023/03/24/search-element.html" rel="noopener noreferrer"&gt;https://www.scottohara.me/blog/2023/03/24/search-element.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>html</category>
      <category>a11y</category>
      <category>frontend</category>
    </item>
    <item>
      <title>CSS Layouts: Get Started with Container Queries</title>
      <dc:creator>Diana Le</dc:creator>
      <pubDate>Wed, 25 Oct 2023 15:00:00 +0000</pubDate>
      <link>https://dev.to/dianale/css-layouts-get-started-with-container-queries-3dnf</link>
      <guid>https://dev.to/dianale/css-layouts-get-started-with-container-queries-3dnf</guid>
      <description>&lt;p&gt;Welcome to another year of the State of CSS. Like for last year's &lt;a href="https://dev.to/dianale/series/20455"&gt;State of CSS 2022&lt;/a&gt;, I will be creating a series of examples and tutorials mentioned in the survey so we can all learn and keep up with the latest features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Container Queries
&lt;/h2&gt;

&lt;p&gt;Let's kick off this series with an introduction to container queries - a new alternative to media queries. I heard about container queries a few years ago, and went through some articles and video tutorials, but for some reason with the examples I reviewed, I just couldn't &lt;strong&gt;get it&lt;/strong&gt;. Everyone was saying how this would dramatically change CSS, but it was hard for me to grasp by how much. After finally understanding the basics I realized that &lt;strong&gt;container queries are super-powered media queries&lt;/strong&gt;. (But be aware they do not replace all media queries).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When Media Queries Become Inefficient&lt;/li&gt;
&lt;li&gt;Enter the Container&lt;/li&gt;
&lt;li&gt;
How to Set Up Container Queries

&lt;ul&gt;
&lt;li&gt;Determine the container&lt;/li&gt;
&lt;li&gt;Set the CSS Container Rules&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;When to Keep Using Media Queries&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  When Media Queries Become Inefficient &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This year I've been working more with components, and when I was working on a project with a permanent sidebar and needed to style the content within the remaining layout portion, I realized this would finally be the opportunity to use container queries. A media query would not work well unless I always factored in the size of the sidebar, which was not going to be efficient.&lt;/p&gt;

&lt;p&gt;Why doesn't this work well with media queries? Imagine that you want to display cards, and for screens 1200 pixels and above, you would like to display a single row of 3 cards: &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1200px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.cards-wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For a layout that is full-width, this works fine with media queries because the width of the browser is the same as the width of the container:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ufa1w1jn772fodlyohf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ufa1w1jn772fodlyohf.png" alt="Row of 3 cards"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What if the layout has a left sidebar? The browser width is still 1200 pixels but the actual container that the cards are displayed in is now only about 800 pixels. But based on the same media query, the cards would still display a single row of 3 cards:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqenzj69yqklxbgc1v7u1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqenzj69yqklxbgc1v7u1.png" alt="Layout featuring a left sidebar and 3 cards on the right"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you wanted to change the number of cards per row to 2 instead of 3 on this specific layout, you'd have to either add a class to this specific instance of cards or use a compound selector:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1200px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.two-column-right&lt;/span&gt; &lt;span class="nc"&gt;.cards-wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This will work but makes the code not as clean because you have to consider all locations where these specific cards are used and adjust all places if the styling changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enter the Container &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;What if we could style our cards based on the parent container so that regardless of what the layout is, the cards would be styled correctly? &lt;strong&gt;That is the power of container queries&lt;/strong&gt;. We could style those same cards for the exact dimensions of the container, and then afterwards we wouldn't have to worry about where the card component is used because we've already accounted for the styling. We basically have a component with built-in styles that can slot anywhere.&lt;/p&gt;

&lt;p&gt;Whether it's dropped into a full-width layout or into a sidebar, once we have the CSS rules in place, we don't have to worry about creating custom rules for a specific layout. We can cover all the scenarios in the same set of rules; &lt;strong&gt;the styles are tied to that container component&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Here's an example of the same card component being used 3 different times on a page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj51aqoeo5vspeid017ru.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj51aqoeo5vspeid017ru.png" alt="Codepen screenshot showing a card component being used 3 times on the same page in different sections"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that the cards are styled differently between: the section "Container Queries", the "Sidebar", and at the bottom of the page.&lt;/p&gt;

&lt;p&gt;You get the best of both worlds with container queries. If your container is always the same width as the browser, then it still works. Container queries still give you the benefits of media queries but with even more functionality.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Set up Container Queries &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Let's walk through the previous example screenshot taken from the following Codepen:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/pursuitofleisure/embed/GRPvYyb?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Determine the container &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;This can be confusing at first. You need to set the container on the &lt;strong&gt;parent&lt;/strong&gt; of the element that you later want to style with container queries. For example, the structure of the cards is:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="c"&gt;&amp;lt;!-- Card wrapper --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- Individual cards --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ...
  &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ...
  &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;card-wrapper&lt;/code&gt; class is where the grid columns are set:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="nc"&gt;.card-wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You might assume that since this &lt;code&gt;.card-wrapper&lt;/code&gt; is the container for the individual cards, that you would set the container property here, but that would be incorrect. You need to create &lt;strong&gt;another&lt;/strong&gt; wrapper as the parent, in this example &lt;code&gt;.card-wrapper-container&lt;/code&gt;, because we want to style &lt;code&gt;.card-wrapper&lt;/code&gt; (and how many cards to display per row) based on the width of &lt;code&gt;.card-wrapper-container&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="c"&gt;&amp;lt;!-- New wrapper --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-wrapper-container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      ...
    &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h4&gt;
  
  
  2. Set the CSS Container Rules &lt;a&gt;&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Now that we know what our container is, we need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create the container by setting the &lt;code&gt;container-type&lt;/code&gt; (use &lt;code&gt;inline-size&lt;/code&gt; as the value for now since this probably covers most of the use cases)&lt;/li&gt;
&lt;li&gt;Define the container and create styling rules based on the width of the container. This logic is incredibly similar to media queries:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="c"&gt;/* Create the container / set the containment context */&lt;/span&gt;
&lt;span class="nc"&gt;.card-wrapper-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;container-type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Define the container query using @container */&lt;/span&gt;
&lt;span class="c"&gt;/* The rule below says: find the closest ancestor with a
 containment context 
- in this case "card-wrapper-container" -
and when the width is 560 pixels and above, 
set the grid columns to 2 */&lt;/span&gt;
&lt;span class="k"&gt;@container&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;560px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.card-wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Those are the minimum CSS rules you need for setting up container queries. You can style anything within the container such as setting font sizes:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;

&lt;span class="c"&gt;/* Change the grid columns to 3 per row
once the width of the container is 768px
and adjust the font size of the card title */&lt;/span&gt;
&lt;span class="k"&gt;@container&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;768px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.card-wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nc"&gt;.card__title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And voilà, you have set up container queries and changed the grid columns and font sizes within. You can keep adding more breakpoints and then place the &lt;code&gt;.card-wrapper-container&lt;/code&gt; HTML anywhere onto a page (and in multiple locations), and it will always style based on the width of the container. 🥳&lt;/p&gt;

&lt;h3&gt;
  
  
  When to Keep Using Media Queries &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Media queries are still useful for setting the overall layout of the page, and needed for accessibility or browser preferences like &lt;code&gt;prefers-reduced-motion&lt;/code&gt; or &lt;code&gt;prefers-color-scheme&lt;/code&gt;. If you need to support older browsers, then media queries are also more browser-compatible. &lt;strong&gt;But container queries can be a powerful, more efficient replacement for media queries when you want to break down your site into reusable components&lt;/strong&gt;. Hopefully this article gives you some ideas that you can use as you get started with this new feature.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Are you an HTML expert? Find out with the new State of HTML 2023 survey</title>
      <dc:creator>Diana Le</dc:creator>
      <pubDate>Thu, 28 Sep 2023 20:00:55 +0000</pubDate>
      <link>https://dev.to/dianale/are-you-an-html-expert-find-out-with-the-new-state-of-html-2023-survey-58g4</link>
      <guid>https://dev.to/dianale/are-you-an-html-expert-find-out-with-the-new-state-of-html-2023-survey-58g4</guid>
      <description>&lt;p&gt;If you're familiar with the State of JavaScript or State of CSS surveys, there is now a brand new &lt;a href="https://stateofhtml.com/en-US" rel="noopener noreferrer"&gt;State of HTML survey&lt;/a&gt; that is still open.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How did you do? Is HTML already one of the languages you continuously keep up with?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This was definitely an (expected) humbling experience for me after 10 years of web development:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6aoc26qzae8lpvj93o1c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6aoc26qzae8lpvj93o1c.png" alt="State of HTML survey results: Of the 131 features mentioned in the survey, you have used 37 and heard of 6 more, which puts you in the top 47% of all respondents"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I feel like HTML can get glossed over in web development since it's not a &lt;em&gt;programming&lt;/em&gt; language and therefore assumed you can just learn the tags at the beginning and never worry about it again. So many online courses have you "learn HTML in one day." Granted, you can definitely get started after a day but there is so much to continuously learn; I still sometimes struggle with selecting the proper tag to represent specific content for semantics and for accessibility. (Don't even get me started on form tags).&lt;/p&gt;

&lt;p&gt;And based on this survey, there are so many new tags and APIs that continue to come out. There were so many things I hadn't even heard of. A lot may not be applicable to what you do day-to-day, but it's definitely a reminder to research things even if you think you already know.&lt;/p&gt;

</description>
      <category>html</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>discuss</category>
    </item>
    <item>
      <title>CSS Layouts: Maintain Element Proportions with aspect-ratio</title>
      <dc:creator>Diana Le</dc:creator>
      <pubDate>Tue, 01 Aug 2023 16:00:00 +0000</pubDate>
      <link>https://dev.to/dianale/css-layouts-maintain-element-proportions-with-aspect-ratio-k32</link>
      <guid>https://dev.to/dianale/css-layouts-maintain-element-proportions-with-aspect-ratio-k32</guid>
      <description>&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Banner Example&lt;/li&gt;
&lt;li&gt;iframe Example&lt;/li&gt;
&lt;li&gt;Images&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;There are times you'll want to keep an object on a web page the same proportion on all devices and screens, and this is possible now with &lt;code&gt;aspect-ratio&lt;/code&gt;. This property is useful for elements that do not have inherit proportions, such as &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I've mostly used &lt;code&gt;aspect-ratio&lt;/code&gt; for decorative or elements with minimal text. Be careful about using it for items with long passages of text, because you have to consider what happens when text overflows. And of course if you're trying to fit it within a layout to align with other components, then you're better off using properties like grid or flex.&lt;/p&gt;

&lt;h2&gt;
  
  
  Banner Example &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Here's a simple banner example:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/pursuitofleisure/embed/poQZyWJ?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- HTML --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"banner"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Welcome to the Movies&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"square-one"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"square-two"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The banner uses &lt;code&gt;aspect-ratio&lt;/code&gt; to keep it the same proportion (21:9) on every screen size. The aspect-ratio uses &lt;code&gt;width / height&lt;/code&gt; as values (height default value is &lt;code&gt;1&lt;/code&gt; if not declared). The banner has two decorative elements that also utilize &lt;code&gt;aspect-ratio&lt;/code&gt; to keep the shapes and sizings consistent. These items don't necessarily have to keep the same proportions (they may change for artistic reasons depending on the viewport), but it's easy to do so now with &lt;code&gt;aspect-ratio&lt;/code&gt; and not need to set explicit heights per viewport.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* CSS */&lt;/span&gt;
&lt;span class="nc"&gt;.banner&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1000px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1em&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;aspect-ratio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;21&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Setting aspect-ratio */&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#00171f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.square-one&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;aspect-ratio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Setting aspect-ratio */&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#007ea7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.square-two&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;aspect-ratio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Setting aspect-ratio */&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#003459&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The two "squares" are decorative background shapes that keep both a consistent percentage width of the banner, and a consistent proportion. Resize the Codepen window and you can see that the banner and the decorative elements inside maintain the same proportions on all screens.&lt;/p&gt;

&lt;p&gt;You can see how simple it is to just set the &lt;code&gt;aspect-ratio&lt;/code&gt; value once and not have to worry about it. In the past I've had to use multiple media queries for banners with background images because there is no inherent size with them, and relying on changing the vertical padding or font sizes to keep the same ratio was tedious and never an exact match.&lt;/p&gt;

&lt;h2&gt;
  
  
  iframe Example &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;For an &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; such as an embedded YouTube video, making it responsive while keeping the original proportion is much easier than it used to be.&lt;/p&gt;

&lt;p&gt;Clicking on the YouTube "share" button will give you a code snippet like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- HTML --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;iframe&lt;/span&gt; 
    &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"560"&lt;/span&gt; 
    &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"315"&lt;/span&gt; 
    &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;...&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/iframe&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use the width and height properties as the &lt;code&gt;aspect-ratio&lt;/code&gt; and this will allow the video to be responsive keeping its original proportion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* CSS */&lt;/span&gt;
&lt;span class="nt"&gt;iframe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;aspect-ratio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;560&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;315&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* width and height of video */&lt;/span&gt;
  &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! Previously you had to &lt;code&gt;position: absolute&lt;/code&gt; the &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; in a container, and set its &lt;code&gt;padding-bottom: 56.25%&lt;/code&gt; which is the video height divided by the width (315 / 560). I used to just copy this block over and over without thinking exactly what it was doing just because I knew it would work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Old CSS method */&lt;/span&gt;
&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;56.25%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;iframe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code will still work, and might still be needed if you're using a non-evergreen browser, but otherwise &lt;code&gt;aspect-ratio&lt;/code&gt; is &lt;a href="https://caniuse.com/?search=aspect-ratio" rel="noopener noreferrer"&gt;highly supported now&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you only style the &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; without setting &lt;code&gt;aspect-ratio&lt;/code&gt;, or without using the old container method, and you only set the &lt;code&gt;width&lt;/code&gt; or &lt;code&gt;max-width&lt;/code&gt; property on the &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt;, you'll wind up with a more square-ish shape as the screen gets smaller because the height will not adjust automatically. The video will still play in the correct aspect-ratio, but you will get really thick letter-boxing on the top and bottom which will make it not look like a video while paused.&lt;/p&gt;

&lt;h2&gt;
  
  
  Images &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;For images, the proportion is inherently built in with the &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; attributes (which you should always specify), so you don't need &lt;code&gt;aspect-ratio&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; 
  &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./image.jpg"&lt;/span&gt; 
  &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; 
  &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"300"&lt;/span&gt; 
  &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"200"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; are treated like an aspect-ratio that will keep the image the same proportion of 300 pixels wide by 200 pixels tall no matter how big or small the image gets. This also helps the browser determine how much space is needed before the image fully loads so you reduce any jarring content shifting AKA "cumulative layout shift" that affects site speed. So you &lt;em&gt;probably&lt;/em&gt; won't need &lt;code&gt;aspect-ratio&lt;/code&gt; for images, however it &lt;em&gt;can&lt;/em&gt; be used in combination with &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; that you can read about &lt;a href="https://css-tricks.com/almanac/properties/a/aspect-ratio/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>career</category>
      <category>productivity</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>CSS Typography: Create exact heights with line-clamp</title>
      <dc:creator>Diana Le</dc:creator>
      <pubDate>Wed, 26 Apr 2023 16:00:00 +0000</pubDate>
      <link>https://dev.to/dianale/css-typography-create-exact-heights-with-line-clamp-40e3</link>
      <guid>https://dev.to/dianale/css-typography-create-exact-heights-with-line-clamp-40e3</guid>
      <description>&lt;p&gt;I've built dozens of web sites, and by far one of the most common components that required multiple edits was the card component. The design was always fine due to standardized placeholder content, but when the actual content came in, the cards would wind up looking like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fya57lcc585a2awywcank.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fya57lcc585a2awywcank.png" alt="Cards of unequal heights due to varying paragraph descriptions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you were a developer during the era of CSS float layouts, this was incredibly annoying to deal with. Cards would stack under shorter cards instead of filling out the row. Thankfully with flex/grid, we don't have that problem anymore, but even now within the card itself, you can still get these alignment issues if you don't prepare for this beforehand. It's a good idea to be proactive and to account for these types of scenarios in order to build more resilient sites.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the Cards "Even"
&lt;/h2&gt;

&lt;p&gt;Make sure you confirm with someone on your project on what this means. Generally I'm not a fan of hiding content just to make something prettier; if the content was intentional, then value is lost by hiding it or cutting it off. The first solution would be to review and see whether the content can be standardized so we don't have such huge differences. Once you have that answer, then proceed with either of the following options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Line-Clamp to Hide Text&lt;/li&gt;
&lt;li&gt;Use Flex-Grow to Stretch Cards&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Demo Showing both Line-Clamp and Flex-Grow
&lt;/h2&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/pursuitofleisure/embed/OJBJNQr?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Line-Clamp for Exact Heights &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Let's say the stakeholder is fine with only showing the first X lines in the card description. This is where line-clamp makes things incredibly easy. Here is the HTML structure of the card:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Title of Card&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Lorem ipsum dolor sit amet consectetur adipiscing elit dis egestas, sem neque integer potenti venenatis vulputate varius donec. Volutpat mus eget suspendisse sollicitudin urna blandit in bibendum dui, class porta rutrum dictum facilisi facilisis mollis natoque elementum, sapien sed quisque adipiscing fames cras est augue. Luctus class rhoncus consequat etiam inceptos volutpat himenaeos quisque aptent per, parturient habitant faucibus aliquet hac torquent tempus cursus senectus, elementum vulputate magna taciti hendrerit erat sodales dapibus blandit.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Learn More&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://picsum.photos/300/100"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag is what we need to "clamp" to make it consistent across all cards. This is how to cut off the text after 3 lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;-webkit-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;-webkit-box-orient&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;vertical&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;-webkit-line-clamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Adjust the number of lines here */&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;But this is using &lt;code&gt;webkit&lt;/code&gt; properties. Is it compatible across all browsers?&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Yep, &lt;a href="https://caniuse.com/?search=webkit-line-clamp" rel="noopener noreferrer"&gt;it is compatible&lt;/a&gt; enough (sorry, Internet Explorer). Even &lt;a href="https://tailwindcss.com/blog/tailwindcss-v3-3#line-clamp-out-of-the-box" rel="noopener noreferrer"&gt;Tailwind has implemented it&lt;/a&gt; by default now. &lt;/p&gt;

&lt;p&gt;You MUST use the webkit properties to get this working. Ellipses will always show by default on the last line if the content is longer than the &lt;code&gt;-webkit-line-clamp&lt;/code&gt; value. If you don't use &lt;code&gt;overflow: hidden&lt;/code&gt;, the ellipses still display, but the content still shows underneath. So at minimum, you will need all 4 rules.&lt;/p&gt;

&lt;p&gt;This used to be much more difficult with CSS, and sometimes you'd have to resort to JavaScript. But now we have fully working CSS, if a little weird that it still relies on browser prefixes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the Cards Equal by using Flex-Grow &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Let's say the stakeholder wants all the content in the card to be visible. This means we'll have to adjust the height of the entire card. This is what I would normally do to account for possible varying content. It's easy to forget to do, especially if you're looking at a design where all the text is the same length. Even as I'm writing this post, I realize that the heading &lt;code&gt;&amp;lt;h3&amp;gt;&lt;/code&gt; is something you'd want to apply the same changes to as well.&lt;/p&gt;

&lt;p&gt;Here's our card HTML again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Title of Card&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Lorem ipsum dolor sit amet consectetur adipiscing elit dis egestas, sem neque integer potenti venenatis vulputate varius donec. Volutpat mus eget suspendisse sollicitudin urna blandit in bibendum dui, class porta rutrum dictum facilisi facilisis mollis natoque elementum, sapien sed quisque adipiscing fames cras est augue. Luctus class rhoncus consequat etiam inceptos volutpat himenaeos quisque aptent per, parturient habitant faucibus aliquet hac torquent tempus cursus senectus, elementum vulputate magna taciti hendrerit erat sodales dapibus blandit.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Learn More&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://picsum.photos/300/100"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to use Flex on the card (which is already put to use by ordering the image at the top of the card). Then we need to tell the &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag to grow if needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;article&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c"&gt;/* could also use flex-grow: 1 */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because the paragraph is now growing, all the "Learn More" buttons will be aligned with each other at the bottom across the entire row. However, if you have multiple rows, while the "Learn More" will always be aligned, the height of the cards between rows will not necessarily match because the height of the &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag can vary. &lt;/p&gt;

&lt;p&gt;Flex is one-dimensional, meaning it will only care about one row or one direction at a time. In this instance, all the cards in the same row (which will change depending on screen size) will be the same height, but flex will not enforce the same height across every row in this section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Line-clamp is a very simple solution to the common problem of uneven heights of content when building web sites. Just make sure that it's not automatically your first solution since it hides content, and know what the other options are as well.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>codepen</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Simplify CSS selectors with :is() and :where()</title>
      <dc:creator>Diana Le</dc:creator>
      <pubDate>Thu, 19 Jan 2023 18:00:00 +0000</pubDate>
      <link>https://dev.to/dianale/simplify-css-selectors-with-is-and-where-i3o</link>
      <guid>https://dev.to/dianale/simplify-css-selectors-with-is-and-where-i3o</guid>
      <description>&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;
How Both :is() and :where() Work

&lt;ul&gt;
&lt;li&gt;How These Help Minimize Errors&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Specificity: How :is() and :where() Differ

&lt;ul&gt;
&lt;li&gt;:where() has Zero Specificity&lt;/li&gt;
&lt;li&gt;:is() Applies the Specificity of the Highest Selector&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The new pseudo-classes &lt;code&gt;:is()&lt;/code&gt; and &lt;code&gt;:where()&lt;/code&gt; help make compound selectors more efficient and less error-prone by allowing you to group and condense selectors, which makes them easier to maintain, but each has its own quirks with how it calculates specificity.&lt;/p&gt;

&lt;p&gt;Keep in mind that while compound selectors in CSS are essential when learning about CSS and how the cascade works, in practice they are somewhat controversial. Sometime during the almost 10 years that I've been a web developer, they became frowned upon because they were difficult to maintain on large projects with multiple developers. Methodologies like BEM became popular in part because they avoided compound selectors entirely (and therefore removed the need to figure out CSS specificity on the fly). These pseudo-classes are still important to learn, however, since compound selectors are vital to CSS, and may also potentially be incorporated in other future CSS functionality, like nesting.&lt;/p&gt;

&lt;p&gt;Let's walk through examples of how both of these pseudo-classes work. If you would like to test the CSS as you read, here is the HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;header&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;About Us&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Meet our Team&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Unordered List item one&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ol&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Ordered List item one&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ol&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/header&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;main&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Web Designer&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;This is our web designer.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;View Bio&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h3&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"heading"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Web Developer&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;This is our web developer.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;View Bio&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;footer&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Unordered List item one&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ol&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Ordered List item one&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ol&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/footer&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How Both :is() and :where() Work &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;With both &lt;code&gt;:is()&lt;/code&gt; and &lt;code&gt;:where()&lt;/code&gt;, you can group any selectors within the parentheses where you want to have the same declarations applied. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For instance&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Becomes&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:where&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pseudo-classes become more powerful once you combine more complex selectors. For example, you can condense the following compound selectors:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nd"&gt;:is&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can even chain them:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="nt"&gt;ol&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;footer&lt;/span&gt; &lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;footer&lt;/span&gt; &lt;span class="nt"&gt;ol&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:where&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;footer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nd"&gt;:where&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;ol&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How These Help Minimize Errors &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;CSS is a declarative language; if the browser runs across a line that it doesn't understand, it skips it and keeps going. If we have the following CSS rule:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blurple&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The color &lt;code&gt;blurple&lt;/code&gt; doesn't exist, and that declaration would be skipped, but then the &lt;code&gt;font-family: sans-serif&lt;/code&gt; would still apply.&lt;/p&gt;

&lt;p&gt;However if you had the following CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nd"&gt;:second-child&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no such thing as a &lt;code&gt;second-child&lt;/code&gt; selector, and this &lt;strong&gt;ENTIRE&lt;/strong&gt; rule would fail silently, meaning neither &lt;code&gt;color&lt;/code&gt; nor &lt;code&gt;font-family&lt;/code&gt; will apply to any selectors even though both declarations are valid. The &lt;code&gt;.card :second-child&lt;/code&gt; selector ruins the entire rule.&lt;/p&gt;

&lt;h4&gt;
  
  
  Forgiving Selectors
&lt;/h4&gt;

&lt;p&gt;Here's where the other benefit to using these new pseudo-classes comes in. Each pseudo-class accepts a "forgiving selector list", which means each &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"parses each selector in the list individually, simply ignoring ones that fail to parse, so the remaining selectors can still be used." - &lt;a href="https://drafts.csswg.org/selectors-4/#typedef-forgiving-selector-list" rel="noopener noreferrer"&gt;CSS Working Group&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you had instead written the previous code with either &lt;code&gt;:is()&lt;/code&gt; or &lt;code&gt;:where()&lt;/code&gt;, you would have a better outcome:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="nd"&gt;:where&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nd"&gt;:second-child&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only the last selector &lt;code&gt;:second-child&lt;/code&gt; fails due to the "forgiving selector list", so both &lt;code&gt;.card h3&lt;/code&gt; and &lt;code&gt;.card p&lt;/code&gt; still get the CSS declarations of &lt;code&gt;color&lt;/code&gt; and &lt;code&gt;font-family&lt;/code&gt; applied.&lt;/p&gt;

&lt;h2&gt;
  
  
  Specificity: How :is() and :where() Differ &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The major difference between &lt;code&gt;:is()&lt;/code&gt; and &lt;code&gt;:where()&lt;/code&gt; is how they handle specificity in regards to the selectors within the parentheses. Specificity determines which rules will get applied to selectors.&lt;/p&gt;

&lt;h3&gt;
  
  
  :where() has 0 Specificity &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Any selectors using &lt;code&gt;:where()&lt;/code&gt; will have 0 specificity. Put very simplistically, HTML tags have a specificity of 1, classes are 10, and IDs are 100. The calculations actually use 3 columns but this is just so you understand that almost all selectors have a specificity greater than 0. Generally you won't need to calculate exact specificity when writing CSS, but you can see that this means that anything inside &lt;code&gt;:where()&lt;/code&gt;, will not apply if that specific selector has already been styled somewhere else beforehand.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* specificity 0-0-1 */&lt;/span&gt;
&lt;span class="nt"&gt;article&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* This rule will not apply 
because it has lower specificity (0) 
than the rule above */&lt;/span&gt;
&lt;span class="nd"&gt;:where&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;article&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes &lt;code&gt;:where()&lt;/code&gt; a good choice for CSS resets or any base styling that may need to be easily overridden later.&lt;/p&gt;

&lt;h3&gt;
  
  
  :is() Applies the Specificity of the Highest Selector &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The pseudo-class &lt;code&gt;:is()&lt;/code&gt; will take the highest specificity of whatever is in your selector list, and then apply that to all the selectors. This means for example that if you group a tag selector with an ID selector, the tag now has the same calculated specificity as the ID. You will not be able to override the styling for the tag afterwards unless you increase the specificity to be at least the same for a CSS ID.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;article&lt;/span&gt; &lt;span class="nd"&gt;:is&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;#heading&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* This rule will not apply
because the ID selector in the previous rule
gives the anchor tag a higher specificity than here */&lt;/span&gt;
&lt;span class="nt"&gt;article&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Let's force the override with the dreaded IMPORTANT  */&lt;/span&gt;
&lt;span class="nt"&gt;article&lt;/span&gt; &lt;span class="nt"&gt;a&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The specificity of &lt;code&gt;is()&lt;/code&gt; makes it hard for me to think of a proper use case for it. If you are not careful with your selectors, such as mixing tags, classes, and IDs together, you will spend more time debugging why certain styles are not applying. If you make sure to &lt;strong&gt;only&lt;/strong&gt; group similar selectors together (all having the same specificity), then this may be useful to use in lieu of the traditional compound selector syntax.&lt;/p&gt;

</description>
      <category>career</category>
      <category>community</category>
      <category>backenddevelopment</category>
      <category>php</category>
    </item>
    <item>
      <title>CSS Selectors: Style lists with the ::marker pseudo-element</title>
      <dc:creator>Diana Le</dc:creator>
      <pubDate>Thu, 29 Dec 2022 18:39:27 +0000</pubDate>
      <link>https://dev.to/dianale/css-selectors-style-lists-with-the-marker-pseudo-element-ee4</link>
      <guid>https://dev.to/dianale/css-selectors-style-lists-with-the-marker-pseudo-element-ee4</guid>
      <description>&lt;p&gt;For HTML lists, there was no straightforward way to style the bullets a different color from the list text until a couple of years ago. If you wanted to change just the marker color, you'd have to generate your own with pseudo-elements. Now with widespread browser support of the &lt;code&gt;::marker&lt;/code&gt; pseudo-element, this can be targeted directly.&lt;/p&gt;

&lt;p&gt;Let's look at the different methods for styling lists, from methods before &lt;code&gt;::marker&lt;/code&gt; was available and how to style with &lt;code&gt;::marker&lt;/code&gt; going forward. Here's a simple grocery list that we will style:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list__apples"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Apples&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list__bananas"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Bananas&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list__avocados"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Avocados&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list__cheese"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Cheese&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"list__bread"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Bread&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/pursuitofleisure/embed/GRGLPYZ?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Before ::marker
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Changing the bullet color using ::before or ::after
&lt;/h3&gt;

&lt;p&gt;In order to change the color of list bullets, we need to generate new bullets using pseudo-elements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0.25rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"\2022"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ec368d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are creating a bullet icon by using the CSS code/unicode "\2022" - which is the code for a filled-in circle. We can set the color and then since the list-item is using flex, we can vertically center the bullet with the text. Before &lt;code&gt;flex&lt;/code&gt; was supported, I used &lt;code&gt;position: absolute&lt;/code&gt;, which was horrible to style and to keep responsive with the font-size. So with &lt;code&gt;flex&lt;/code&gt; being available now, this already makes the old method not as cumbersome as it used to be. The new marker will take into account any left-padding on the list.&lt;/p&gt;

&lt;p&gt;I used to include the following rule to remove the default list styling first. This is accomplished by the following line (if you have any CSS resets in use, this may already be included):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;ul&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;list-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This rule however is actually not needed because with the pseudo-elements, those replace the default style regardless. You may or may not want to add this for standardization purposes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Changing the marker to an image
&lt;/h3&gt;

&lt;p&gt;What about changing the marker to an image instead? This is actually pretty simple. Here I'm setting the marker to the CSS code/unicode for a shopping cart emoji.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;list-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"\1F6D2"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using ::marker
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Changing the color of the list marker
&lt;/h3&gt;

&lt;p&gt;Now that we have access to &lt;code&gt;::marker&lt;/code&gt;, things are much easier. If we want to just change the color of the bullets, then it's just one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="nd"&gt;::marker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ec368d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For changing the bullets to an emoji, we can also use &lt;code&gt;::marker&lt;/code&gt;. This is the same amount of code as the old method, so it's your preference on which to use:&lt;/p&gt;

&lt;h3&gt;
  
  
  Changing the marker to an emoji
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="nd"&gt;::marker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"🍎"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's have fun and have each emoji match its list item:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.list__apples&lt;/span&gt;&lt;span class="nd"&gt;::marker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"🍎"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.list__bananas&lt;/span&gt;&lt;span class="nd"&gt;::marker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"🍌"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.list__avocados&lt;/span&gt;&lt;span class="nd"&gt;::marker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"🥑"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.list__cheese&lt;/span&gt;&lt;span class="nd"&gt;::marker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"🧀"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.list__bread&lt;/span&gt;&lt;span class="nd"&gt;::marker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"🥖"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use the CSS code/unicode value for &lt;code&gt;content&lt;/code&gt; instead of the actual emoji in case emojis cause issues within your editor or compiler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="nd"&gt;::marker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"\1F34E"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;And that's it for styling list markers! Short and simple and one of the really nice things to have compared to the old methods.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>ruby</category>
      <category>rails</category>
      <category>backend</category>
    </item>
    <item>
      <title>CSS Selectors: Introduction to :has()</title>
      <dc:creator>Diana Le</dc:creator>
      <pubDate>Fri, 09 Dec 2022 13:00:00 +0000</pubDate>
      <link>https://dev.to/dianale/css-the-has-selector-styling-navigation-d16</link>
      <guid>https://dev.to/dianale/css-the-has-selector-styling-navigation-d16</guid>
      <description>&lt;p&gt;The functionality of CSS's new &lt;code&gt;:has()&lt;/code&gt; selector has been something that I've wished existed natively ever since I first started learning web development. With &lt;code&gt;:has()&lt;/code&gt;, you are able to style a parent element based on its children, or a previous sibling element based on its subsequent siblings. Before &lt;code&gt;:has()&lt;/code&gt;, you could style an element in CSS if it followed another element, but in order to style a preceding element, you'd have to either flip the order of elements in the HTML, or resort to JavaScript. Now we can use pure CSS to style any element based on its relative selectors.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: At the time of this writing, this feature is supported in Chrome, Edge, and Safari. Firefox requires enabling the &lt;code&gt;layout.css.has-selector.enabled&lt;/code&gt; flag, which I found still didn't give the full functionality.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Let's learn this selector with two simple examples, one utilizing siblings and the other utilizing parents.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Required Form Fields with Matching Labels&lt;/li&gt;
&lt;li&gt;Navigation Menu with Parent Dropdowns&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Required Form Fields with Matching Labels &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;I've built and edited a lot of HTML forms, and when form fields were updated very frequently, one of the easiest mistakes to make was forgetting to indicate via the form label that the input was required (or was now optional after previously being required). The visual corrections were always easy to adjust (adding/removing an asterisk or "required" text to the label), but it would have been nice if there were a way to automatically sync the two together to reduce developer error. With &lt;code&gt;:has()&lt;/code&gt;, now there is.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/pursuitofleisure/embed/BaVMZdo?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;This is a standard form with a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; containing each label and input. The label and input are sibling elements. The name and email fields are both required. For a required input, before &lt;code&gt;:has()&lt;/code&gt;, I would write the HTML like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"contact__field"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Name &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;*&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since the "name" input is required, I would add a &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; tag containing an asterisk to the label to visually indicate to the user that this is a required field. This is where developer error occurs if this field is later switched to optional with the removal of the &lt;code&gt;required&lt;/code&gt; attribute from the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;, but where the label is not updated to match.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using :has() to dynamically update required labels
&lt;/h3&gt;

&lt;p&gt;With &lt;code&gt;:has()&lt;/code&gt;, now we can target labels that specifically have any sibling with the "required" attribute. Just put the regular CSS selectors you want within the parentheses. In this example, I am using the adjacent sibling selector:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;label&lt;/span&gt;&lt;span class="nd"&gt;:has&lt;/span&gt;&lt;span class="o"&gt;(+&lt;/span&gt; &lt;span class="nd"&gt;:required&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;' *'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f68ea6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This selector says, "Find all labels that have an immediate sibling with the 'required' attribute, and create the 'after' pseudo-element."&lt;/p&gt;

&lt;p&gt;This means my HTML can now be updated. I no longer need to manually mark up the label with any additional HTML or classes because the CSS will now generate the asterisk for the label automatically depending on the existence of the "required" attribute of the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"contact__field"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Name&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! If you follow the same HTML structure, you can add additional form fields and the label will adjust dynamically based on a required or optional input.&lt;/p&gt;

&lt;h2&gt;
  
  
  Navigation Menu with Parent Dropdowns &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Let's say you have a primary navigation, and some of the landing pages have children pages, and these pages will be displayed once the user hovers over the parent link. You'd probably want an indicator to let the user know that there will be subpages, and we can do that with &lt;code&gt;:has()&lt;/code&gt;. Here I am adding an arrow pseudo-element to links with child pages (in this example, the "About Us" link):&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/pursuitofleisure/embed/VwdWPKp?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If you were using a CMS or components to build your site, you could use logic to mark parent pages with a specific class and then style from there, but I'm purposely avoiding using CSS classes so you can see how this can be done without additional markup.&lt;/p&gt;

&lt;p&gt;For this menu I am using unordered lists, and for nested lists, the HTML syntax is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;About Us&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Culture&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;History&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Team&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using :has() to dynamically indicate parent pages
&lt;/h3&gt;

&lt;p&gt;All links use an &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; tag, and all parent pages will have a nested &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; tag containing the child links. This means we can specifically style all (and only) parent pages by targeting &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; tags that have a &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; as a direct child using &lt;code&gt;:has()&lt;/code&gt;. Again, place the selector within the parentheses; here I'm using the child combinator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.links&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="nd"&gt;:has&lt;/span&gt;&lt;span class="o"&gt;(&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;-20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;50%&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;border-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#044b7f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="nb"&gt;transparent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border&lt;/span&gt; &lt;span class="m"&gt;0.4s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This selector says, "In the navigation list, find all &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; tags that have a direct &lt;code&gt;&amp;lt;ul&amp;gt;&lt;/code&gt; child, and create the 'after' pseudo-element." All other &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; tags without this child element (non-parents) will not be affected. There is additional styling related to the hover and displaying of the submenu on hover, but the main selector that will continue to be used is the &lt;code&gt;.links &amp;gt; li:has(&amp;gt; ul)&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;And that's all that's needed! In the HTML, if you were to create additional parent links in the navigation with child links, these would automatically get the same parent styling with the pseudo-element arrow without needing any additional markup or CSS classes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;These are just a couple of simple examples where &lt;code&gt;:has()&lt;/code&gt; can make CSS more dynamic and convenient. There are ways to chain the selectors for much more complex uses, but hopefully this is enough to get you started with this powerful new functionality.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>codepen</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>State of CSS 2022 Survey</title>
      <dc:creator>Diana Le</dc:creator>
      <pubDate>Wed, 07 Dec 2022 19:21:31 +0000</pubDate>
      <link>https://dev.to/dianale/state-of-css-2022-33p7</link>
      <guid>https://dev.to/dianale/state-of-css-2022-33p7</guid>
      <description>&lt;p&gt;I always get a little excited each time the annual State of CSS survey rolls around because I can feel validated in what I know, and I can also discover new things I haven't heard about so I can learn them in the future. I took the 2022 survey almost immediately when it was released this year and my personal results made me feel demoralized:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F45ennp9a6xbbcdpj5b0a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F45ennp9a6xbbcdpj5b0a.png" alt="My State of CSS Survey results showing a 33% knowledge score (18 out of 54 features mentioned) "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'd been scoring 70+% each time I'd taken previous surveys so I was surprised how low I scored this time. But there are a couple things going on here. First is the rapid speed in which new CSS features are rolling out to browsers now, which is a great thing. We won't have to wait for a "CSS4" spec; individual features are able to be implemented in browsers. &lt;/p&gt;

&lt;p&gt;The second factor is how web development requires constant learning. Hopefully you are able to keep up with at least some of the new features in your job, but I've worked in roles where this wasn't prioritized and it required personal time to keep up. It can also feel overwhelming even if you do have time to learn at work just on account of how many new features there are and where to start, and whether those new features have practical uses for what you're working on.&lt;/p&gt;

&lt;p&gt;In the past few months I've been more proactive about my career and focusing more on CSS, so I'll be making a series specifically on features from this survey so I can learn and hopefully help you to learn as well. These will not be in any particular order, and there may be multiple articles about the same feature depending on the functionality. Overall I'm pretty excited to explore all these new CSS features. Let's do this!&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>When did you create a Stack Overflow account?</title>
      <dc:creator>Diana Le</dc:creator>
      <pubDate>Tue, 21 Jun 2022 17:14:59 +0000</pubDate>
      <link>https://dev.to/dianale/when-did-you-create-a-stack-overflow-account-3nk2</link>
      <guid>https://dev.to/dianale/when-did-you-create-a-stack-overflow-account-3nk2</guid>
      <description>&lt;h2&gt;
  
  
  It took me 9+ years to join Stack Overflow
&lt;/h2&gt;

&lt;p&gt;I've been using Stack Overflow as a resource for web development for 9+ years now, but it wasn't until this week that I actually created an account and started answering questions and commenting and it's been incredibly rewarding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why did it take so long?
&lt;/h3&gt;

&lt;p&gt;Maybe because it's always been such a major source of developer information, but I always found the site intimidating because every now and then I would see a question that I thought was legitimate get downvoted, or I was put off by some long critical arguments over which answer was "right." Most developers on my team didn't have accounts either because they felt similarly. &lt;/p&gt;

&lt;p&gt;I can't even fully explain where this paranoia came. The thought was something like what if you answered a question that wound up being severely downvoted by the entire community, and then you find out you're not a "real developer." The other thought was any question that I can answer, another developer has probably already answered, so what's the point? I finally realized those were unhealthy insecurities that I was placing on myself. The whole point of the site relies on an active community.&lt;/p&gt;

&lt;h3&gt;
  
  
  Providing my first answer
&lt;/h3&gt;

&lt;p&gt;I found out that you can't upvote an answer until you have at least 15 points so it was necessary to find a question I could solve. The responsiveness of the community is lightning fast too. I think my first answer for a question that was posted 1 minute earlier already had another answer by the time I finished typing my reply. But my answer got upvoted immediately and I saw the little points notification in the top right. Then I answered another question and got upvoted and then I got the power to add comments. Other answers never got responses, or my answer wasn't what the user needed. But hey, I tried. Turns out getting started was not as scary as I thought it would be.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally being part of the community
&lt;/h2&gt;

&lt;p&gt;Now I feel guilty for never upvoting and showing gratitude for all those answers that have been vital to solving problems I've encountered over the years, but better late than never. I'm making it a goal to casually answer questions when I can because at the end we're all trying to learn and help each other, and if something I answer winds up not being right, then I'll learn the better way to do it. And I can finally ask questions when I'm stuck instead of combing through dozens of posts trying to find my exact problem.&lt;/p&gt;

&lt;p&gt;There are times as a developer when I've felt like I've just had to stick my head down and code and figure out any problems on my own, even though I was always happy to help out a coworker who got stuck on a coding issue. That's how I view being active on Stack Overflow. You're helping someone out and growing your own troubleshooting skills, just on a much wider scale.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't doubt yourself
&lt;/h3&gt;

&lt;p&gt;If you've restrained from joining Stack Overflow for the same reasons, then I encourage you to join the community if you feel it would be beneficial. I'm not interested in the clever gamification system they have with badges and points, but it does feel rewarding to contribute back to the community that has helped me out a lot throughout my developer career.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devjournal</category>
      <category>discuss</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Best Internet Explorer Troubleshooting Memories</title>
      <dc:creator>Diana Le</dc:creator>
      <pubDate>Wed, 15 Jun 2022 03:47:16 +0000</pubDate>
      <link>https://dev.to/dianale/best-internet-explorer-troubleshooting-memories-7m3</link>
      <guid>https://dev.to/dianale/best-internet-explorer-troubleshooting-memories-7m3</guid>
      <description>&lt;p&gt;In honor of IE retiring tomorrow June 15, let's talk about our best (or worst depending on your point of view) troubleshooting experiences with Internet Explorer.&lt;/p&gt;




&lt;p&gt;One of my first tasks at my first web development job was to make sure another developer's site was working in IE 7, 8, and 9. We had an old Windows XP desktop in a corner of the dev room specifically to test IE versions and I probably spent 20 hours fixing issues on that site, hacking through floats and z-indexes and fixing random JavaScript issues (or leaving them alone if the site still seemed to be working). I had always heard about IE being bad but didn't really get it, but after that task... I finally understood.&lt;/p&gt;

&lt;p&gt;I haven't worked in IE for a while now and much like how we used to use CSS floats for layouts, I'd almost forgotten how much more tedious troubleshooting CSS used to be.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;As an aside I will say that despite all the dunking we like to do on IE, they had smart people working on the browser and the origin of CSS grid came from the IE team so it wasn't all bad in the later years.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>discuss</category>
      <category>browsers</category>
    </item>
  </channel>
</rss>
