<?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: Carly Ho 🌈</title>
    <description>The latest articles on DEV Community by Carly Ho 🌈 (@carlymho).</description>
    <link>https://dev.to/carlymho</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%2F30828%2Fc0b598ed-b218-4609-acc7-5aae8a740ab0.jpg</url>
      <title>DEV Community: Carly Ho 🌈</title>
      <link>https://dev.to/carlymho</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/carlymho"/>
    <language>en</language>
    <item>
      <title>Tech, Bread, and Roses🌹</title>
      <dc:creator>Carly Ho 🌈</dc:creator>
      <pubDate>Fri, 08 Mar 2019 17:52:40 +0000</pubDate>
      <link>https://dev.to/carlymho/tech-bread-and-roses-47g2</link>
      <guid>https://dev.to/carlymho/tech-bread-and-roses-47g2</guid>
      <description>&lt;p&gt;There’s a lot that’s been said about surviving the early stages of a career as an underrepresented minority in tech. We think a great deal about how to get through, tell our stories of triumph over adversity. We tell each other to put our own oxygen mask on first, before assisting others.&lt;/p&gt;

&lt;p&gt;We don’t so much talk about what you do when  you’re &lt;em&gt;ready&lt;/em&gt; to help others.&lt;/p&gt;

&lt;p&gt;I’m not just talking about getting more women and gender minorities into code via mentorship, or volunteering with women in tech orgs—which is still essential. For more kinds of people to succeed—and for us to create balance for better—we need to create systems that will lift them up.&lt;/p&gt;

&lt;p&gt;Learning to code is just one part of building a solid career. You can be the best programmer in the world, but without sufficient compensation, adequate healthcare benefits, access to parental leave, time to relax and lead a personal life, and the ability to feel safe in the workplace, you won't get very far. Stress takes its toll. Those of us of &lt;em&gt;any&lt;/em&gt; gender at the senior level know that our voices carry weight, and we have a responsibility to advocate for both our co-workers, and the rest of the workers in the industry.&lt;/p&gt;

&lt;p&gt;Creating comfortable lives for those who work in our industry—whether they're programmers, project managers, designers, administrative staff, or housekeepers—certainly can be said to be beneficial from a financial standpoint. I don't think it would surprise anyone to hear that happy employees mean better productivity and quality of work. However, it's my firm belief that those in positions of leadership have an ethical imperative to improve the standard of living for those around them.&lt;/p&gt;

&lt;p&gt;If you're senior level or above, do you know if your company has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A clear and public policy on harrassment?&lt;/li&gt;
&lt;li&gt;A good healthcare plan for all employees that includes mental health care?&lt;/li&gt;
&lt;li&gt;LGBTQ-inclusive healthcare, including transition care and fertility treatment?&lt;/li&gt;
&lt;li&gt;Public salary information?&lt;/li&gt;
&lt;li&gt;A clear understanding of nonbinary pronouns and what constitutes misgendering?&lt;/li&gt;
&lt;li&gt;Parental leave for all genders?&lt;/li&gt;
&lt;li&gt;Adequate work/life balance for all employees?&lt;/li&gt;
&lt;li&gt;A continuing education budget available to all employees?&lt;/li&gt;
&lt;li&gt;Equal access to restrooms, including gender-neutral ones?&lt;/li&gt;
&lt;li&gt;A flexible work-from-home policy?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If it doesn't, find out who has power to implement those things, and bring it up and don't stop bringing it up to them. There is a bit of "if you build it, they will come" to diversity; even if you have the numbers, there'll still be turnover if employees don't feel supported in their day-to-day life.&lt;/p&gt;

&lt;p&gt;Furthermore, as leaders in technology, we have responsibility to make sure that what we create will help bring balance for better. Stories abound of apps that don't properly recognize facial features on dark-skinned people, internet-connected devices being used for emotional terrorism by abusers, and sensitive information being leaked to untrustworthy entities. We have the ability to make sure that tech is both used to include, and also that it isn't used to exclude or make people unsafe.&lt;/p&gt;

&lt;p&gt;"Computing professionals’ actions change the world," the Association for Computing Machinery's code of ethics begins. "To act responsibly, they should reflect upon the wider impacts of their work, consistently supporting the public good." This will rarely be found in a job description—but, it is our job regardless.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;No more the drudge and idler / ten that toil, for one reposes / but a sharing of life's glories / bread and roses, bread and roses.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>wecoded</category>
      <category>inclusion</category>
    </item>
    <item>
      <title>#bestofdev on Inclusion</title>
      <dc:creator>Carly Ho 🌈</dc:creator>
      <pubDate>Thu, 08 Nov 2018 06:15:45 +0000</pubDate>
      <link>https://dev.to/carlymho/bestofdev-on-inclusion-3g60</link>
      <guid>https://dev.to/carlymho/bestofdev-on-inclusion-3g60</guid>
      <description>&lt;p&gt;Dev.to has become a great home for diversity, equity and inclusion content related to the tech industry, including this year's great &lt;a href="https://dev.to/t/shecoded"&gt;#shecoded&lt;/a&gt;/&lt;a href="https://dev.to/t/theycoded"&gt;#theycoded&lt;/a&gt; series for International Women's Day. It's spread out across a lot of tags, though, so with the help of the dev.to admins, we're working to make it a nice, fancy tag home under &lt;a href="https://dev.to/t/inclusion"&gt;#inclusion&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We (&lt;a href="https://dev.to/carlymho"&gt;Carly&lt;/a&gt;, &lt;a href="https://dev.to/sublimemarch"&gt;Fen&lt;/a&gt;, and &lt;a href="https://dev.to/thejessleigh"&gt;Jess&lt;/a&gt;) are three developer friends who care a lot about Diversity, Equity and Inclusion (DEI) and work to drive it as part of our day jobs as well as through meetups and online organizing. Today, we've put together a quick round-up of some of our favorite DEI-related articles on Dev.to so far!&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/rhymes" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2693%2Fbfd9a4a5-92b3-4ac3-a276-3ccb68d78203.jpg" alt="rhymes"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/rhymes/britain-in-the-70s-killed-its-tech-industry-because-of-sexism-3h08" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Britain in the 70s killed its tech industry because of sexism&lt;/h2&gt;
      &lt;h3&gt;rhymes ・ Sep 25 '18&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#discuss&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#womenintech&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#technology&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;div class="ltag__link"&gt;
  &lt;div class="ltag__link__content"&gt;
    &lt;div class="missing"&gt;
      &lt;h2&gt;Article No Longer Available&lt;/h2&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;div class="ltag__link"&gt;
  &lt;a href="/maxart2501" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1737%2Fb0afc4df-0cba-4bff-be66-a9094d23c223.jpg" alt="maxart2501"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/maxart2501/on-lowering-the-bar" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;On lowering the bar&lt;/h2&gt;
      &lt;h3&gt;Massimo Artizzu ・ Aug 25 '17&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#diversity&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#hiringprocess&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#inclusion&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#damoresmanifesto&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;div class="ltag__link"&gt;
  &lt;a href="/joelarson4" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F22482%2F177eff21-6781-4b0f-ae11-2f482bce807f.jpg" alt="joelarson4"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/joelarson4/what-could-be-better-than-pizza-and-beer--why-you-need-to-provide-more-inclusive-food-at-your-tech-event" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;What could be better than pizza and beer?  Why you need to provide more inclusive food at your tech event.&lt;/h2&gt;
      &lt;h3&gt;joe larson ・ Jun 19 '17&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#food&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#events&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tech&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#inclusion&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;div class="ltag__link"&gt;
  &lt;a href="/uu" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F102795%2F72fb1f28-ca9f-4679-9c63-44a94415a8ff.png" alt="uu"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/uu/ai-is-very-biased-and-we-should-stop-it-3gmn" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;A.I is very biased and we should stop it&lt;/h2&gt;
      &lt;h3&gt;Uchi Uchibeke ・ Sep 19 '18&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#ai&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#machinelearning&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#diversity&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#womenintech&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Those are some of our favorites! What are yours? (From here or elsewhere!) Are there any DEI topics you wish there was more written about?&lt;/p&gt;

</description>
      <category>inclusion</category>
      <category>bestofdev</category>
    </item>
    <item>
      <title>#AdventOfCode: What language are you using?</title>
      <dc:creator>Carly Ho 🌈</dc:creator>
      <pubDate>Tue, 06 Nov 2018 19:22:18 +0000</pubDate>
      <link>https://dev.to/carlymho/adventofcode-what-language--are-you-using-4ae0</link>
      <guid>https://dev.to/carlymho/adventofcode-what-language--are-you-using-4ae0</guid>
      <description>&lt;p&gt;&lt;a href="https://adventofcode.com/" rel="noopener noreferrer"&gt;Advent of Code&lt;/a&gt; is a December code challenge, with code puzzles running from the first through Christmas, put together by &lt;a href="https://twitter.com/ericwastl" rel="noopener noreferrer"&gt;Eric Wastl&lt;/a&gt;. I completed it last year, and I know a lot of folks here have done it in the past!&lt;/p&gt;

&lt;p&gt;I did Python last year, but I was considering choosing something I'm less familiar with this year (something in the set of Go, Haskell, Rust, Elixir, maybe). As we're coming up on AoC 2018, does anyone else planning to participate have their language picked out for this year?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>adventofcode</category>
    </item>
    <item>
      <title>Let’s make life easier for autistic folks at work!</title>
      <dc:creator>Carly Ho 🌈</dc:creator>
      <pubDate>Tue, 09 Oct 2018 19:25:15 +0000</pubDate>
      <link>https://dev.to/carlymho/lets-make-life-easier-for-autistic-folks-at-work-17pl</link>
      <guid>https://dev.to/carlymho/lets-make-life-easier-for-autistic-folks-at-work-17pl</guid>
      <description>&lt;h2&gt;
  
  
  About Me
&lt;/h2&gt;

&lt;p&gt;My name’s Carly Ho, and I’m a Senior Engineer at Clique Studios in Chicago; I’m also an autistic adult. I was diagnosed during college as part of getting help for my executive function problems. I sometimes have difficulty with getting overwhelmed by sounds, often find eye contact incredibly uncomfortable, and can get really fidgety in long meetings if I’m not actively engaged somehow.&lt;/p&gt;

&lt;p&gt;I’ve made it to a place I’m pretty happy with, career-wise, but it’s not all been smooth sailing, and over the course of my years in tech I’ve learned a lot of things about myself and the environments I work best in. To pay it forward, I wanted to put together some information to help make more workplaces a comfortable place for autistic folks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some Terminology: What is autism?
&lt;/h2&gt;

&lt;p&gt;Autism is hard to pin down, since its markers exist on a spectrum. Autistic people “may communicate, interact, behave, and learn in ways that are different from most other people,” in the words of the CDC, but “there is often nothing about how people with ASD [Autism Spectrum Disorders] look that sets them apart from other people.”&lt;/p&gt;

&lt;p&gt;The differences in how autistics communicate and perceive the world often cause them (us!) social and behavioral challenges in understanding and being understood. While there are no hard limitations on what autistic people are capable of, the way society is structured can make many things significantly more challenging.&lt;/p&gt;

&lt;p&gt;While “person-first” terminology is recommended for referring to people with disabilities, many autistics prefer identity language (“autistic” versus “person with autism”). This doesn’t cover 100% of the autistic community, so it’s always good to double-check with people who have a personal stake in it.&lt;/p&gt;

&lt;p&gt;“Neuroatypical” is also a way to refer to people with neurological differences, often specifically referring to autism, but sometimes also other neurological conditions and developmental disorders. (“Neurotypical” being the inverse.)&lt;/p&gt;

&lt;h2&gt;
  
  
  How are work environments stressful for neuroatypical folks? And how can we fix it?
&lt;/h2&gt;

&lt;p&gt;There's a lot of things in the workplace—and particularly in the tech workplace—that can be a struggle for autistic folks to handle. While tech has long been considered something of a career refuge for autistic people in that it's more acceptable to stay heads-down programming most of the day and not socialize much, that's not how all autistic people prefer to work, and there are still a lot of hurdles.&lt;/p&gt;

&lt;p&gt;A lot of this advice is also what in accessibility is called a &lt;a href="https://ssir.org/articles/entry/the_curb_cut_effect"&gt;"curb cut" effect&lt;/a&gt;—while it's helpful for autistic folks, they're also things that might help people with other neurological conditions, or even neurotypical employees.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interpersonal Communication
&lt;/h3&gt;

&lt;p&gt;Communication is often a struggle for autistic folks. Some are entirely nonverbal, and others can talk but struggle to express themselves or read tone from others in spoken communication. As a result, many autistics prefer email or chat programs for communication, where they can consider their words more carefully, and where emojis and parentheticals can clarify emotional tone.&lt;/p&gt;

&lt;p&gt;Furthermore, communication in general can be stressful; social anxiety is a frequent companion of autism due to the fact that autistic people go through a lot of uncertainty in social situations. If you’re sending someone a message, even if it’s just friendly conversation, lead with your intent; open-ended messages can stress people out, since they don’t know if it’s bad news, a request, or just chatter.&lt;/p&gt;

&lt;p&gt;Try and get to know how individuals like to receive communication and feedback. I know some people (&lt;a href="https://github.com/cmho/README/blob/master/README.md"&gt;including me!&lt;/a&gt;) have “readme” files about how they prefer to communicate at work. If your organization hosts events, consider also having &lt;a href="https://autisticadvocacy.org/wp-content/uploads/2014/02/ColorCommunicationBadges.pdf"&gt;color-coded badges&lt;/a&gt; at events to allow people to set their own level of engagement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Noise and External Stimuli
&lt;/h3&gt;

&lt;p&gt;Many autistics have difficulty with various forms of sensory processing. Noise is the most common office hazard out of all of those—open office environments, which are ubiquitous in tech, often come with noise and distractions that can make it even more difficult for autistic employees to work, since autism can make it harder to filter out distracting noise.&lt;/p&gt;

&lt;p&gt;Try and have an emcee or event leader keep cross-talk/multi-directional noise to a minimum at events for people who have sensory overload problems, and provide rooms in the office for people to take phone calls and have conversations away from desks. If you have an open-office environment, consider subsidizing noise-cancelling headphone purchases. It can also be nice to have work events in quieter settings than the usual venues of restaurants or bars.&lt;/p&gt;

&lt;h3&gt;
  
  
  Long Meetings and Stimming
&lt;/h3&gt;

&lt;p&gt;Many autistic people have difficulty maintaining focus through long meetings. The expression of autism can sometimes overlap with that of ADHD—fidgeting and poor attention span. A lot of autistic people feel most comfortable when allowed to engage in &lt;em&gt;stimming&lt;/em&gt;, which often involves some kind of repetitive movement. Doing this generally helps autistic people maintain a sense of calm and focus, but can be misconstrued as being inattentive or disruptive.&lt;/p&gt;

&lt;p&gt;Autistic adults in the workplace generally know how to regulate their own behavior in a way such that it's not attention-grabbing. However, specifically allowing people at meetings to do other things to occupy their hands and not necessarily sit completely still as long as they're engaged is something that might help autistic employees feel more comfortable in knowing that their behavior won't be interpreted as disengagement.&lt;/p&gt;

&lt;p&gt;If it's necessary to have long meetings or education sessions, consider building in things that invite attendees to participate and have stretch breaks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dealing with priority and schedule changes
&lt;/h3&gt;

&lt;p&gt;A common feature of autism is difficulty with executive function—which is to say, organization and successfully executing all the steps to complete a task. It can sometimes interfere with memory, planning, and time management, among other things. Autistic adults in the workplace generally have some measure of executive function, but will sometimes need different accommodations than neurotypical employees.&lt;/p&gt;

&lt;p&gt;Let folks know about schedule changes and plan changes with as much lead time as possible. This is polite, but also helps autistic co-workers re-plan their time.&lt;/p&gt;

&lt;p&gt;If you can, make requests or tasks in written form in addition to verbally so that there’s a reference able record. Also, try to be specific as possible about priority of tasks if there’s a distinct order; what may seem obvious to you might not to others.&lt;/p&gt;

&lt;h2&gt;
  
  
  And above all else…
&lt;/h2&gt;

&lt;p&gt;Include neuroatypical folks in your diverse hiring efforts, and listen to them about what accommodations they need. The saying goes that “if you’ve met one autistic person, you’ve met one autistic person,” and it holds true for a lot of other types of neuroatypicality. Different neuroatypical folks have very different skills, needs, and difficulties, but we also tend to have a good handle on what will help us best if you make it clear that it’s possible to be accommodated.&lt;/p&gt;

&lt;h2&gt;
  
  
  What helps you?
&lt;/h2&gt;

&lt;p&gt;Readers at home: those of you who are autistic or neuroatypical, what challenges do you find in the office? What accommodations and strategies do you find helpful?&lt;/p&gt;

</description>
      <category>inclusion</category>
      <category>diversity</category>
      <category>workplace</category>
    </item>
    <item>
      <title>What's in a name (validation)?</title>
      <dc:creator>Carly Ho 🌈</dc:creator>
      <pubDate>Mon, 08 Oct 2018 18:56:02 +0000</pubDate>
      <link>https://dev.to/carlymho/whats-in-a-name-validation-4b41</link>
      <guid>https://dev.to/carlymho/whats-in-a-name-validation-4b41</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was adapted from my &lt;a href="https://www.youtube.com/watch?v=yuQ5YTNO3I0"&gt;talk at AlterConf Chicago 2017&lt;/a&gt;, which has also been adapted into a handy &lt;a href="https://carlymho.itch.io/whats-in-a-name-validation"&gt;zine version&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Validating Names
&lt;/h2&gt;

&lt;p&gt;Let’s talk about names!&lt;/p&gt;

&lt;p&gt;See how my name’s right at the top of this thing? Names are generally one of the first things we ask for and one of the first things we offer in conversation as part of getting to know someone.&lt;/p&gt;

&lt;p&gt;Names are also a pretty personal thing. It’s one thing to dislike your own name for your own reasons, but having someone else mangle your name can range from annoying to genuinely hurtful. So, it’s important to think about how we validate names as we work to create more inclusive technology.&lt;/p&gt;

&lt;p&gt;So names are pretty important information. However: names can take a lot of forms, and it's hard to account for all of them. If we want to build validation into our forms, how do we validate names? Can we?&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a name?
&lt;/h2&gt;

&lt;p&gt;What are things that you’ve seen forms assume about how a name should be formatted?&lt;/p&gt;

&lt;p&gt;Some assumptions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Everyone has one first name and one last name.&lt;/li&gt;
&lt;li&gt;Everyone has one first name and two last names!&lt;/li&gt;
&lt;li&gt;A name has a minimum of three characters. - you'd be surprised how often this comes up. Hilariously some of them accept "Ho!" and not "Ho"&lt;/li&gt;
&lt;li&gt;A given name comes first, and a family name comes last.&lt;/li&gt;
&lt;li&gt;Names are composed of letters.&lt;/li&gt;
&lt;li&gt;Names are composed of letters from the Latin alphabet, or can be losslessly translated into letters from the Latin alphabet.&lt;/li&gt;
&lt;li&gt;Names don't change, or only change at a few very specific points in time.&lt;/li&gt;
&lt;li&gt;Everyone has one canonical full name.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are all actually wrong! As it turns out, basically all assumptions you can make about names are wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  So what IS a name, actually?
&lt;/h2&gt;

&lt;p&gt;What people take for granted as being a "name" anywhere is not true in the majority of other places—and even within their own country.&lt;/p&gt;

&lt;h3&gt;
  
  
  In the USA, we still often assume western euro norms
&lt;/h3&gt;

&lt;p&gt;While the USA is extremely diverse, there still tends to be a lot of expectation that names conform to a certain "Americanized" standard&lt;/p&gt;

&lt;p&gt;This goes back to way before web forms--immigrants did and still do often adopt more "American" names in hopes that assimilating would lead to more opportunity. People with names that don't sound European even today often find themselves marked as perpetual foreigners, even when they were born here, and their parents were born here, and so on.&lt;/p&gt;

&lt;p&gt;These expectations, when extended to web forms, both are really obnoxious and do cause problems. I actually was looking into pitching a different talk to another conference earlier this year, but it turned out their form validated names to be a minimum of three characters. To their credit, they were very graceful and fixed the problem after I let them know, but it's possible other people just gave up. (Hilariously, I have occasionally gotten around forms set up like that by adding an exclamation point.)&lt;/p&gt;

&lt;h3&gt;
  
  
  Names: a way to refer to someone.
&lt;/h3&gt;

&lt;p&gt;That's pretty much it. It's very difficult to define a name as anything other than this very basic, very vague thing, without any incorrect premises.&lt;/p&gt;

&lt;p&gt;Sorry, there's no good way to validate them!&lt;/p&gt;

&lt;h2&gt;
  
  
  So what can you do?
&lt;/h2&gt;

&lt;p&gt;So, okay. Names are nigh-impossible to pin down, but you want to make sure you have data that's useful and serves the intended purpose. What can you do about that?&lt;/p&gt;

&lt;h3&gt;
  
  
  What do you need the name for?
&lt;/h3&gt;

&lt;p&gt;So, when we're gathering name information via a web form, the point of a validation is not actually to figure out what is and isn't a name; the point is actually to get the information we need to use elsewhere. Sometimes we just want to be able to greet a user in emails or on their dashboard, sometimes we need it to respond to a personal communication, sometimes we need to know what to put on a packing label, and so on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do you need to ID them by name?
&lt;/h3&gt;

&lt;p&gt;Do you really need to identify a user by a name? If the information isn't used in any way other than cosmetically, and you have other ways of identifying a user uniquely, such as email, you might be able to just drop it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do you need to separate first name/last name?
&lt;/h3&gt;

&lt;p&gt;If there's never any reason for you to need only the given name or names, or only the surname or surnames, you can replace first name/last name with a single full name field. That way people can enter their name in a way that feels right to them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do you only need one part of a name?
&lt;/h3&gt;

&lt;p&gt;Like, just the personal name, or just the surname(s)? If so, consider collecting only that data, and labeling it in a way that makes sense to users from any cultural context, such as: "How should we address you?" "What's your full formal title?" or something similar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let the user help you by telling them what you'll use the name for
&lt;/h3&gt;

&lt;p&gt;If a user knows you want a name for how to address them in emails, or for addressing a petition to a Congressperson, or to mail them a package, that's useful context that will help the user enter information that's helpful to both of you.&lt;/p&gt;

&lt;p&gt;If you know, for example, that some of your users have multiple names that they go by (e.g., some people adopt an "English" given name on immigrating, or to do business with English-speakers, but retain a different legal name), your form might need to ask for both of those names if you anticipate situations where both are needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't assume which part is the surname/family name
&lt;/h3&gt;

&lt;p&gt;Some people have multiple given names, multiple surnames, or additional name parts that signify gender, generation, marital status or religious identity, among other things.&lt;/p&gt;

&lt;p&gt;The world is also not uniform on whether the given name or the family name is written first. For example, many people with Spanish names coming to the United States encounter the issue that only their second family name gets read as their "real" surname, whereas in most Spanish-speaking countries the first one is generally the emphasized one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Make sure your ui accommodates both long + short names
&lt;/h3&gt;

&lt;p&gt;Twitter, for example, only allows a 16-character display name, which is not much! While it means they don't have to adjust their placement of items in their UI, it means that a large number of people can't enter their whole name on Twitter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compassionate Validation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Your system might not be able to process all possible names
&lt;/h3&gt;

&lt;p&gt;Some systems are old, and have limited ability to be changed to accommodate larger character sets, spaces, punctuation, etc. due to the size or sensitivity of the data. That's understandable. I think we're all familiar with airline systems, for example, which stubbornly refuse to process hyphens and tend to squeeze out spaces.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't position it as a problem with the user's name
&lt;/h3&gt;

&lt;p&gt;If you can't process a name as-entered in your system, don't position it as a problem with the user's name.&lt;/p&gt;

&lt;p&gt;John Graham-Cumming wrote in &lt;a href="http://blog.jgc.org/2010/06/your-last-name-contains-invalid.html"&gt;a 2010 blog post&lt;/a&gt; about encountering this issue: "What they actually meant is: our web site will not accept that hyphen in your last name. But do they say that? No, of course not. They decide to shove in my face the claim that there's something wrong with my name." If it's their name, it can't be &lt;em&gt;invalid&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Admit the system limitation in validations + work to improve
&lt;/h3&gt;

&lt;p&gt;The best thing you can do is admit the system limitations in your validation messages (Graham-Cumming suggests "Our system is unable to process last names that contain non-letters, please replace them with spaces", for example) and continue to work on any improvements you can make so that more names can be correctly processed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Further Reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://stackoverflow.com/questions/888838/regular-expression-for-validating-names-and-surnames"&gt;"Regular Expression for Validating Names and Surnames,"&lt;/a&gt; stackoverflow&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://blog.jgc.org/2010/06/your-last-name-contains-invalid.html"&gt;"Your Last Name Contains Invalid Characters,"&lt;/a&gt; John Graham-Cumming&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://dublincore.org/documents/1998/02/03/name-representation/"&gt;"Representing People's Names in Dublin Core,"&lt;/a&gt; Andrew Waugh&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://wookware.org/name.html"&gt;"Wookey - is that it?"&lt;/a&gt; Wookey&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/"&gt;"Falsehoods Programmers Believe About Names,"&lt;/a&gt; Patrick McKenzie&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>forms</category>
      <category>webdev</category>
      <category>validation</category>
    </item>
    <item>
      <title>How to Get Into Mastodon</title>
      <dc:creator>Carly Ho 🌈</dc:creator>
      <pubDate>Tue, 02 Oct 2018 04:43:09 +0000</pubDate>
      <link>https://dev.to/carlymho/how-to-get-into-mastodon-2m1g</link>
      <guid>https://dev.to/carlymho/how-to-get-into-mastodon-2m1g</guid>
      <description>&lt;p&gt;Maybe you’ve heard of the newish social network Mastodon, or maybe you haven’t, but between Facebook’s repeat mishandling of data and Twitter’s general toxicity, maybe you’re looking for a new way to keep in touch with your friends and professional networks! Here's a quick guide on how to get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Mastodon?
&lt;/h2&gt;

&lt;p&gt;Mastodon is a social network similar to Twitter in format, where users post statuses that can be seen in a stream, and can follow each others’ updates. The default layout on the web is similar to Tweetdeck, in fact! The main difference is that Mastodon is a distributed system broken into instances that anyone can host.&lt;/p&gt;

&lt;p&gt;Mastodon also has some nice extra features; posts can go up to 500 characters by default, rather than Twitter’s 280 (and some instances set their limit even higher). You can also control the privacy of specific tweets (only to who you’re following, or only to specific users) and set content warnings for your posts. Some instances also have even stricter codes of conduct and limitations on what content is allowed, if you don’t want to deal with spam or adult content.&lt;/p&gt;

&lt;p&gt;Mastodon isn’t so different from other parts of the internet, but it has its own variations on a lot of social media terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Toots = tweets, statuses&lt;/li&gt;
&lt;li&gt;Boost = retweet&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Fediverse" rel="noopener noreferrer"&gt;Fediverse&lt;/a&gt; = a collection of servers used for web publishing that work by an agreed-upon standard. Mastodon is a Fediverse.&lt;/li&gt;
&lt;li&gt;Favorite = like&lt;/li&gt;
&lt;li&gt;Locked account = private account&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Instances, and Picking Yours
&lt;/h2&gt;

&lt;p&gt;The original Mastodon instance is &lt;a href="https://mastodon.social" rel="noopener noreferrer"&gt;mastodon.social&lt;/a&gt;, but you can search the whole list of instances at &lt;a href="https://instances.social" rel="noopener noreferrer"&gt;instances.social&lt;/a&gt; or on &lt;a href="https://joinmastodon.org/" rel="noopener noreferrer"&gt;the Mastodon informational website&lt;/a&gt;. Instances are sometimes themed and have a particular culture to them; there are some targeted at artists, some for tech, some that are for posting selfies or birds only, some just for running mastodon bots.&lt;/p&gt;

&lt;p&gt;You’ll probably be fine on a general instance such as &lt;a href="https://mastodon.cloud" rel="noopener noreferrer"&gt;mastodon.cloud&lt;/a&gt; if you don’t have a particular preference, since you can follow anyone on any Mastodon instance. Your instance matters for two things: your full username/URL (so if you want to be &lt;code&gt;@yourname@webdev.network&lt;/code&gt;, sign up on webdev.network), and who shows up in what’s called the “Local Timeline,” which is a stream of all posts on that instance. The “Federated Timeline” shows all posts across &lt;em&gt;all&lt;/em&gt; instances, apart from any that your instance has blocked.&lt;/p&gt;

&lt;p&gt;Before you sign up on any one instance, consider clicking around to look at what instances exist, whether they’re open for new signups (some instances have a user cap or are invite-only) and if you like their vibe and the content available in their public timeline! You don’t need to make friends with everyone in your instance, but it’s good to get a feel for the culture. It’s also good to look at their stats for how many users they have and how many statuses have been posted on that instance; depending on how you want to use Mastodon, you may prefer a smaller, quieter instance, or a larger and more talkative one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Signing Up and Setting Up Your Account
&lt;/h2&gt;

&lt;p&gt;Once you’ve picked an instance, sign up! If an instance is open for signups, you’ll usually find it in the left-hand sidebar on the front page.&lt;/p&gt;

&lt;p&gt;Logged in, you’ll see a column for typing statuses, one for your timeline, one for your notifications, and one where you can open your local or federated timelines, or view your direct messages, favorites or lists.&lt;/p&gt;

&lt;p&gt;Above the status box, you’ll see a search bar, and then above that a gear icon, which is where you can manage your account settings.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edit Profile&lt;/em&gt; contains some controls for the look of your profile; you can edit your display name and bio, as well as add a profile image and header just like on Twitter. You can also choose to lock your account here, which will require followers to be approved by you, which is useful if you plan to make tweets private to followers. You can also enter up to 4 items of custom metadata for your profile, which you can use to display things like your website or pronouns.&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%2F5fjr47efxapcumou43lp.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%2F5fjr47efxapcumou43lp.png" alt="A set of four label and value fields for profile metadata."&gt;&lt;/a&gt;&lt;/p&gt;
Profile metadata entry fields



&lt;p&gt;&lt;em&gt;Preferences&lt;/em&gt; contains a number of settings for how you read and write on Mastodon, including selecting what language you’d like for the interface, and what languages to show in your timelines. This can be helpful for filtering out content you can’t read from the Local and Federated Timelines. Preferences also contains settings for hiding your posts from the Local/Federated timelines if you don’t want to be findable that way, and opt out of search engine indexing. You can also control what content to hide or display by default from here.&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%2Fol5819lizctxr6h0pre2.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%2Fol5819lizctxr6h0pre2.png" alt="A preferences panel allowing a user to set their account's default post privacy to public, unlisted, or followers-only."&gt;&lt;/a&gt;&lt;/p&gt;
Your account-level privacy settings



&lt;p&gt;A lot of the other settings sections are pretty straightforward, though worth exploring since they give you some other useful privacy controls. Authorized followers in particular is useful if you’re a locked account; this is where you can set your list of who can see your posts.&lt;/p&gt;

&lt;p&gt;You’ll also want to look into &lt;em&gt;Filters&lt;/em&gt;, which is under Settings; it allows you to filter out certain keyword content from any or all of your timelines, which is great if there’s a topic in the news you’d prefer not to see or if all your friends are really into a TV show you’re not into.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing a Toot
&lt;/h2&gt;

&lt;p&gt;It’s time to write your first toot if you haven’t already! You have up to 500 characters, unless your instance allows more. If you’d like to add images, click the icon of a camera. The globe icon allows you to adjust the privacy of your status; you can make any individual toot unlisted from public timelines, or post to your followers only. You can also just send a toot to specific users, like a direct message on Twitter.&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%2Fvp4y3ct8unep0prl6mrd.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%2Fvp4y3ct8unep0prl6mrd.png" alt="The Mastodon status box, showing the options for post privacy: public, unlisted, followers-only, direct message."&gt;&lt;/a&gt;&lt;/p&gt;
Your post privacy options, which override your account post privacy settings



&lt;p&gt;The other tool you have in writing toots on Mastodon is content warnings; you can manage them under the “CW” icon. If your toot contains sensitive content or a common phobia, you can label why you’re hiding your content with a warning, and then put the actual content underneath. Some Mastodon users also use this to tell jokes—they write the setup in the “warning” field and the punchline in the status box.&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%2F7d8ev0y93tq833hgdmt5.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%2F7d8ev0y93tq833hgdmt5.png" alt="The Mastodon status box, content warning field open, with text: "&gt;&lt;/a&gt;&lt;/p&gt;
An example of posting a toot with a content warning



&lt;p&gt;Then hit the Toot! button! That’s it, you’re live on Mastodon!&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding People to Follow
&lt;/h2&gt;

&lt;p&gt;If you’re looking to see who you already know that’s on Mastodon, you can use &lt;a href="https://bridge.joinmastodon.org/" rel="noopener noreferrer"&gt;Mastodon Bridge&lt;/a&gt;, which lets users connect their Twitter and Mastodon accounts so their followers on either platform can find their account on the other. You can also opt to add your information to the database so that people can look you up on Mastodon as well!&lt;/p&gt;

&lt;p&gt;Apart from already knowing people, the primary way to find people to follow is looking at your Local and Federated timelines to see what people are posting and following folks who look interesting. Many people will also add hashtags of things they like to post about to their profile to make them easy to search for, if you’re looking for people into the same topics!&lt;/p&gt;

&lt;h2&gt;
  
  
  Crossposting To and From Twitter
&lt;/h2&gt;

&lt;p&gt;If you want to still post content for your followers on Twitter but start ramping up your Mastodon presence, you can log in with both your Twitter and Mastodon accounts on the &lt;a href="https://crossposter.masto.donte.com.br/" rel="noopener noreferrer"&gt;Twitter-Mastodon Crossposter&lt;/a&gt;, which will automatically crosspost in either direction, with the option to include retweets/boosts, replies, mentions, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiple Accounts?
&lt;/h2&gt;

&lt;p&gt;As mentioned above, you can follow anyone on any mastodon instance from one account, so if you’d like to follow someone on birb.site when you’re on witches.live, there’s no need to create a birb.site account. You can also create curated lists of users, just like on Twitter, if you want to see a feed of just people you follow for tabletop gaming, or music, or people you know IRL. However, there are definitely reasons you might want to create more than one account:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Maintaining an account for a particular type of professional content (art, web development, etc) without getting your personal talk mixed in there&lt;/li&gt;
&lt;li&gt;Participating in an instance for posting a specific kind of content (bird pictures, selfies, etc)&lt;/li&gt;
&lt;li&gt;Managing an account for an organization, meetup group, or company&lt;/li&gt;
&lt;li&gt;Creating bots for Mastodon&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For most of those cases, I’d suggest setting up accounts on different Mastodon instances; there isn’t a whole lot of support for being logged into two accounts on one Mastodon instance like Tweetdeck provides for Twitter, but you &lt;em&gt;can&lt;/em&gt; keep two instances open in two separate tabs, and some mobile Mastodon clients allow you to be logged into multiple instances.&lt;/p&gt;

&lt;p&gt;If you want to switch to using a different account (even one on a different instance!), you can find a setting to redirect your account under &lt;em&gt;Edit Profile&lt;/em&gt; in your settings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running Your Own Mastodon Instance
&lt;/h2&gt;

&lt;p&gt;You might consider running your own Mastodon instance if you want really fine control over some instance-wide settings, if you want to fill a niche that isn’t already present, or if you want to have an instance that’s curated to a specific group of people, such as family or friends.&lt;/p&gt;

&lt;p&gt;An easy way to run your own is to use &lt;a href="https://masto.host" rel="noopener noreferrer"&gt;masto.host&lt;/a&gt;, which will manage a Mastodon instance for you. You can also run one off of your own server, if you have one and want to control your hosting. The resources Mastodon requires generally are related to how many users the instance has, which is why many instances have user caps or are invite-only. If you’re interested, you can find more info about running your own instance &lt;a href="https://github.com/tootsuite/mastodon" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow me on Mastodon!
&lt;/h2&gt;

&lt;p&gt;My ulterior motive in writing this is to get more folks on Mastodon so I can hang out with them! You can find me at &lt;a href="https://kitty.town/@carly" rel="noopener noreferrer"&gt;carly@kitty.town&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>socialnetworking</category>
      <category>socialmedia</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Dynamically Sizing Text for a Tag Cloud Effect</title>
      <dc:creator>Carly Ho 🌈</dc:creator>
      <pubDate>Wed, 16 May 2018 06:28:10 +0000</pubDate>
      <link>https://dev.to/carlymho/dynamically-sizing-text-for-a-tag-cloud-effect-15g0</link>
      <guid>https://dev.to/carlymho/dynamically-sizing-text-for-a-tag-cloud-effect-15g0</guid>
      <description>&lt;p&gt;It's common to see data presented in a tag cloud format—which is to say, a chunk of keywords or terms displayed inline, with each term sized to show its relative importance or frequency out of all the existing terms.&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%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2F7%2F79%2FTop_500_by_volume_on_the_NYSE.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%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2F7%2F79%2FTop_500_by_volume_on_the_NYSE.png" alt="tag cloud of New York Stock Exchange symbols"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A lot of times we see these tag clouds built into content management systems or generated via plugins, but how do we make something like this if we want to do it from scratch? In this tutorial I'll walk through how I built this feature for my own website, to display the relative amounts of time I've worked with different technologies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up
&lt;/h2&gt;

&lt;p&gt;I tried to keep the markup pretty simple:&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;data-year=&lt;/span&gt;&lt;span class="s"&gt;"2001"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;HTML&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;data-year=&lt;/span&gt;&lt;span class="s"&gt;"2002"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;CSS&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;data-year=&lt;/span&gt;&lt;span class="s"&gt;"2003"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;PHP&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;data-year=&lt;/span&gt;&lt;span class="s"&gt;"2010"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Javascript&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;data-year=&lt;/span&gt;&lt;span class="s"&gt;"2012"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Ruby&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;data-year=&lt;/span&gt;&lt;span class="s"&gt;"2010"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Python&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;data-year=&lt;/span&gt;&lt;span class="s"&gt;"2017"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Node.js&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;data-year=&lt;/span&gt;&lt;span class="s"&gt;"2010"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;MySQL&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;It's a simple unordered list. The only thing here that's special is that each &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; has a data-attribute, &lt;code&gt;data-year&lt;/code&gt;, which denotes the year I started working with that particular technology. If you were creating a tag cloud for the number of articles with a given tag on your blog, you might instead call the data-attribute &lt;code&gt;data-count&lt;/code&gt;, and set it to the number of articles with that tag.&lt;/p&gt;

&lt;p&gt;Moving on to the styles, again keeping it pretty simple. Mostly I stripped out the default formatting, aligned the content to the center, and set list-items to &lt;code&gt;display: inline-block&lt;/code&gt; so they coalesce into one block of text.&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="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&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;text-align&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="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;ul&lt;/span&gt; &lt;span class="nt"&gt;li&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;0&lt;/span&gt; &lt;span class="m"&gt;5px&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;inline-block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;vertical-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;middle&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;
  
  
  The Scripting
&lt;/h2&gt;

&lt;p&gt;First, let's wrap everything in an event handler for the window's &lt;code&gt;load&lt;/code&gt; event, just to make sure everything's in place before we start applying our font-sizing. I'm using a bit of jQuery here to speed the process along, but there's no reason you couldn't do it in vanilla Javascript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;load&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your font sizes change at certain screen size breakpoints, you may also want to re-trigger this on &lt;code&gt;resize&lt;/code&gt; as well as &lt;code&gt;load&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now that we've got that done, we need to get the range of numbers represented in our tag cloud.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ul li&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;year&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;maxVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;minVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;map&lt;/code&gt; function iterates over every list item and returns the value of the &lt;code&gt;data-year&lt;/code&gt; attribute, parsed as an integer; the &lt;code&gt;.get()&lt;/code&gt; method formats the output into an array.&lt;/p&gt;

&lt;p&gt;We then pass the numbers into Javascript's &lt;code&gt;Math.max&lt;/code&gt; and &lt;code&gt;Math.min&lt;/code&gt; functions to get the largest and smallest values, respectively. (&lt;code&gt;nums&lt;/code&gt; preceded by the &lt;code&gt;...&lt;/code&gt; to denote that it should be read as an array.)&lt;/p&gt;

&lt;p&gt;Now, we'll calculate the sizing for the fonts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;currentDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;currentYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;currentDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;baseFont&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ul li&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;font-size&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fontsplit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;baseFont&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;([&lt;/span&gt;&lt;span class="sr"&gt;0-9&lt;/span&gt;&lt;span class="se"&gt;\.]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)\s?([&lt;/span&gt;&lt;span class="sr"&gt;a-z&lt;/span&gt;&lt;span class="se"&gt;\%]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;minFont&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fontsplit&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;maxFont&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fontsplit&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fontUnits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fontsplit&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, we're getting the value of the current year since we want to have the program do the math on how long I've worked with a technology. If you're getting something like a number of blog posts or inventory count instead, you can skip that step!&lt;/p&gt;

&lt;p&gt;Then we get the base font size from the CSS. It comes with the units, so I've inserted a regular expression to match a number and a unit abbreviation. The current font size becomes the minimum font size for the tag cloud, assigned to &lt;code&gt;minFont&lt;/code&gt;; the maximum font size is the minimum times three. You can adjust these to taste—for example, if you want your minimum to be 80% of the base font size, you'd set &lt;code&gt;minFont = parseInt(fontsplit[1])*.8&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now it's time to actually apply the font sizes!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ul li&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;itemYear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;year&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;itemYear&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;currentYear&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;itemYear&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fontSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="nx"&gt;maxVal&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;itemYear&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;maxVal&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;minVal&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;maxFont&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;minFont&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;minFont&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;font-size&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fontSize&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;fontUnits&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentYear&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;itemYear&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; years&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// if we can't determine the year, just set it to 90% size&lt;/span&gt;
      &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;css&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;font-size&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;minFont&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;fontUnits&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;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First it performs a quick check to make sure that &lt;code&gt;data-year&lt;/code&gt; is actually set before trying to access it. Then we do a little math, subtracting the value of &lt;code&gt;data-year&lt;/code&gt; from the current year to determine the years experience (again, this step is skippable if you're not trying to determine years since).&lt;/p&gt;

&lt;p&gt;We determine the font size by figuring out what percentage the current number is between the minimum and maximum value, multiplying that by the difference between &lt;code&gt;maxFont&lt;/code&gt; and &lt;code&gt;minFont&lt;/code&gt;, and then adding that to &lt;code&gt;minFont&lt;/code&gt;. We then set the css &lt;code&gt;font-size&lt;/code&gt; value to that number and tack the units back on at the end.&lt;/p&gt;

&lt;p&gt;Also, just to make sure that the information is represented in a way that's accessible to non-visual media, we set the list item's title attribute to "[N] years."&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Product
&lt;/h2&gt;

&lt;p&gt;All of this adds up to a result that looks a bit like this!&lt;/p&gt;

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

&lt;p&gt;You can also see a live data version on &lt;a href="https://carlymho.com/" rel="noopener noreferrer"&gt;my personal website&lt;/a&gt; if you scroll down to the bottom.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>jquery</category>
    </item>
    <item>
      <title>Line-Based Truncation Methods</title>
      <dc:creator>Carly Ho 🌈</dc:creator>
      <pubDate>Wed, 25 Apr 2018 03:29:09 +0000</pubDate>
      <link>https://dev.to/carlymho/line-based-truncation-methods-51bk</link>
      <guid>https://dev.to/carlymho/line-based-truncation-methods-51bk</guid>
      <description>&lt;p&gt;I frequently get the request to truncate content excerpts on websites I build to a certain number of lines. While it sounds like a straightforward task, it’s difficult to implement for two main reasons: firstly, since we build websites to scale responsively to a variety of device sizes, we can’t assume that a content box will be the same width at any given screen size, and secondly, unless we’re using a monospace font, the number of lines any text will take up is dependent on the content, since in most fonts characters have different widths.&lt;/p&gt;

&lt;p&gt;Let’s take, for example, this snippet of code:&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;This is a really long heading that we’re going to need to truncate for the sake of the layout since it goes on for several lines.&lt;span class="nt"&gt;&amp;lt;/h3&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;“excerpt”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Cras dolor orci, mollis eget mi vel, faucibus malesuada velit. Phasellus egestas nec nisi non bibendum. Vestibulum faucibus mauris ac ipsum viverra volutpat. Sed lobortis justo sapien, eget ornare orci convallis ut. Nullam pulvinar, urna at faucibus dignissim, orci elit varius quam, non sodales lacus elit a nunc. Morbi eleifend velit quis tellus tempus, sed vehicula neque vulputate. Vestibulum sit amet tempus nibh, sit amet semper mi. Integer sit amet quam eget ligula luctus pulvinar at non ligula. Suspendisse a fringilla lorem, cursus sodales odio. Aliquam ac odio eget nulla consectetur dictum eu quis massa. Sed volutpat ante non felis condimentum vestibulum. In tempor tristique varius. Nunc est nunc, tincidunt quis metus et, semper molestie eros. &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="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;“readmore”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Read More&lt;span class="nt"&gt;&amp;lt;/a&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;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What are some approaches we can take?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  CSS-Based Clipping
&lt;/h3&gt;

&lt;p&gt;A very simple solution would be to use CSS to set a maximum height for the container that the text is inside. If we know the line-height, we can multiply that by the number of lines we want to show to get the height the box should be to clip it properly.&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="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;26px&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;52px&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;.content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&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="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="nl"&gt;max-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;72px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.content&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;margin&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This solution requires no javascript and therefore is very good for performance. You could also add a tiny amount of javascript to be able to reveal the hidden content by setting the max-height of the .content container to a height much longer than any content in it might be, such as 9999999px, which is also friendly to transition animations.&lt;/p&gt;

&lt;p&gt;However, if you need to include a “More” or “Continue” link at the end, or want to add an ellipsis to indicate that the text has been truncated, you’ll need something a little more robust, since this solution will hide the end of a segment that happens to be over the specified number of lines long.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Minimum performance change, no modification of markup needed&lt;br&gt;
&lt;strong&gt;Cons:&lt;/strong&gt; Can’t use readmore links or ellipses at the end of the text, specific to certain CSS selectors&lt;/p&gt;
&lt;h3&gt;
  
  
  Javascript-Based Clipping
&lt;/h3&gt;

&lt;p&gt;By using Javascript (and in this example, jQuery, although I’m sure you could write it without) to manipulate the HTML document, we can achieve more flexible results.&lt;/p&gt;

&lt;p&gt;In this case, if we know, the line-height of the element and it remains constant, we can separate out any readmore links, split the text by spaces, and then iterate over each word until we find that the content is now taller than the box we want to fit it to. We should also store the original text in an attribute so that we can update the excerpt when the container size changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="nx"&gt;resize&lt;/span&gt; &lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;lineHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// content's line-height&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// number of lines to show&lt;/span&gt;
        &lt;span class="c1"&gt;// only truncate if the text is longer than the desired size; if not, skip it&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;lineHeight&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a.readmore&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data-link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a.readmore&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// if there's a readmore link, separate it out and put it on a data attribute&lt;/span&gt;
                    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a.readmore&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;detach&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// remove the link from the HTML&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// set the text as the title attribute to preserve it&lt;/span&gt;
            &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// empty the content&lt;/span&gt;
            &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;prevstr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// split text into words&lt;/span&gt;
            &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data-link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;lineHeight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="c1"&gt;// if we've spilled over onto the next line, roll it back a word and break the loop&lt;/span&gt;
                    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prevstr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;hellip; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;undefined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
                    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="nx"&gt;prevstr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="c1"&gt;// update the working string with the next word&lt;/span&gt;
                &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="c1"&gt;// update the content in the document&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;hellip;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;undefined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="c1"&gt;// if the last iteration caused us to spill over a line, roll back one word&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;lineHeight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prevstr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;hellip; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;undefined&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&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;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;Pros:&lt;/strong&gt; Can maintain readmore links and ellipses&lt;br&gt;
&lt;strong&gt;Cons:&lt;/strong&gt; Specific to certain CSS selectors&lt;/p&gt;
&lt;h3&gt;
  
  
  Javascript Truncation on Arbitrary Items
&lt;/h3&gt;

&lt;p&gt;The above solution is pretty flexible, but needs to specify the line-height. What if we want to apply the solution to an arbitrary element, or what if this particular element has a different line-height specified at some CSS breakpoints?&lt;/p&gt;

&lt;p&gt;With many attributes one could just get the property, either from vanilla Javascript or by using the $(elt).css(“line-height”) method, but many browsers return the line-height value slightly differently, and, furthermore, we can’t guarantee what kind of units the line-height will be in.&lt;/p&gt;

&lt;p&gt;I wish I had a really easy brilliant solution that anyone can DIY, but I got very tired and just downloaded the &lt;a href="https://www.npmjs.com/package/line-height"&gt;line-height&lt;/a&gt; module and included it ahead of my own scripting. (The line-height module was, unsurprisingly, &lt;em&gt;also&lt;/em&gt; written to supplement a line-based truncation solution.)&lt;/p&gt;

&lt;p&gt;Using that, we can replace the static number assigned to the lineHeight variable with &lt;code&gt;window.lineHeight(this[0]);&lt;/code&gt;, which should return the line-height value in an easy-to-use way. At this point, this is pretty easy to turn into a custom function we can call with an element and a given number of lines, or even as a jQuery plugin we can use as a method on any element.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Maintains readmore links and ellipses, can be re-used easily&lt;br&gt;
&lt;strong&gt;Cons:&lt;/strong&gt; Uses an external library for line-height&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo!
&lt;/h2&gt;

&lt;p&gt;And here's the whole thing put together in a Codepen demo, with everything wrapped into a jQuery plugin:&lt;/p&gt;

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

</description>
      <category>javascript</category>
      <category>css</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>The Hardest Thing is to Keep Going</title>
      <dc:creator>Carly Ho 🌈</dc:creator>
      <pubDate>Thu, 08 Mar 2018 00:52:20 +0000</pubDate>
      <link>https://dev.to/carlymho/the-hardest-thing-is-to-keep-going--27ee</link>
      <guid>https://dev.to/carlymho/the-hardest-thing-is-to-keep-going--27ee</guid>
      <description>&lt;p&gt;Or: to my younger self, with love.&lt;/p&gt;

&lt;p&gt;Listen: things will be hard, and then they will be easy, and then they will get hard again, because you have earned the skills to imagine the ways in which you can be better. Even when you're learning you'll think: wasn't this easier to take in before? And maybe it was, or maybe you're learning harder and harder things.&lt;/p&gt;

&lt;p&gt;Sometimes impostor syndrome comes from within—not in comparing to your co-workers and classmates and the Silicon Valley luminaries you followed on Twitter, but in comparing yourself to you as you were when you were ten years old and burning with the enthusiasm of someone discovering her new world and the way she could impose her will upon it, or even you as you just thought you'd be by now. We often have the least patience for ourselves.&lt;/p&gt;

&lt;p&gt;Keep learning, and try not to lock yourself into the futures you can see yourself in now. You don't think you could ever be a manager, but those skills are things that will come to you easier with practice, too, just like code, and those skills are just as important. To be able to estimate, to have confidence in your implementation ideas, to be able to communicate—those are things that demonstrate mastery of craft, too. But it's okay not to force it before you're ready, too.&lt;/p&gt;

&lt;p&gt;The tools you use may change and the people you work with may change, but what won’t change is that this work is something that calls to you and drives you to be your best self in a way that will, someday, make you feel like an expert. Someday you’ll &lt;em&gt;be&lt;/em&gt; an expert. Someday you’ll feel confident saying “I don’t know, but I’m sure I can figure it out” and it’ll be true.&lt;/p&gt;

&lt;p&gt;When you can’t see what lies ahead of you with any certainty or any knowledge of payoff, the hardest thing is to keep going. What I can tell you is that if you keep going, if you find friends and peers and mentors to support you (and you will) and take care of yourself (it helps, I promise), you’ll eventually find yourself in a place where you realize that you have everything that you need.&lt;/p&gt;

&lt;p&gt;There will be days when everything feels like it’s fine and you’ll feel fulfilled by your work and still feel like you’d prefer to just lie down because (for better or for worse) you're not a formless energy cloud of programming knowledge and your body has just decided to rebel. Sometimes work will be great but some dude you’ve never even heard of somewhere across the country will unleash a waterfall of hot takes about whether people like you should be programmers and you’ll just feel &lt;em&gt;so very tired&lt;/em&gt;. Give yourself a break, do what you need to get back on your feet. The needs of the mind and the body are needs you’re allowed to have. The productivity can come later. You have plenty of time yet.&lt;/p&gt;

&lt;p&gt;You’ll never be done learning or improving, and you’ll never get a trophy that says you get to be done and that everything will be perfect smooth sailing from here on out. But like all hard things, carrying on gets easier with practice.&lt;/p&gt;

</description>
      <category>wecoded</category>
    </item>
  </channel>
</rss>
