Who sponsors Drupal development? (2018-2019 edition)

The past years, I've examined Drupal.org's contribution data to understand who develops Drupal, how diverse the Drupal community is, how much of Drupal's maintenance and innovation is sponsored, and where that sponsorship comes from.

You can look at the 2016 report, the 2017 report, and the 2018 report. Each report looks at data collected in the 12-month period between July 1st and June 30th.

This year's report shows that:

Both the recorded number of contributors and contributions have increased.
Most contributions are sponsored, but volunteer contributions remains very important to Drupal's success.
Drupal's maintenance and innovation depends mostly on smaller Drupal agencies and Acquia. Hosting companies, multi-platform digital marketing agencies, large system integrators and end users make fewer contributions to Drupal.
Drupal's contributors have become more diverse, but are still not diverse enough.
Methodology

What are Drupal.org issues?

"Issues" are pages on Drupal.org. Each issue tracks an idea, feature request, bug report, task, or more. See https://www.drupal.org/project/issues for the list of all issues.

For this report, we looked at all Drupal.org issues marked "closed" or "fixed" in the 12-month period from July 1, 2018 to June 30, 2019. The issues analyzed in this report span Drupal core and thousands of contributed projects, across all major versions of Drupal.

What are Drupal.org credits?

In the spring of 2015, after proposing initial ideas for giving credit, Drupal.org added the ability for people to attribute their work in the Drupal.org issues to an organization or customer, or mark it the result of volunteer efforts.

A screenshot of an issue comment on Drupal.org. You can see that jamadar worked on this patch as a volunteer, but also as part of his day job working for TATA Consultancy Services on behalf of their customer, Pfizer.
Drupal.org's credit system is truly unique and groundbreaking in Open Source and provides unprecedented insights into the inner workings of a large Open Source project. There are a few limitations with this approach, which we'll address at the end of this report.

What is the Drupal community working on?

In the 12-month period between July 1, 2018 and June 30, 2019, 27,522 issues were marked "closed" or "fixed", a 13% increase from the 24,447 issues in the 2017-2018 period.

In total, the Drupal community worked on 3,474 different Drupal.org projects this year compared to 3,229 projects in the 2017-2018 period — an 8% year over year increase.

The majority of the credits are the result of work on contributed modules:

Compared to the previous period, contribution credits increased across all project types:

The most notable change is the large jump in "non-product credits": more and more members in the community started tracking credits for non-product activities such as organizing Drupal events (e.g. DrupalCamp Delhi project, Drupal Developer Days, Drupal Europe and DrupalCon Europe), promoting Drupal (e.g. Drupal pitch deck or community working groups (e.g. Drupal Diversity and Inclusion Working Group, Governance Working Group).

While some of these increases reflect new contributions, others are existing contributions that are newly reported. All contributions are valuable, whether they're code contributions, or non-product and community-oriented contributions such as organizing events, giving talks, leading sprints, etc. The fact that the credit system is becoming more accurate in recognizing more types of Open Source contribution is both important and positive.

Who is working on Drupal?

For this report's time period, Drupal.org's credit system received contributions from 8,513 different individuals and 1,137 different organizations — a meaningful increase from last year's report.

Consistent with previous years, approximately 51% of the individual contributors received just one credit. Meanwhile, the top 30 contributors (the top 0.4%) account for 19% of the total credits. In other words, a relatively small number of individuals do the majority of the work. These individuals put an incredible amount of time and effort into developing Drupal and its contributed projects:

RankUsernameIssues1kiamlaluno16102jrockowitz7563alexpott6424RajabNatshah6165volkswagenchick5196bojanz5047alonaoneill4898thalles4889Wim Leers43710DamienMcKenna43111Berdir42412chipway35613larowlan32414pifagor32015catch31316mglaman27717adci_contributor27418quietone26619tim.plunkett26520gaurav.kapoor25321RenatoG24622heddn24323chr.fritsch24124xjm23825phenaproxima23826mkalkbrenner23527gvso23228dawehner21929e0ipso21830drumm205Out of the top 30 contributors featured this year, 28 were active contributors in the 2017-2018 period as well. These Drupalists' dedication and continued contribution to the project has been crucial to Drupal's development.

It's also important to recognize that most of the top 30 contributors are sponsored by an organization. Their sponsorship details are provided later in this article. We value the organizations that sponsor these remarkable individuals, because without their support, it could be more challenging for these individuals to be in the top 30.

It's also nice to see two new contributors make the top 30 this year — Alona O'neill with sponsorship from Hook 42 and Thalles Ferreira with sponsorship from CI&T. Most of their credits were the result of smaller patches (e.g. removing deprecated code, fixing coding style issues, etc) or in some cases non-product credits rather than new feature development or fixing complex bugs. These types of contributions are valuable and often a stepping stone towards towards more in-depth contribution.
How much of the work is sponsored?

Issue credits can be marked as "volunteer" and "sponsored" simultaneously (shown in jamadar's screenshot near the top of this post). This could be the case when a contributor does the necessary work to satisfy the customer's need, in addition to using their spare time to add extra functionality.

For those credits with attribution details, 18% were "purely volunteer" credits (8,433 credits), in stark contrast to the 65% that were "purely sponsored" (29,802 credits). While there are almost four times as many "purely sponsored" credits as "purely volunteer" credits, volunteer contribution remains very important to Drupal.

Both "purely volunteer" and "purely sponsored" credits grew — "purely sponsored" credits grew faster in absolute numbers, but for the first time in four years "purely volunteer" credits grew faster in relative numbers.

The large jump in volunteer credits can be explained by the community capturing more non-product contributions. As can be seen on the graph below, these non-product contributions are more volunteer-centric.

Who is sponsoring the work?

Now that we've established that the majority of contributions to Drupal are sponsored, let's study which organizations contribute to Drupal. While 1,137 different organizations contributed to Drupal, approximately 50% of them received four credits or less. The top 30 organizations (roughly the top 3%) account for approximately 25% of the total credits, which implies that the top 30 companies play a crucial role in the health of the Drupal project.

Top contributing organizations based on the number of issue credits.While not immediately obvious from the graph above, a variety of different types of companies are active in Drupal's ecosystem:

Category
Description
Traditional Drupal businesses
Small-to-medium-sized professional services companies that primarily make money using Drupal. They typically employ fewer than 100 employees, and because they specialize in Drupal, many of these professional services companies contribute frequently and are a huge part of our community. Examples are Hook42, Centarro, The Big Blue House, Vardot, etc.
Digital marketing agencies
Larger full-service agencies that have marketing-led practices using a variety of tools, typically including Drupal, Adobe Experience Manager, Sitecore, WordPress, etc. They tend to be larger, with many of the larger agencies employing thousands of people. Examples are Wunderman, Possible and Mirum.
System integrators
Larger companies that specialize in bringing together different technologies into one solution. Example system agencies are Accenture, TATA Consultancy Services, Capgemini and CI&T.
Hosting companies
Examples are Acquia, Rackspace, Pantheon and Platform.sh.
End users
Examples are Pfizer or bio.logis Genetic Information Management GmbH.
A few observations:

Almost all of the sponsors in the top 30 are traditional Drupal businesses with fewer than 50 employees. Only five companies in the top 30 — Pfizer, Google, CI&T, bio.logis and Acquia — are not traditional Drupal businesses. The traditional Drupal businesses are responsible for almost 80% of all the credits in the top 30. This percentage goes up if you extend beyond the top 30. It's fair to say that Drupal's maintenance and innovation largely depends on these traditional Drupal businesses.
The larger, multi-platform digital marketing agencies are barely contributing to Drupal. While more and more large digital agencies are building out Drupal practices, no digital marketing agencies show up in the top 30, and hardly any appear in the entire list of contributing organizations. While they are not required to contribute, I'm frustrated that we have not yet found the right way to communicate the value of contribution to these companies. We need to incentivize each of these firms to contribute back with the same commitment that we see from traditional Drupal businesses
The only system integrator in the top 30 is CI&T, which ranked 4th with 795 credits. As far as system integrators are concerned, CI&T is a smaller player with approximately 2,500 employees. However, we do see various system integrators outside of the top 30, including Globant, Capgemini, Sapient and TATA Consultancy Services. In the past year, Capgemini almost quadrupled their credits from 46 to 196, TATA doubled its credits from 85 to 194, Sapient doubled its credits from 28 to 65, and Globant kept more or less steady with 41 credits. Accenture and Wipro do not appear to contribute despite doing a fair amount of Drupal work in the field.
Hosting companies also play an important role in our community, yet only Acquia appears in the top 30. Rackspace has 68 credits, Pantheon has 43, and Platform.sh has 23. I looked for other hosting companies in the data, but couldn't find any. In general, there is a persistent problem with hosting companies that make a lot of money with Drupal not contributing back. The contribution gap between Acquia and other hosting companies has increased, not decreased.
We also saw three end users in the top 30 as corporate sponsors: Pfizer (453 credits), Thunder (659 credits, up from 432 credits the year before), and the German company, bio.logis (330 credits). A notable end user is Johnson & Johnson, who was just outside of the top 30, with 221 credits, up from 29 credits the year before. Other end users outside of the top 30, include the European Commission (189 credits), Workday (112 credits), Paypal (80 credits), NBCUniversal (48 credits), Wolters Kluwer (20 credits), and Burda Media (24 credits). We also saw contributions from many universities, including the University of British Columbia (148 credits), University of Waterloo (129 credits), Princeton University (73 credits), University of Austin Texas at Austin (57 credits), Charles Darwin University (24 credits), University of Edinburgh (23 credits), University of Minnesota (19 credits) and many more.

It would be interesting to see what would happen if more end users mandated contributions from their partners. Pfizer, for example, only works with agencies that contribute back to Drupal, and uses Drupal's credit system to verify their vendors' claims. The State of Georgia started doing the same; they also made Open Source contribution a vendor selection criteria. If more end users took this stance, it could have a big impact on the number of digital agencies, hosting companies and system integrators that contribute to Drupal.

While we should encourage more organizations to sponsor Drupal contributions, we should also understand and respect that some organizations can give more than others and that some might not be able to give back at all. Our goal is not to foster an environment that demands what and how others should give back. Instead, we need to help foster an environment worthy of contribution. This is clearly laid out in Drupal's Values and Principles.

How diverse is Drupal?

Supporting diversity and inclusion within Drupal is essential to the health and success of the project. The people who work on Drupal should reflect the diversity of people who use and work with the web.

I looked at both the gender and geographic diversity of Drupal.org contributors. While these are only two examples of diversity, these are the only diversity characteristics we currently have sufficient data for. Drupal.org recently rolled out support for Big 8/Big 10, so next year we should have more demographics information

Gender diversity

The data shows that only 8% of the recorded contributions were made by contributors who do not identify as male, which continues to indicate a wide gender gap. This is a one percent increase compared to last year. The gender imbalance in Drupal is profound and underscores the need to continue fostering diversity and inclusion in our community.

Last year I wrote a post called about the privilege of free time in Open Source. It made the case that Open Source is not a meritocracy, because not everyone has equal amounts of free time to contribute. For example, research shows that women still spend more than double the time as men doing unpaid domestic work, such as housework or childcare. This makes it more difficult for women to contribute to Open Source on an unpaid, volunteer basis. It's one of the reasons why Open Source projects suffer from a lack of diversity, among others including hostile environments and unconscious biases. Drupal.org's credit data unfortunately still shows a big gender disparity in contributions:

Ideally, over time, we can collect more data on non-binary gender designations, as well as segment some of the trends behind contributions by gender. We can also do better at collecting data on other systemic issues beyond gender alone. Knowing more about these trends can help us close existing gaps. In the meantime, organizations capable of giving back should consider financially sponsoring individuals from underrepresented groups to contribute to Open Source. Each of us needs to decide if and how we can help give time and opportunities to underrepresented groups and how we can create equity for everyone in Drupal.
Geographic diversity

When measuring geographic diversity, we saw individual contributors from six continents and 114 countries:

Contribution credits per capita calculated as the amount of contributions per continent divided by the population of each continent. 0.001% means that one in 100,000 people contribute to Drupal. In North America, 5 in 100,000 people contributed to Drupal the last year.Contributions from Europe and North America are both on the rise. In absolute terms, Europe contributes more than North America, but North America contributes more per capita.

Asia, South America and Africa remain big opportunities for Drupal, as their combined population accounts for 6.3 billion out of 7.5 billion people in the world. Unfortunately, the reported contributions from Asia are declining year over year. For example, compared to last year's report, there was a 17% drop in contribution from India. Despite that drop, India remains the second largest contributor behind the United States:

The top 20 countries from which contributions originate. The data is compiled by aggregating the countries of all individual contributors behind each issue. Note that the geographical location of contributors doesn't always correspond with the origin of their sponsorship. Wim Leers, for example, works from Belgium, but his funding comes from Acquia, which has the majority of its customers in North America.Top contributor details

To create more awareness of which organizations are sponsoring the top individual contributors, I included a more detailed overview of the top 50 contributors and their sponsors. If you are a Drupal developer looking for work, these are some of the companies I'd apply to first. If you are an end user looking for a company to work with, these are some of the companies I'd consider working with first. Not only do they know Drupal well, they also help improve your investment in Drupal.

Rank
Username
Issues
Volunteer
Sponsored
Not specified
Sponsors
1
kiamlaluno
1610
99%
0%
1%

2
jrockowitz
756
98%
99%
0%
The Big Blue House (750), Memorial Sloan Kettering Cancer Center (5), Rosewood Marketing (1)
3
alexpott
642
6%
80%
19%
Thunder (336), Acro Media Inc (100), Chapter Three (77)
4
RajabNatshah
616
1%
100%
0%
Vardot (730), Webship (2)
5
volkswagenchick
519
2%
99%
0%
Hook 42 (341), Kanopi Studios (171)
6
bojanz
504
0%
98%
2%
Centarro (492), Ny Media AS (28), Torchbox (5), Liip (2), Adapt (2)
7
alonaoneill
489
9%
99%
0%
Hook 42 (484)
8
thalles
488
0%
100%
0%
CI&T (488), Janrain (3), Johnson & Johnson (2)
9
Wim Leers
437
8%
97%
0%
Acquia (421), Government of Flanders (3)
10
DamienMcKenna
431
0%
97%
3%
Mediacurrent (420)
11
Berdir
424
0%
92%
8%
MD Systems (390)
12
chipway
356
0%
100%
0%
Chipway (356)
13
larowlan
324
16%
94%
2%
PreviousNext (304), Charles Darwin University (22), University of Technology, Sydney (3), Service NSW (2), Department of Justice & Regulation, Victoria (1)
14
pifagor
320
52%
100%
0%
GOLEMS GABB (618), EPAM Systems (16), Drupal Ukraine Community (6)
15
catch
313
1%
95%
4%
Third & Grove (286), Tag1 Consulting (11), Drupal Association (6), Acquia (4)
16
mglaman
277
2%
98%
1%
Centarro (271), Oomph, Inc. (16), E.C. Barton & Co (3), Gaggle.net, Inc. (1), Bluespark (1), Thinkbean (1), LivePerson, Inc (1), Impactiv, Inc. (1), Rosewood Marketing (1), Acro Media Inc (1)
17
adci_contributor
274
0%
100%
0%
ADCI Solutions (273)
18
quietone
266
41%
75%
1%
Acro Media Inc (200)
19
tim.plunkett
265
3%
89%
9%
Acquia (235)
20
gaurav.kapoor
253
0%
51%
49%
OpenSense Labs (129), DrupalFit (111)
21
RenatoG
246
0%
100%
0%
CI&T (246), Johnson & Johnson (85)
22
heddn
243
2%
98%
2%
MTech, LLC (202), Tag1 Consulting (32), European Commission (22), North Studio (3), Acro Media Inc (2)
23
chr.fritsch
241
0%
99%
1%
Thunder (239)
24
xjm
238
0%
85%
15%
Acquia (202)
25
phenaproxima
238
0%
100%
0%
Acquia (238)
26
mkalkbrenner
235
0%
100%
0%
bio.logis Genetic Information Management GmbH (234), OSCE: Organization for Security and Co-operation in Europe (41), Welsh Government (4)
27
gvso
232
0%
100%
0%
Google Summer of Code (214), Google Code-In (16), Zivtech (1)
28
dawehner
219
39%
84%
8%
Chapter Three (176), Drupal Association (5), Tag1 Consulting (3), TES Global (1)
29
e0ipso
218
99%
100%
0%
Lullabot (217), IBM (23)
30
drumm
205
0%
98%
1%
Drupal Association (201)
31
gabesullice
199
0%
100%
0%
Acquia (198), Aten Design Group (1)
32
amateescu
194
0%
97%
3%
Pfizer, Inc. (186), Drupal Association (1), Chapter Three (1)
33
klausi
193
2%
59%
40%
jobiqo - job board technology (113)
34
samuel.mortenson
187
42%
42%
17%
Acquia (79)
35
joelpittet
187
28%
78%
14%
The University of British Columbia (146)
36
borisson_
185
83%
50%
3%
Calibrate (79), Dazzle (13), Intracto digital agency (1)
37
Gábor Hojtsy
184
0%
97%
3%
Acquia (178)
38
adriancid
182
91%
22%
2%
Drupiter (40)
39
eiriksm
182
0%
100%
0%
Violinist (178), Ny Media AS (4)
40
yas
179
12%
80%
10%
DOCOMO Innovations, Inc. (143)
41
TR
177
0%
0%
100%

42
hass
173
1%
0%
99%

43
Joachim Namyslo
172
69%
0%
31%

44
alex_optim
171
0%
99%
1%
GOLEMS GABB (338)
45
flocondetoile
168
0%
99%
1%
Flocon de toile (167)
46
Lendude
168
52%
99%
0%
Dx Experts (91), ezCompany (67), Noctilaris (9)
47
paulvandenburg
167
11%
72%
21%
ezCompany (120)
48
voleger
165
98%
98%
2%
GOLEMS GABB (286), Lemberg Solutions Limited (36), Drupal Ukraine Community (1)
49
lauriii
164
3%
98%
1%
Acquia (153), Druid (8), Lääkärikeskus Aava Oy (2)
50
idebr
162
0%
99%
1%
ezCompany (156), One Shoe (5)
Limitations of the credit system

It is important to note a few of the current limitations of Drupal.org's credit system:

The credit system doesn't capture all code contributions. Parts of Drupal are developed on GitHub rather than Drupal.org, and often aren't fully credited on Drupal.org. For example, Drush is maintained on GitHub instead of Drupal.org, and companies like Pantheon don't get credit for that work. The Drupal Association is working to integrate GitLab with Drupal.org. GitLab will provide support for "merge requests", which means contributing to Drupal will feel more familiar to the broader audience of Open Source contributors who learned their skills in the post-patch era. Some of GitLab's tools, such as in-line editing and web-based code review will also lower the barrier to contribution, and should help us grow both the number of contributions and contributors on Drupal.org.
The credit system is not used by everyone. There are many ways to contribute to Drupal that are still not captured in the credit system, including things like event organizing or providing support. Technically, that work could be captured as demonstrated by the various non-product initiatives highlighted in this post. Because using the credit system is optional, many contributors don't. As a result, contributions often have incomplete or no contribution credits. We need to encourage all Drupal contributors to use the credit system, and raise awareness of its benefits to both individuals and organizations. Where possible, we should automatically capture credits. For example, translation efforts on https://localize.drupal.org are not currently captured in the credit system but could be automatically.
The credit system disincentives work on complex issues. We currently don't have a way to account for the complexity and quality of contributions; one person might have worked several weeks for just one credit, while another person might receive a credit for 10 minutes of work. We certainly see a few individuals and organizations trying to game the credit system. In the future, we should consider issuing credit data in conjunction with issue priority, patch size, number of reviews, etc. This could help incentivize people to work on larger and more important problems and save smaller issues such as coding standards improvements for new contributor sprints. Implementing a scoring system that ranks the complexity of an issue would also allow us to develop more accurate reports of contributed work.
All of this means that the actual number of contributions and contributors could be significantly higher than what we report.

Like Drupal itself, the Drupal.org credit system needs to continue to evolve. Ultimately, the credit system will only be useful when the community uses it, understands its shortcomings, and suggests constructive improvements.

A first experiment with weighing credits

As a simple experiment, I decided to weigh each credit based on the adoption of the project the credit is attributed to. For example, each contribution credit to Drupal core is given a weight of 11 because Drupal core has about 1,1 million active installations. Credits to the Webform module, which has over 400,000 installations, get a weight of 4. And credits to Drupal's Commerce project gets just 1 point as it is installed on fewer than 100,000 sites.

The idea is that these weights capture the end user impact of each contribution, but also act as a proxy for the effort required to get a change committed. Getting a change accepted in Drupal core is both more difficult and more impactful than getting a change accepted to Commerce project.

This weighting is far from perfect as it undervalues non-product contributions, and it still doesn't recognize all types of product contributions (e.g. product strategy work, product management work, release management work, etc). That said, for code contributions, it may be more accurate than a purely unweighted approach.

The top 30 contributing individuals based on weighted Drupal.org issue credits.The top 30 contributing organizations based on weighted Drupal.org issue credits.

Conclusions

Our data confirms that Drupal is a vibrant community full of contributors who are constantly evolving and improving the software. It's amazing to see that just in the last year, Drupal welcomed more than 8,000 individuals contributors and over 1,100 corporate contributors. It's especially nice to see the number of reported contributions, individual contributors and organizational contributors increase year over year.

To grow and sustain Drupal, we should support those that contribute to Drupal and find ways to get those that are not contributing involved in our community. Improving diversity within Drupal is critical, and we should welcome any suggestions that encourage participation from a broader range of individuals and organizations.
Source: Dries Buytaert www.buytaert.net


Low-code and no-code tools continue to drive the web forward

A version of this article was originally published on Devops.com.

Twelve years ago, I wrote a post called Drupal and Eliminating Middlemen. For years, it was one of the most-read pieces on my blog. Later, I followed that up with a blog post called The Assembled Web, which remains one of the most read posts to date.

The point of both blog posts was the same: I believed that the web would move toward a model where non-technical users could assemble their own sites with little to no coding experience of their own.

This idea isn't new; no-code and low-code tools on the web have been on a 25-year long rise, starting with the first web content management systems in the early 1990s. Since then no-code and low-code solutions have had an increasing impact on the web. Examples include:

WYSIWYG site-builders like Wix and Squarespace
WordPress' Gutenberg
Drupal's new Layout Builder
While this has been a long-run trend, I believe we're only at the beginning.

Trends driving the low-code and no-code movements

According to Forrester Wave: Low-Code Development Platforms for AD&D Professionals, Q1 2019, In our survey of global developers, 23% reported using low-code platforms in 2018, and another 22% planned to do so within a year..

Major market forces driving this trend include a talent shortage among developers, with an estimated one million computer programming jobs expected to remain unfilled by 2020 in the United States alone.

What is more, the developers who are employed are often overloaded with work and struggle with how to prioritize it all. Some of this burden could be removed by low-code and no-code tools.

In addition, the fact that technology has permeated every aspect of our lives — from our smartphones to our smart homes — has driven a desire for more people to become creators. As the founder of Product Hunt Ryan Hoover said in a blog post: As creating things on the internet becomes more accessible, more people will become makers..

But this does not only apply to individuals. Consider this: the typical large organization has to build and maintain hundreds of websites. They need to build, launch and customize these sites in days or weeks, not months. Today and in the future, marketers can embrace no-code and low-code tools to rapidly develop websites.

Abstraction drives innovation

As discussed in my middleman blog post, developers won't go away. Just as the role of the original webmaster has evolved with the advent of web content management systems, the role of web developers is changing with the rise of low-code and no-code tools.

Successful no-code approaches abstract away complexity for web development. This enables less technical people to do things that previously could only by done by developers. And when those abstractions happen, developers often move on to the next area of innovation.

When everyone is a builder, more good things will happen on the web. I was excited about this trend more than 12 years ago, and remain excited today. I'm eager to see the progress no-code and low-code solutions will bring to the web in the next decade.
Source: Dries Buytaert www.buytaert.net


Drupal Display Modes: How to Make the Most Out of Them

Start: 
2019-02-07 18:30 - 20:00 Europe/Sofia

Organizers: 

marie77e

anna.radulovski

Event type: 

Training (free or commercial)

https://www.coding-girls.com/drupal-display-modes-how-make-most-out-them

WHAT IS THE EVENT ABOUT?
This event is part of the Drupal Global Training Days initiative. During this session we are going to dig in deeper into the content entities' view & form modes and explore different scenarios on their usage.
WHAT WILL WE DO EXACTLY?
We will work with entity reference fields & the Views module to see how to request the same content item to be rendered in various ways. Join us in this workshop and let's explore together how to work easily and successfully with nodes, blocks, media and paragraphs.
WHO IS IT FOR?
No matter whether you are a total beginner or have some previous experience in Drupal, this session is a good exercise that will provide you with practical examples.
WHO WILL BE LEADING THE WORKSHOP?
Maria Totova is a Drupal developer at Trio-Group, a core engineer, education manager & instructor at Coding Girls, a co-founder of Drupal Girls and a board member of Drupal Bulgaria. Her passion for studying both arts and science has defined her professional path.
HOW MUCH?
The event is totally FREE but the seats are limited, so please register on time if you would like to attend! See you there!

AttachmentSize

drupal_training.jpg998.12 KB


Source: https://groups.drupal.org/node/512931/feed


Who sponsors Drupal development? (2017-2018 edition)

For the past two years, I've examined Drupal.org's commit data to understand who develops Drupal, how much of that work is sponsored, and where that sponsorship comes from.

I have now reported on this data for three years in a row, which means I can start to better compare year-over-year data. Understanding how an open-source project works is important because it establishes a benchmark for project health and scalability.

I would also recommend taking a look at the 2016 report or the 2017 report. Each report looks at data collected in the 12-month period between July 1st and June 30th.

This year's report affirms that Drupal has a large and diverse community of contributors. In the 12-month period between July 1, 2017 and June 30, 2018, 7,287 different individuals and 1,002 different organizations contributed code to Drupal.org. This include contributions to Drupal core and all contributed projects on Drupal.org.

In comparison to last year's report, both the number of contributors and contributions has increased. Our community of contributors (including both individuals and organizations) is also becoming more diverse. This is an important area of growth, but there is still work to do.

For this report, we looked at all of the issues marked "closed" or "fixed" in our ticketing system in the 12-month period from July 1, 2017 to June 30, 2018. This includes Drupal core and all of the contributed projects on Drupal.org, across all major versions of Drupal. This year, 24,447 issues were marked "closed" or "fixed", a 5% increase from the 23,238 issues in the 2016-2017 period. This averages out to 67 feature improvements or bug fixes a day.

In total, we captured 49,793 issue credits across all 24,447 issues. This marks a 17% increase from the 42,449 issue credits recorded in the previous year. Of the 49,793 issue credits reported this year, 18% (8,822 credits) were for Drupal core, while 82% (40,971 credits) went to contributed projects.

"Closed" or "fixed" issues are often the result of multiple people working on the issue. We try to capture who contributes through Drupal.org's unique credit system. We used the data from the credit system for this analysis. There are a few limitations with this approach, which we'll address at the end of this report.

What is the Drupal.org credit system?

In the spring of 2015, after proposing ideas for giving credit and discussing various approaches at length, Drupal.org added the ability for people to attribute their work to an organization or customer in the Drupal.org issue queues. Maintainers of Drupal modules, themes, and distributions can award issue credits to people who help resolve issues with code, translations, documentation, design and more.

A screenshot of an issue comment on Drupal.org. You can see that jamadar worked on this patch as a volunteer, but also as part of his day job working for TATA Consultancy Services on behalf of their customer, Pfizer.
Credits are a powerful motivator for both individuals and organizations. Accumulating credits provides individuals with a way to showcase their expertise. Organizations can utilize credits to help recruit developers, to increase their visibility within the Drupal.org marketplace, or to showcase their Drupal expertise.

Who is working on Drupal?

In the 12-month period between July 1, 2017 to June 30, 2018, 24,447, Drupal.org received code contributions from 7,287 different individuals and 1,002 different organizations.

While the number of individual contributors rose, a relatively small number of individuals still do the majority of the work. Approximately 48% of individual contributors received just one credit. Meanwhile, the top 30 contributors (the top 0.4%) account for more than 24% of the total credits. These individuals put an incredible amount of time and effort in developing Drupal and its contributed projects:

RankUsernameIssues1RenatoG8512RajabNatshah7453jrockowitz7004adriancid5295bojanz5156Berdir4327alexpott4148mglaman4149Wim Leers39510larowlan36011DamienMcKenna35312dawehner34013catch33914heddn32715xjm30316pifagor28417quietone26118borisson_25519adci_contributor25520volkswagenchick25421drunken monkey23122amateescu22523joachim19924mkalkbrenner19525chr.fritsch18526gaurav.kapoor17827phenaproxima17728mikeytown217329joelpittet17030timmillwood169Out of the top 30 contributors featured, 15 were also recognized as top contributors in our 2017 report. These Drupalists' dedication and continued contribution to the project has been crucial to Drupal's development. It's also exciting to see 15 new names on the list. This mobility is a testament to the community's evolution and growth. It's also important to recognize that a majority of the 15 repeat top contributors are at least partially sponsored by an organization. We value the organizations that sponsor these remarkable individuals, because without their support, it could be more challenging to be in the top 30 year over year.

How diverse is Drupal?

Next, we looked at both the gender and geographic diversity of Drupal.org code contributors. While these are only two examples of diversity, this is the only available data that contributors can currently choose to share on their Drupal.org profiles. The reported data shows that only 7% of the recorded contributions were made by contributors that do not identify as male, which continues to indicates a steep gender gap. This is a one percent increase compared to last year. The gender imbalance in Drupal is profound and underscores the need to continue fostering diversity and inclusion in our community.

To address this gender gap, in addition to advancing representation across various demographics, the Drupal community is supporting two important initiatives. The first is to adopt more inclusive user demographic forms on Drupal.org. Adopting Open Demographics on Drupal.org will also allow us to improve reporting on diversity and inclusion, which in turn will help us better support initiatives that advance diversity and inclusion. The second initiative is supporting the Drupal Diversity and Inclusion Contribution Team, which works to better include underrepresented groups to increase code and community contributions. The DDI Contribution Team recruits team members from diverse backgrounds and underrepresented groups, and provides support and mentorship to help them contribute to Drupal.

It's important to reiterate that supporting diversity and inclusion within Drupal is essential to the health and success of the project. The people who work on Drupal should reflect the diversity of people who use and work with the software. While there is still a lot of work to do, I'm excited about the impact these various initiatives will have on future reports.

When measuring geographic diversity, we saw individual contributors from 6 different continents and 123 different countries:

The top 20 countries from which contributions originate. The data is compiled by aggregating the countries of all individual contributors behind each commit. Note that the geographical location of contributors doesn't always correspond with the origin of their sponsorship. Wim Leers, for example, works from Belgium, but his funding comes from Acquia, which has the majority of its customers in North America.
123 different countries is seven more compared to the 2017 report. The new countries include Rwanda, Namibia, Senegal, Sierra Leone, and Swaziland, Zambia. Seeing contributions from more African countries is certainly a highlight.

How much of the work is sponsored?

Issue credits can be marked as "volunteer" and "sponsored" simultaneously (shown in jamadar's screenshot near the top of this post). This could be the case when a contributor does the minimum required work to satisfy the customer's need, in addition to using their spare time to add extra functionality.

While Drupal started out as a 100% volunteer-driven project, today the majority of the code on Drupal.org is sponsored by organizations. Only 12% of the commit credits that we examined in 2017-2018 were "purely volunteer" credits (6,007 credits), in stark contrast to the 49% that were "purely sponsored". In other words, there were four times as many "purely sponsored" credits as "purely volunteer" credits.

A few comparisons between the 2017-2018 and the 2016-2017 data:

The credit system is being used more frequently. In total, we captured 49,793 issue credits across all 24,447 issues in the 2017-2018 period. This marks a 17% increase from the 42,449 issue credits recorded in the previous year. Between July 1, 2016 and June 30, 2017, 28% of all credits had no attribution while in the period between July 1, 2017 to June 30, 2018, only 25% of credits lacked attribution. More people have become aware of the credit system, the attribution options, and their benefits.
Sponsored credits are growing faster than volunteer credits. Both "purely volunteer" and "purely sponsored" credits grew, but "purely sponsored" credits grew faster. There are two reasons why this could be the case: (1) more contributions are sponsored and (2) organizations are more likely to use the credit system compared to volunteers.
No data is perfect, but it feels safe to conclude that most of the work on Drupal is sponsored. At the same time, the data shows that volunteer contribution remains very important to Drupal. Maybe most importantly, while the number of volunteers and sponsors has grown year over year in absolute terms, sponsored contributions appear to be growing faster than volunteer contributions. This is consistent with how open source projects grow and scale.

Who is sponsoring the work?

Now that we've established a majority of contributions to Drupal are sponsored, we want to study which organizations contribute to Drupal. While 1,002 different organizations contributed to Drupal, approximately 50% of them received four credits or less. The top 30 organizations (roughly the top 3%) account for approximately 48% of the total credits, which implies that the top 30 companies play a crucial role in the health of the Drupal project. The graph below shows the top 30 organizations and the number of credits they received between July 1, 2017 and June 30, 2018:

The top 30 contributing organizations based on the number of Drupal.org commit credits.
While not immediately obvious from the graph above, a variety of different types of companies are active in Drupal's ecosystem:

Category
Description
Traditional Drupal businesses
Small-to-medium-sized professional services companies that primarily make money using Drupal. They typically employ fewer than 100 employees, and because they specialize in Drupal, many of these professional services companies contribute frequently and are a huge part of our community. Examples are Chapter Three and Lullabot (both shown on graph).
Digital marketing agencies
Larger full-service agencies that have marketing-led practices using a variety of tools, typically including Drupal, Adobe Experience Manager, Sitecore, WordPress, etc. They tend to be larger, with the larger agencies employing thousands of people. Examples are Wunderman and Mirum.
System integrators
Larger companies that specialize in bringing together different technologies into one solution. Example system agencies are Accenture, TATA Consultancy Services, Capgemini and CI&T (shown on graph).
Technology and infrastructure companies
Examples are Acquia (shown on graph), Lingotek, BlackMesh, Rackspace, Pantheon and Platform.sh.
End-users
Examples are Pfizer (shown on graph) or NBCUniversal.
A few observations:

Almost all of the sponsors in the top 30 are traditional Drupal businesses. Companies like MD Systems (12 employees), Valuebound (58 employees), Chapter Three (33 employees), Commerce Guys (13 employees) and PreviousNext (22 employees) are, despite their size, critical to Drupal's success.
Compared to these traditional Drupal businesses, Acquia has nearly 800 employees and at least ten full-time Drupal contributors. Acquia works to resolve some of the most complex issues on Drupal.org, many of which are not recognized by the credit system (e.g. release management, communication, sprint organizing, and project coordination). Acquia added several full-time contributors compared to last year, however, I believe that Acquia should contribute even more due to its comparative size.
No digital marketing agencies show up in the top 30, though some of them are starting to contribute. It's exciting that an increasing number of digital marketing agencies are delivering beautiful experiences using Drupal. As a community, we need to work to ensure that each of these firms are contributing back to the project with the same commitment that we see from firms like Commerce Guys, CI&T or Acro Media. Compared to last year, we have not made meaningful progress on growing contributions from digital marketing agencies. It would be interesting to see what would happen if more large organizations mandated contributions from their partners. Pfizer, for example, only works with agencies and vendors that contribute back to Drupal, and requires that its agency partners contribute to open source. If more organizations took this stance, it could have a big impact on the number of digital agencies that contribute to Drupal
The only system integrator in the top 30 is CI&T, which ranked 3rd with 959 credits. As far as system integrators are concerned, CI&T is a smaller player with approximately 2,500 employees. However, we do see various system integrators outside of the top 30, including Globant, Capgemini, Sapient and TATA Consultancy Services. Each of these system integrators reported 30 to 85 credits in the past year. The top contributor is TATA with 85 credits.
Infrastructure and software companies also play an important role in our community, yet only Acquia appears in the top 30. While Acquia has a professional services division, more than 75% of the contributions come from the product organization. Other infrastructure companies include Pantheon and Platform.sh, which are both venture-backed, platform-as-a-service companies that were born from the Drupal community. Pantheon has 6 credits and Platform.sh has 47 credits. Amazee Labs, a company that is building an infrastructure business, reported 40 credits. Compared to last year, Acquia and Rackspace have slightly more credits, while Pantheon, Platform.sh and Amazee contributed less. Lingotek, a vendor that offers cloud-based translation management software has 84 credits.
We also saw three end-users in the top 30 as corporate sponsors: Pfizer (491 credits, up from 251 credits the year before), Thunder (432 credits), and the German company, bio.logis (319 credits, up from 212 credits the year before). Other notable customers outside of the top 30, include Workday, Wolters Kluwer, Burda Media, YMCA and OpenY, CARD.com and NBCUniversal. We also saw contributions from many universities, including University of Colorado Boulder, University of Waterloo, Princeton University, University of Adelaide, University of Sydney, University of Edinburgh, McGill University and more.
We can conclude that technology and infrastructure companies, digital marketing agencies, system integrators and end-users are not making significant code contributions to Drupal.org today. How can we explain this disparity in comparison to the traditional Drupal businesses that contribute the most? We believe the biggest reasons are:

Drupal's strategic importance. A variety of the traditional Drupal agencies almost entirely depend on Drupal to support their businesses. Given both their expertise and dependence on Drupal, they are most likely to look after Drupal's development and well-being. Contrast this with most of the digital marketing agencies and system integrators who work with a diversified portfolio of content management platforms. Their well-being is less dependent on Drupal's success.
The level of experience with Drupal and open source. Drupal aside, many organizations have little or no experience with open source, so it is important that we motivate and teach them to contribute.
Legal reservations. We recognize that some organizations are not legally permitted to contribute, let alone attribute their customers. We hope that will change as open source continues to get adopted.
Tools barriers. Drupal contribution still involves a patch-based workflow on Drupal.org's unique issue queue system. This presents a fairly steep learning curve to most developers, who primarily work with more modern and common tools such as GitHub. We hope to lower some of these barriers through our collaboration with GitLab.
Process barriers. Getting code changes accepted into a Drupal project — especially Drupal core — is hard work. Peer reviews, gates such as automated testing and documentation, required sign-offs from maintainers and committers, knowledge of best practices and other community norms are a few of the challenges a contributor must face to get code accepted into Drupal. Collaborating with thousands of people on a project as large and widely-used as Drupal requires such processes, but new contributors often don't know that these processes exist, or don't understand why they exist.
We should do more to entice contribution

Drupal is used by more than one million websites. Everyone who uses Drupal benefits from work that thousands of other individuals and organizations have contributed. Drupal is great because it is continuously improved by a diverse community of contributors who are enthusiastic to give back.

However, the vast majority of the individuals and organizations behind these Drupal websites never participate in the development of the project. They might use the software as it is or don't feel the need to help drive its development. We have to provide more incentive for these individuals and organizations to contribute back to the project.

Consequently, this data shows that the Drupal community can do more to entice companies to contribute code to Drupal.org. The Drupal community has a long tradition of encouraging organizations to share code rather than keep it behind firewalls. While the spirit of the Drupal project cannot be reduced to any single ideology — not every organization can or will share their code — we would like to see organizations continue to prioritize collaboration over individual ownership.

We understand and respect that some can give more than others and that some might not be able to give back at all. Our goal is not to foster an environment that demands what and how others should give back. Our aim is not to criticize those who do not contribute, but rather to help foster an environment worthy of contribution. This is clearly laid out in Drupal's Values and Principles.

Given the vast amount of Drupal users, we believe continuing to encourage organizations and end-users to contribute is still a big opportunity. From my own conversations, it's clear that organizations still need need education, training and help. They ask questions like: "Where can we contribute?", "How can we convince our legal department?", and more.

There are substantial benefits and business drivers for organizations that contribute: (1) it improves their ability to sell and win deals and (2) it improves their ability to hire. Companies that contribute to Drupal tend to promote their contributions in RFPs and sales pitches. Contributing to Drupal also results in being recognized as a great place to work for Drupal experts.

What projects have sponsors?

To understand where the organizations sponsoring Drupal put their money, I've listed the top 20 most sponsored projects:

RankProject nameIssues1Drupal core59192Webform9053Drupal Commerce6074Varbase: The Ultimate Drupal 8 CMS Starter Kit (Bootstrap Ready)5515Commerce Point of Sale (POS)3246Views3187Commerce Migrate3078JSON API3049Paragraphs27210Open Social22211Search API Solr Search21212Drupal Connector for Janrain Identity Cloud19713Drupal.org security advisory coverage applications18914Facets17115Open Y16216Metatag16217Web Page Archive15418Drupal core - JavaScript Modernization Initiative14519Thunder14420XML sitemap120Who is sponsoring the top 30 contributors?

Rank
Username
Issues
Volunteer
Sponsored
Not specified
Sponsors
1
RenatoG
851
0%
100%
0%
CI&T (850), Johnson & Johnson (23)
2
RajabNatshah
745
14%
100%
0%
Vardot (653), Webship (90)
3
jrockowitz
700
94%
97%
1%
The Big Blue House (680), Memorial Sloan Kettering Cancer Center (7), Rosewood Marketing (2), Kennesaw State University (1)
4
adriancid
529
99%
19%
0%
Ville de Montréal (98)
5
bojanz
515
0%
98%
2%
Commerce Guys (503), Torchbox (17), Adapt (6), Acro Media (4), Bluespark (1)
6
Berdir
432
0%
92%
8%
MD Systems (396), Translations.com (10), Acquia (2)
7
alexpott
414
13%
84%
10%
Chapter Three (123), Thunder (120), Acro Media (103)
8
mglaman
414
5%
96%
1%
Commerce Guys (393), Impactiv (17), Circle Web Foundry (16), Rosewood Marketing (14), LivePerson (13), Bluespark (4), Acro Media (4), Gaggle.net (3), Thinkbean (2), Matsmart (2)
9
Wim Leers
395
8%
94%
0%
Acquia (371)
10
larowlan
360
13%
97%
1%
PreviousNext (350), University of Technology, Sydney (24), Charles Darwin University (10), Australian Competition and Consumer Commission (ACCC) (1), Department of Justice & Regulation, Victoria (1)
11
DamienMcKenna
353
1%
95%
5%
Mediacurrent (334)
12
dawehner
340
48%
86%
4%
Chapter Three (279), Torchbox (10), Drupal Association (5), Tag1 Consulting (3), Acquia (2), TES Global (1)
13
catch
339
1%
97%
3%
Third and Grove (320), Tag1 Consulting (8)
14
heddn
327
2%
99%
1%
MTech (325)
15
xjm
303
0%
97%
3%
Acquia (293)
16
pifagor
284
32%
99%
1%
GOLEMS GABB (423), Drupal Ukraine Community (73)
17
quietone
261
48%
55%
5%
Acro Media (143)
18
borisson_
255
93%
55%
3%
Dazzle (136), Intracto digital agency (1), Acquia (1), DUG BE vzw (Drupal User Group Belgium) (1)
19
adci_contributor
255
0%
100%
0%
ADCI Solutions (255)
20
volkswagenchick
254
1%
100%
0%
Hook 42 (253)
21
drunken monkey
231
91%
22%
0%
DBC (24), Vizala (20), Sunlime Web Innovations GmbH (4), Wunder Group (1), epiqo (1), Zebralog (1)
22
amateescu
225
3%
95%
3%
Pfizer (211), Drupal Association (1), Chapter Three (1)
23
joachim
199
56%
44%
19%
Torchbox (88)
24
mkalkbrenner
195
0%
99%
1%
bio.logis (193), OSCE: Organization for Security and Co-operation in Europe (119)
25
chr.fritsch
185
0%
99%
1%
Thunder (183)
26
gaurav.kapoor
178
0%
81%
19%
OpenSense Labs (144), DrupalFit (55)
27
phenaproxima
177
0%
99%
1%
Acquia (176)
28
mikeytown2
173
0%
0%
100%

29
joelpittet
170
28%
74%
16%
The University of British Columbia (125)
30
timmillwood
169
1%
100%
0%
Pfizer (169), Appnovation (163), Millwood Online (6)
We observe that the top 30 contributors are sponsored by 58 organizations. This kind of diversity is aligned with our desire to make sure that Drupal is not controlled by a single organization. These top contributors and organizations are from many different parts of the world, and work with customers large and small. Nonetheless, we will continue to benefit from an increased distribution of contribution.

Limitations of the credit system and the data

While the benefits are evident, it is important to note a few of the limitations in Drupal.org's current credit system:

Contributing to issues on Drupal.org is not the only way to contribute. Other activities, such as sponsoring events, promoting Drupal, and providing help and mentorship are also important to the long-term health of the Drupal project. Many of these activities are not currently captured by the credit system. For this post, we chose to only look at code contributions.
We acknowledge that parts of Drupal are developed on GitHub and therefore aren't fully credited on Drupal.org. The actual number of contributions and contributors could be significantly higher than what we report. The Drupal Association is working to integrate GitLab with Drupal.org. GitLab will provide support for "merge requests", which means contributing to Drupal will feel more familiar to the broader audience of open source contributors who learned their skills in the post-patch era. Some of GitLab's tools, such as inline editing and web-based code review, will also lower the barrier to contribution, and should help us grow both the number of contributions and contributors on Drupal.org.
Even when development is done on Drupal.org, the credit system is not used consistently. As using the credit system is optional, a lot of code committed on Drupal.org has no or incomplete contribution credits.
Not all code credits are the same. We currently don't have a way to account for the complexity and quality of contributions; one person might have worked several weeks for just one credit, while another person might receive a credit for ten minutes of work. In the future, we should consider issuing credit data in conjunction with issue priority, patch size, etc. This could help incentivize people to work on larger and more important problems and save coding standards improvements for new contributor sprints. Implementing a scoring system that ranks the complexity of an issue would also allow us to develop more accurate reports of contributed work.
Like Drupal itself, the Drupal.org credit system needs to continue to evolve. Ultimately, the credit system will only be useful when the community uses it, understands its shortcomings, and suggests constructive improvements.

Conclusion

Our data confirms that Drupal is a vibrant community full of contributors who are constantly evolving and improving the software. While we have amazing geographic diversity, we still need greater gender diversity, in addition to better representation across various demographic groups. Our analysis of the Drupal.org credit data concludes that most contributions to Drupal are sponsored. At the same time, the data shows that volunteer contribution remains very important to Drupal.

As a community, we need to understand that a healthy open source ecosystem includes more than the traditional Drupal businesses that contribute the most. We still don't see a lot of contribution from the larger digital marketing agencies, system integrators, technology companies, or end-users of Drupal — we believe that might come as these organizations build out their Drupal practices and Drupal becomes more strategic for them.

To grow and sustain Drupal, we should support those that contribute to Drupal and find ways to get those that are not contributing involved in our community. We invite you to help us continue to strengthen our ecosystem.
Source: Dries Buytaert www.buytaert.net


5-Day Drupal 8 Training - Toronto

Start: 
2018-10-01 09:00 - 2018-10-05 16:30 America/Toronto

Organizers: 

Meyzi

Event type: 

Training (free or commercial)

https://evolvingweb.ca/training/5-day-drupal-8-training

Learn how to build a website with Drupal from top to bottom. This week-long Drupal class is divided into three parts: site building, theming, and module development. You can register for all five days, or just the days of interest to you.
Day 1: Drupal 8 Site Building & Architecture
This course will give participants a thorough understanding of the Drupal site building process. You'll get hands-on experience creating an information architecture for Drupal, and implementing advanced features with Drupal core and contributed modules.
Planning and implementing content types
Techniques for organizing content with Views
Building layouts with configuration
Structuring content with Paragraphs
Setting up landing pages
Selecting and installing contributed modules
Site maintenance best practices
Pre-launch checklist
Days 2-3: Drupal 8 Theming
You'll learn how to build a responsive Drupal theme to customize the look of your Drupal site. We’ll create a theme based on Drupal core, and another using a front-end framework. Learn how to create layouts, customize Twig templates, and best practices for organizing your theme.
Creating a custom Drupal theme
Using Drupal's core themes
Drupal's templating system
Adding CSS and Javascript to your Drupal theme
Twig syntax and Twig debug
Sub-theming with Bootstrap, Zurb Foundation, etc.
Using Twig to customize Views output
Preprocess functions
Using SASS with your Drupal theme
Extending Twig templates
Using libraries to manage internal and external assets
Best practices for Drupal theming
Days 4-5: Drupal 8 Module Development
You'll learn the process for developing a module with standard components like blocks, permissions, forms, and pages. The course will cover the concepts behind module development, how to use Object Oriented Programming for Drupal 8, and essential Drupal developer tools. It will give you an overall understanding of how modules work and you’ll get hands-on experience developing modules from scratch.
Creating a Drupal 8 module
Drupal coding standards
Using Drush, Drupal Console, and Composer
Creating pages programmatically
Creating custom field types and formatters
Using the Examples module
Creating custom forms
Database integration
Creating blocks programmatically
Creating administrative forms
Creating and applying patches
Configuration management
To register and for details: https://evolvingweb.ca/training/5-day-drupal-8-training
Source: https://groups.drupal.org/node/512931/feed


SANDcamp: Introduction to Site Building

Start: 
2018-03-23 09:00 - 17:00 America/Los_Angeles

Organizers: 

rainbreaw

cstauffer

Event type: 

Training (free or commercial)

https://www.sandcamp.org/introduction-drupal-8-site-building

Description
Learn the basics of building a CMS (content management system) based website using Drupal 8 — a completely customizable, flexible, and scalable open-source framework. This introduction will give you all of the essentials required to produce a straightforward site, customize your content and displays, and enough knowledge to find more targeted information for unique customizations as you progress through your Drupal site building adventures.
This training is being offered by STAUFFER – www.stauffer.com - for free as part of the Drupal Global Training Days initiative.

Training Agenda
Morning: Part I
Introduction: What is Drupal?
Getting Set Up Quickly
Basic Site Configuration
Basic Content Creation
Navigation / Structure:
-- The Menu System
-- Taxonomy
Morning: Part II
Going beyond OOTB (out of the box) Options
-- Changing functionality with Contributed Modules
-- Customizing your Content Types
-- Customizing your Taxonomy
What Are Entities
The Blocks System
The Comments System
Afternoon: Part III
How (and what) Content is Displayed
-- Views
-- Contextual Filters and Relationships
-- View Modes
Afternoon: Part IV
Part four will largely depend on you and your interests. First, we will need to finish up or clarify anything from the earlier parts. Beyond that, topics we can cover will include:
Media (Images, Videos, YouTube, etc., as well as responsive breakpoints)
Installing (and using) a Contributed Theme
Creating a custom sub-theme or entirely custom theme
Multilingual behavior
Managing Users/Roles/Permissions/Access beyond the surface discussion from Part I
Development environments and configuration management
You will choose which of these topics we explore with what time is available.
What You Need
We will use the Pantheon sandbox to build our sites during this workshop, so you do not need to install anything special onto your system. You do need a wireless capable laptop, as this is a hands-on workshop.
You do not need any coding skills to get started as a Drupal Site Builder, but the more you know (especially related to HTML5, CSS, SASS, PHP, Twig, MySQL, and jQuery), the more successful you will be.
If you have not already done so, please set up a user account on drupal.org before this workshop. It will make it easier for you to participate in the issue queues and be an active community member.
Source: https://groups.drupal.org/node/512931/feed


Detecting Motion with PIR Sensors


Recently we needed to determine whether or not movement was occurring in the nearby vicinity of a device. The application was to be used for an interactive art installation (which you can read more about at viget.com/lightwalk), where motion would trigger the activation of lights. We considered a wide array of components to do the job, but ultimately landed on using Passive Infrared Sensors (PIR for short). Here, I'll explain the process by which we got our PIR sensors to report momentary and sustained movement.

The Task

What is it that we wanted exactly? Detect when motion occurs in front of the sensor (between 1 and 10 feet), and continue to detect the motion for as long as it occurs. This covers the two main use cases we were designing for - casually walking by the sensor, and dancing like a maniac (a maaaaniac) in front of the sensor.

The Existing Tech

This is, not surprisingly, a problem that's been solved time and time again. So much so that there are really great proto-boards available to dip your toes into PIR with (ie: SparkFun OpenPIR). PIR sensors are commonly used to power deck and garage lighting that needs to activate whenever motion occurs in some specific area, and they work in pretty much all environmental circumstances (night, day, cloudy, sunny, etc.) Side note: the science behind how PIR sensors work is roughly a cross between infrared waves and the eye of a bug, here's a pre-assembled Wikipedia rabbit hole for you: PIR -> Fresnal Lense -> Anthropod Eye.

Unfortunately for us, we couldn't use an off-the-shelf solution for a number of reasons, mainly that they had to live outside, be tiny, and mount to the side of a 1-inch tube. We ultimately sprung for a batch of industrial PIR sensors, those that are built small and capable of handling all sorts of weather, and then set about determining which one detected motion in the desired focal area.

The Experimentation

We rigged up six different sensors to a pole, and logged the readings each sensor spat out while a coworker made crazy dance motions along a grid (video proof). We then plotted the readings on a spreadsheet and color coded the results to determine where each sensor's sweet spot of motion detection was:

It's not every day that you get to do Actual Science as a software developer! The dark purple blocks represents a "strong" reading, and the graphs here show the results from the three most promising sensors. We ended up going with sensor #1 as it offered the best detection for "right in front of the thing". All this goes to show that every type of sensor behaves differently depending on what kind of lens is fixed to it, and you should pick the one that best suits your needs. (for those curious, we ended up with this one)

The Fine Tuning

Now came the fun part (for me at least) - the coding! PIR sensors output their perception of the world by way of an analog value, a number between 0 and 4096 that describes ... something. That something isn't as straightforward as "a high number means motion is happening" unfortunately. In fact, when something moves drastically in front of a PIR sensor, that analog value moves high and low rather slowly. The graphs above were filled with the lowest value recorded in a set time period, a rudimentary method for detecting motion.

Let's take a look at some graphs visualizing the raw output of a few different scenarios (each graph represents ~7 seconds of time):

Flatline - no motion detected

At rest the sensor outputs a value around 3100.

Quick Motion - wave hand in front of sensor

Motion causes the value to spike low and high at mostly unpredictable rates, and over the course of multiple seconds (milliseconds would have been nice, but this is certainly workable)

Sustained Motion - dance in front of sensor

Sustained motion triggers similar spikes, but with varying amplitudes as time passes

It's easy enough to detect single motion events. When the amplitude of the graph hits a certain threshold in a given timeframe, you have motion. Sustained motion sensing behaves a bit differently however. The amplitude of the wave has it's extremes, but will spend multiple seconds outputting more mild oscillations. Thus, the overall tactic becomes:

Determine initial motion based on the detection of a large oscillation.
Determine sustained motion based on the continued detection of a smaller oscillations.

Let's take a look at one more graph to bring this home. The jagged red line here is the difference between local maximums and minimums recorded at 250ms intervals, and the orange line is the final boolean value answering the question "is something moving in front of the sensor" (25 seconds in total covered here):

There's a single motion near the beginning, and sustained motion for the latter half. Even though there are multiple instances where there is very little activity recorded during the sustained motion, our threshold is set loosely enough that continued motion is still detected until it concretely comes to a stop.

The Code

I'll spare you the minute details, if you're interested in taking a look at the actual code, this gist has everything you need.

In closing, check out these pictures of our little sensors in the wild:


Source: VigetInspire


How to Implement Accessibility in Agency Projects: Part 2

In part 1 of my series, How to Implement Accessibility in Agency Projects, I discussed some of the high-level challenges faced when implementing accessibility in client service companies and how we’re approaching them at Viget.

Talking about accessibility is relatively easy, but when project constraints like timelines and budgets are involved, putting it into practice can be challenging. We've been working on this at Viget and in part 2 of this series, I’ll share some concepts and tips that we're using to make accessibility part of every project.

Thinking About Accessibility

Making accessibility part of your team’s work can be challenging and requires a deliberate effort. At Viget, we've found that building empathy, company-wide education, and re-framing how we think to be valuable strategies.

Cultivate Empathy

If you’re reading this, you likely work at a computer… a lot. You also may have customized your setup to enhance the way you like to work. In short: you’re a “power user”. That’s great for productivity but bad for empathy. The more ingrained we are in our setup the harder it is to understand how other people use and experience their computer and the web. We can easily forget that we are not like our users. It's challenging enough to keep in mind that most people are less savvy, use less-than-cutting-edge hardware, or don’t have a high-speed internet connection. If you don’t have direct experience with disabilities (either yourself or someone in your life), it takes deliberate effort gain empathy for people who interact with the web in ways that are different from you.

You may be able-bodied now, but things happen as we journey through life that can cause us to become temporarily or permanently disabled. Has anything ever prevented you from using your computer in your normal way? Perhaps a broken thumb affected your ability to use the mouse, LASIK surgery made it difficult to focus on your screen for a week or two, or maybe your trackpad just gave out (all of these happened to me). Having even temporary dependence on accessible technologies, like I did with keyboard access and font zooming, can give us a new perspective and appreciation for the importance of building accessible products.

“By designing for someone with a permanent disability, someone with a situational disability can also benefit.” pic.twitter.com/H38S2Dw0LL— David Storey (@dstorey) October 1, 2015

Try these tips for gaining better insight into how people with various disabilities use the Web:

Take the #NoMouse challenge and spend some time navigating by keyboard.
Learn the basics of how to use a screen reader and try listening to how pages are read.
Install Chrome extensions like NoCoffee or Funkify to experience browsing with various disabilities.
Check out many of the other simulations from WebAIM.
Hold an empathy-building workshop for your team or company where you challenge the group to perform a specific task, like selecting a round-trip flight, using only the keyboard or with one of the Funkify personas enabled.

Educate Across the Company

Lone accessibility advocates, however passionate, aren't going to make much of a lasting impact on accessibility awareness company-wide — they can’t be everywhere all the time, and if they leave the company their influence goes with them. At Viget, we found that the most successful strategy for creating a lasting company value was to harness those with a passion for accessibility to speak, write, and lead training sessions. By framing accessibility knowledge as a higher level of expertise and empowering everyone to own their role’s portion of accessibility, we quickly saw a higher level of buy-in and enthusiasm.

To that end, we built the Interactive WCAG: a tool for filtering and sharing the daunting Web Content Accessibility Guideline (WCAG) spec in a digestible format. The spec can be filtered to only view a certain level (A, AA or AAA) and a role's responsibility (copywriting, visual design, user experience design, development, or front-end development). It also creates a shareable URL so that it can be easily sent to a colleague or client.

Try these ideas for getting a discussion going in your office:

Lead by example — begin with your own work and show what good accessibility looks like.
Do a lunch-and-learn presentation or offer to speak at a team or company all-hands meeting.
Depending on how your company is structured, approach other discipline or project teams and ask if an accessibility presentation can get on an upcoming meeting agenda. Make sure the presentation is tailored to the concerns of that group.
Write about accessibility on your company's blog.
Hold an empathy-building session or build an empathy lab where coworkers can get a better understanding of some people's barriers to using the web.
Attend a local accessibility Meetup and offer to host a meeting at your office.
Invite an outside accessibility expert to speak at a company or team meeting (in person or remote).

Think of Accessibility as a Core Part of Usability

The introduction of the iPhone and the explosion of internet-connected portable devices that followed was a sea-change moment for web developers. At the time, we were too busy re-learning how to build for the web to realize how beneficial these devices would be for people with disabilities. Our need to start accounting for new patterns of input and output beyond the desktop computer and mouse wound up being a boon to accessibility on the web. We're now accustomed to thinking about patterns that coincide with a variety of disabilities:

Better readability and responsive designs for small screens also benefit those with low vision who might prefer to zoom their browser to see content better.
Making targets, like buttons, large enough for a finger on a touchscreen also makes it easier for users with fine motor control disabilities that can still use a mouse to target and click.
Considering content in smaller chunks and writing tight for small screens is great for helping those with cognitive or memory disabilities, like ADD/ADHD, focus on the page's task.
The popularity of touch devices largely killed hovers as a primary way of revealing and interacting with content. This was good for keyboard users because it meant that we stopped relying on the mouse hover and started designing and coding for the click as the primary way to interact with things.

Tips for Making Accessibility Part of Your Day-To-Day Work

Here are some curated tips from the Viget team on how we're implementing accessibility in our daily work:

Design

“Check your palette at every step of the way so that you don't have to adjust for contrast later on. Keep the contrast checker open in a tab for easy access.”

- Mindy Wagner, Art Director

Content

“Keyboard testing is a quick and important way to QA a site. When going through pages using your keyboard, remember to use shift+tab to make sure keyboard users can move both down and up a page in a logical way. You can find some sneaky things that way, especially when elements appear/disappear when scrolling.”

“Always dig into contrast errors when using WAVE or a similar tool. Don’t consider it an error just because it is flagged as one - look at the details and see what level and font size it's failing.”

- Becky Tornes, Senior Project Manager

User Experience

Question :hover with extreme prejudice.
Edit labels and microcopy for simplicity and directness.
Disable CSS to see if a UI "reads" logically when color, shape, alignment, emphasis, and other visual design elements are absent.
Balance working memory with the amount of content on a page.
Be consistent and predictable, particularly with navigation.
Poke yoke your data inputs. Error prevention > error resolution.

- Todd Moy, Former Senior User Experience Designer

Front-End Development

“Purposely become a keyboard-only user as often as possible. You can start small. Try giving yourself a user goal, like "As a user, I need to be able to search for careers" and try to complete it using only the keyboard. If you're developing on a Mac, you may need to adjust browser and OS settings before getting started.”

- Chris Manning, Senior Front-End Developer

Don't Reserve Accessibility for Just Production Code

When prototyping or test-coding a new feature, always build it to be accessible. Even if it's for a small internal audience or just yourself, considering accessibility at a nascent stage will get it baked in from the beginning and, most importantly, means you won't have to re-think a feature's structure or interaction model later. And who are we kidding... when the going gets tough these prototypes sometimes make their way into production.

Learn HTML and Use It Semantically

Using the correct markup for the task is the easiest way to get accessibility for free. This can be pretty straightforward if you're coding by hand but more challenging if you're using a framework or helper that outputs markup for you. The benefits, though, are significant:

Sectioning elements allow screen reader users to jump around the page quickly.
Good use of headings, similarly, lets screen reader users understand a page's content structure and jump to just want they want.
Using frequently built-from-scratch elements like <button>, <a> and <select> correctly instead of meaningless <div>'s provides all of the expected interactivity (keyboard focusable, clickable and correctly read by a screen reader) without the extra work of having to add it in with JavaScript.

Not using the correct element, or trying to reproduce a native control from scratch, can lead to bigger headaches down the road and a true adding-accessibility-takes-more-time result.

Support Flexibility

Building for accessibility isn't about just one disability. There's a broad range of disabilities to keep in mind and it can feel overwhelming at times. Building flexibility into your interfaces and interactions helps ensure broader access. What does that mean? To an extent, with responsive design, we're already doing it. Accounting for multiple kinds of input (mouse and touch) and output (small to large screens) makes our sites better able to accommodate a variety of situations.

Sometimes we unknowingly disable flexibility. For example, one common practice is locking a mobile browser's zoom level to ensure that the site fits the screen or to prevent some gestures from interfering with interactions. This has the unintended consequence of preventing users with vision disabilities from zooming the page to make text or images easier to see.

Ask, “does my site’s responsive mobile version disable pinch & zoom?” If it does, you’ve created an anti-user design. @cameronmoll #aeaaus— Jeffrey Zeldman (@zeldman) October 5, 2015

Prioritize Accessible Content Over Accessible Experience

We're frequently tasked with creating richly interactive sites. That's the fun part of what we do, right? In a perfect situation with plenty of time, we'd be able to make that experience accessible to everyone. I don't know about you, but I'm still waiting for that unicorn project to come along (hint: it won't). When the task of making a complex piece of functionality or experience accessible is daunting, prioritize making sure that the content is accessible. With enough time, we could make anything accessible. But when faced with deadlines and budgets, making something accessible over nothing is the better tradeoff.

An example of this concept in practice was a map page we created for a client. This page was designed with a map of clickable pushpins that brought up a little info overlay. Rather than trying to figure out how to make the SVG map accessible to keyboards and screen readers, the design already included an identical text list that we were able to rely on. The solution was to make the map inaccessible to keyboards and screen readers. The map script that we used created the pushpins as <span>'s (see using semantic HTML above) rather than <button>'s so it was already inaccessible out-of-the-box. To make it invisible to screen readers we added aria-hidden="true" to its outermost wrapper.

The result is perfectly accessible content without the added time and expense of trying to make the map accessible. This was a win for accessibility and a win for the budget! Now, of course it's possible to make the map accessible with some extra effort, but instead, those hours could be spent on other features and contributed to delivering the site on time and on budget.

Conclusion

Creating more accessible products and experiences is an essential and rewarding endeavor but carries unique challenges for those of us working in client service companies. Rather than give up or wait for clients to ask, we’ve found that the practices I outlined in this article lead to a lasting culture at Viget that values thinking about accessibility throughout a project and throughout the company. Here are just a few examples from our experience working on some fun, beautiful and disability-specific projects. Do you have any tips to share? Comments? Criticism? We'd love to hear about it below!


Source: VigetInspire


Top 5 Text Editors for Designers Learning to Code

Okay, so you’ve decided it’s finally time to expand on your design expertise with some ninja coding skills. Congratulations! The good news is there are plenty of online resources to help you learn the basics and get your coding adventures off to a rolling start.
Sooner or later, though, you’re going to have to fly solo and pen your own code. In fact, the sooner you do this, the better – because scribbling real code is by far the best way to learn, practise and improve.
Which means, sooner or later, you’re going to need a good text editor – a program for typing unformatted text. This incredibly simple tool is the playground of all your coding escapades and modern text editors are a lot fancier than they used to be.
Here are the top five text editors for designers learning to code.
#1: Sublime Text ($70)

Sublime Text calls itself “the text editor you’ll fall in love with” and I have to admit I fell for it from the moment I started using it. Sublime was the first text editor I encountered that was designed and built to make the coding experience easier – and what a job it does.
Before Sublime, I was staring at masses of black text on white pages, until a burst of color made writing, reading and checking code so much easier.
You can select and edit multiple lines and chunks of text – eg: select every variable of the same name and change it, instead of going through them one by one. Plus you can save chunks of code (HTML templates, forms, functions, etc.) and type them out with a single button.
In fairness, most text editors offer the same features now. Sublime was the first one I came across and I’ll always have a soft spot for my first text editor love.
#2: Notepad++ (Free)

Notepad++ is easily the least exciting text editor in this list but it’s probably the best place to start as a beginner. There are no distractions or unnecessary features getting in the way. You simply write your code, execute it and see if it works. If it doesn’t, you have to try and diagnose the problem yourself – an important part of the learning process.
#3: Atom (Free)

If you like the Sublime look and feel but don’t want to pay for it, Atom is a damn good alternative. It’s not a direct swap, though. To match the same features as Sublime you have to download more plugins (additional features can also be added to Sublime via plugins), for example.
Then there’s the file preview experience which is far more intuitive with Sublime. However, there are some features Sublime lacks that are worth mentioning – my favorite being the file drag-and-drop implementation, which works wonderfully.
My biggest gripe with Atom is it lags behind at times. Performance, in general, is noticeably behind Sublime but this is a free alternative, of course.
#4: Coda ($99)

Coda calls itself a text editor but it’s actually more of an integrated integrationenvironment (IDE). In other words, it provides pretty much everything you need to develop full software applications, as opposed to simply writing the code.
That’s not really important for the purposes of this article, aside from partly explaining the price tag.
Coda might be more than a text editor but it’s still a damn good text editor in its own right. Unlike most text editors, though, you get a preview button with Coda, which allows you to get a visual representation of your code at the click of a button.
Snazzy stuff.
The main downside to Coda is the learning curve. Personally, I prefer a more basic text editor that lets me focus on coding – especially as a beginner when you’ve got enough to learn as it is. Although, I have to say, some of those Coda features are very tempting once you’ve nailed the coding basics.
#5: Visual Studio Code (Free)

I’m in two minds about recommending this one for designers learning to code. Aside from the autocomplete you get with most text editors these days, Visual Studio Code also comes with IntelliSense and other features that handle a lot of the coding for you.
If you’re the kind of person who learns by doing rather than seeing (certainly the case for me), you might find Visual Studio does too much for you.
That said, you don’t have to use autocomplete or IntelliSense just because you can. And, if you’ve got the willpower to learn by hand, they can help you quickly check your own code without reverting back to other resources.
This isn’t what Visual Studio Code is designed for but it’s up to you how you use it.
Once you are proficient with code, by the way, Visual Studio is an incredible integrationtool.
Verdict
If you’re just starting out with code, I fully recommend Notepad++ as your first text editor. You’ll know when the time comes to move on to something more advanced. Sublime and Atom are great once you start putting websites together and you need to handle multiple files.
As a designer, those programs will probably be all you ever need and more. But, if you start working on projects with other people, you’ll start to see why Coda and Visual Studio Code are so popular.
The post Top 5 Text Editors for Designers Learning to Code appeared first on Web Designer Hub.
Source: http://www.webdesignerhub.com


DrupalCoin Blockchain Web Developer - Chandra Technologies Inc - Madison, WI

DrupalCoin Blockchain Web Developer. Advance experience with DrupalCoin Blockchain architecture, best practices, and coding standards (3 Years).... $50 an hour
From Chandra Technologies Inc - Sat, 02 Dec 2017 12:48:45 GMT - View all Madison, WI jobs
Source: http://rss.indeed.com/rss?q=DrupalCoin Blockchain+Developer


Web Designer / Developer (senior level) - State Government - SunPlus Data Group, Inc. - Madison, WI

Advance experience with DrupalCoin Blockchain architecture, best practices, and coding standards. SunPlus Data Group is seeking a Web Designer / Developer for a State...
From Indeed - Fri, 01 Dec 2017 16:08:11 GMT - View all Madison, WI jobs
Source: http://rss.indeed.com/rss?q=DrupalCoin Blockchain+Developer


Advocating for Accessible UI Design

Accessibility is a hot topic these days, and the older we web-makers get, the hotter it's going to become! That might be a snarky outlook, but what I'm trying to say is that it's about time we start designing the web for everyone because the web was meant to be for everyone, and less and less are we able to predict where, when, and how our work will be consumed.

Accessibility is not just up to developers
As developers, we often encounter accessibility post-design, when we do things like implementating the correct role and aria attributes, ensuring navigation is keyboard friendly, and responsibly hiding elements. In general, our accessibility efforts go towards thinking about how to make specific components and features accessible, such as an SVG icon system or helpful tool-tips.
Given our roles as developers, this makes sense. Accessibility flaws, however, often originate in the UI design itself, and depending on our work environment, we developers don't necessarily have the authority or bandwidth to advocate for accessibility in the designs we are handed.
For example, let's say you are tasked with turning a Sketch file into a one-page WordPress site.
The design has finally been approved by the client, and now you have a weekend to build the thing, plus another two days to work with QA to perfect it. As you take a look at the design for the first time, you notice that, on small devices, the dainty serif typeface overlaid on a background image would be difficult for low-sighted visitors to read.
You, the accessibility-minded developer, could proceed in a few ways:

Remain silent and sate your accessibility conscience by making accessible choices in the code where you can
Go ahead and make accessibility improvements to the UI as you develop, present them in the finished product, and explain yourself after
Compile a list of suggested changes to send to the designer and request they be implemented in the mockups so you can then develop them

I was in a situation like this recently and, judge me if you will, I chose number one.
If I'd had the time and the guts, number 2 would've gotten me the furthest, but given the nature of my role as a first-time contractor at this high-speed agency I was hoping to develop a working relationship with, I felt I'd be overstepping my bounds and wasn't ready to take the risk of being too vocal out of the gate. I chose not to do number 3 for similar reasons, mainly for fear of causing more work and stress for the already extremely busy designer.
Now that I have the benefit of hindsight, however, might I add a fourth item to the list?

Send a succinct list of non-technical accessibility tips for UI design to everyone on the team so they make more accessible design choices in future

Where to find such a list? Well, you are in luck! Read on!
Non-technical Accessibility Tips for UI Design
What follows is a list of plain language, no-jargon, "Accessibility Tips for UI Design" you, developer, can share with everyone at work: UI designers, content providers, project managers, and clients alike. The more we can spread awareness about accessibility and think critically about the mockups we are handed to implement, the more accessible the web will be!
I have chosen the examples below from various trendy website feeds, and I used the fantastic Funkify Chrome Extension to simulate the viewing experience of site visitors with varying abilities and disabilities.
First up:
Easy on the animations.
With great power comes great responsibility. The modern web affords us the power to bounce-in, fly-in, or drop-in any content we please, but besides the wow factor, how are these animations contributing to a reader's experience on your site? How are the animations triggered? Can they be mistakenly triggered, causing a confusing jolt in the flow of your site visitor's experience?
Take this example of a car repair company's website. I've applied the "Elderly Ellen" filter from Funkify to simulate slightly blurred vision and shaky hands:
Elderly Ellen's trembling hands cause a jarring experience with bold animations.
If I were Ellen, this experience would likely steer me away from Service King's services! Someone like Elderly Ellen is constantly frustrated with technology. It's unnecessary to cause her that stress when she's trying to read about a service for repairing her car after an already traumatizing fender bender.
Make sure background and text colors have enough contrast.
Although that medium grey text looks just right on that light grey background, it's hard to read...and impossible to read if you are working out in the sunshine (not a common occurance, but I've done it before). Here's an example of the aforementioned grey-on-grey scenario:
The medium grey text color of these icons' captions does not contrast enough with the light grey background color.
And now, the same example affected by the "Sunshine Sue" filter from Funkify deems our low contrast captions simply invisible!
And now, simulating sunshine on a screen, the text is completely gone!
The solution? Run your color choices through the WebAIM contrast checker to see if they meet standards for readability and color contrast, and if they don't, adjust the color values until they do.

The Funkify extension can be used to test anything that is visible in a browser. Even if a design mock isn't yet implemented in code, an image or PDF can be opened in the browser and the extension will still work!
Be very careful when overlaying text on images, or don't.
It might look just right to have that dainty serif overlaid on the big header image, but can you read it if you slightly blur your vision? If not, up the contrast between the text and image, perhaps by brightening the text color and increasing the transparency of the image on a dark background.
On Burberry's website, for example, the user must select from a drop-down in order to enter the site, but the text identifying the drop-down is barely readable over top the background image. There are many ways to solve this from a design standpoint, but for a quick example, we could add a dark background beneath the light text to provide a bit more contrast:
Adding a contrasting background beneath the text overlaid on an image can help with readability.
Similarly, while the delicate descriptive text below the image on Tesla's new Semi website is delicate and beautiful, it is barely legiible when simulating slightly blurred vision with "Blurry Bianca":
The descriptive text overlaid on the bottom of this image is barely legible when simulating slightly blurred vision.
Double-check the readability of font weights and sizes.
The thinner the font weight and the smaller the size, the harder it is to read. Even I, as a hearing, well-sighted individual, find myself zooming in on body text at times because it is so darn lightweight and small, even if the color contrast is up to speed. If you must stick with the lightweight font, increasing the sizes and line height can do wonders as well.
I like to ask myself, does it pass the slightly-cross-eye test? That is when I slightly cross my eyes, can I still make out the text?
Some contrast, line-height, and font-size adjustments make for a more readable text in a disclaimer we are supposed to read.
Indicate external links.
If it is a requirement for a link to open in a new tab, first question whether it should be a requirement, then indicate it visually with a small icon or note in the UI.
Additionally, designers can make a note in their designs where there should be screen-reader-only text indicating the link will navigate the user away from their current viewing portal. This was brought to mind by way of some excellent replies to a Twitter conversation; read through that here.
Differentiate between action-oriented social media links vs. profile links.
When we see small social media icons, I think the general assumption is that they link to the relevant social media profiles. Sometimes, however, these icons are actually actions that, rather than linking to a profile, open a "New Tweet" dialog or similar. These actions should be marked as such.
Don't rely 100% on icons and colors to communicate.
It's easy to assume everyone knows that a hamburger icon indicates a menu or that everyone is familiar with the various versions of LinkedIn's icon. However, this is not the case, and it causes a moment of confusion and insult that isn't necessary to site visitors that are less in-the-know than we are. Especially if your audience tends to be older and/or less tech-savvy, make sure you aren't relying on what you think is common knowledge.
Reliance on colors for meaning causes a similar issue, and more-so for any users that deal with color blindness. A recent Smashing Magazine article covers this problem in detail and uses the example of a color picker on shoe sales website that, for color-blind users, results in an entirely different palette.
What would the design look like without interactivity?
If all a user could do was scroll, does the content still make sense? Are there areas where, rather than hiding the thumbnail caption under a fancy hover event, the caption could be plainly visible instead? What about on a touch screen, where hover events are treated quite differently?
What else?
Have you encountered issues with accessibility in designs you've implemented? How did you handle it? What other tips can we give designers and producers for creating more accessible UI designs?
The first step to advocating for accessible UI design is to simply think twice about what you, the developer, are told to implement. While coding up a design, try applying a few of these Funkify filters and see what results they yield. Think critically about the designs you are handed, and start a conversation with your coworkers.

Advocating for Accessible UI Design is a post from CSS-Tricks
Source: CssTricks


4 Reasons to Go PRO on CodePen

I could probably list about 100 reasons, since as a founder, user, and (ahem) PRO member of CodePen myself, I'm motivated to do so. But let me just list a few here. Some of these are my favorites, some are what PRO members have told us are their favorite, and some are lesser-known but very awesome.

1) No-hassle Debug View
Debug View is a way to look at your the Pen you've built with zero CodePen UI around it and no <iframe> containing it. Raw output! That's a dangerous thing, in the world of user-generated code. It could be highly abused if we let it go unchecked. The way it works is fairly simple.
You can use Debug View if :

You're logged in
The Pen is PRO-owned

Logging in isn't too big of a deal, but sometimes that's a pain if you just wanna shoot over a Debug View URL to your phone or to CrossBrowserTesting or something. If you're PRO, you don't worry about it at all, Debug View is totally unlocked for your Pens.

2) Collab with anybody anytime
Collab Mode on CodePen is the one that's like Google Docs: people can work together in real time on the same Pen. You type, they see you type, they type, you see what they type.
Here's what is special about that:

There is nothing to install or set up, just shoot anybody a link.
Only you need to be PRO. Nobody else does. They don't even have to be logged in.

Basically, you can be coding together with someone (or just one or the other of you watching, if you please) in about 2 seconds. Here's a short silent video if you wanna see:
[vimeo 154349112 w=640 h=360]
People use it for all sorts of things. In classrooms and educational contexts, for hiring interviews, and just for working out problems with people across the globe.
Drag and drop uploading
Need to quickly host an asset (like an image) somewhere? As in, quickly get a URL for it that you can use and count on forever? It's as easy as can be on CodePen.

If you're working on a Project, you can drag and drop files right into the sidebar as well:
[vimeo 223337237 w=640 h=360]
Save Anything Privately
Privacy is unlimited on CodePen. If you're PRO, you can make unlimited Private Pens and Private Collections. You're only limited in Private Projects by the total number of Projects on your plan. This is the number one PRO feature on CodePen for a variety of reasons. People use them to keep client work safe. People use them to experiment without anyone seeing messy tidbits. People use them to keep in-progress ideas.

I didn't even mention my actual favorite CodePen PRO feature. I'll have to share that one some other time ;)
Go PRO on CodePen

4 Reasons to Go PRO on CodePen is a post from CSS-Tricks
Source: CssTricks


Google Maps Improves Location Discovery by Color Coding Points of Interest by @MattGSouthern

Google Maps will soon be rolling out an update that will improve location discovery in two distinct ways.The post Google Maps Improves Location Discovery by Color Coding Points of Interest by @MattGSouthern appeared first on Search Engine Journal.
Source: https://www.searchenginejournal.com/feed/


Aspect Ratios for Grid Items

We've covered Aspect Ratio Boxes before. It involves trickery with padding such that an element's width and height are in proportion to your liking. It's not an ultra-common need, since fixing an element's height is asking for trouble, but it comes up.
One way to lower the risk is The Psuedo Element Tactic, in which a pseudo element pushes its parent element to the aspect ratio, but if the content inside pushes it taller, it will get taller, aspect ratio be damned.
You can use that technique in CSS grid with grid items! Although there are a couple of different ways to apply it that are worth thinking about.

Remember that grid areas and the element that occupy them aren't necessarily the same size.
We just covered this. That article started as a section in this article but felt important enough to break off into its own concept.
Knowing this, it leads to: do you need the grid area to have an aspect ratio, and the element will stretch within? Or does the element just need an aspect ratio regardless of the grid area it is in?
Scenario 1) Just the element inside needs to have an aspect ratio.
Cool. This is arguably easier. Make sure the element is 100% as wide as the grid area, then apply a pseudo element to handle the height-stretching aspect ratio.
<div class="grid">
<div style="--aspect-ratio: 2/1;">2/1</div>
<div style="--aspect-ratio: 3/1;">3/1</div>
<div style="--aspect-ratio: 1/1;">1/1</div>
</div>
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
place-items: start;
}
.grid > * {
background: orange;
width: 100%;
}
.grid > [style^='--aspect-ratio']::before {
content: "";
display: inline-block;
width: 1px;
height: 0;
padding-bottom: calc(100% / (var(--aspect-ratio)));
}
Which leads to this:

Note that you don't need to apply aspect ratios through custom properties necessarily. You can see where the padding-bottom is doing the heavy lifting and that value could be hard-coded or whatever else.
Scenario 2) Span as many columns as needed for width
I bet it's more likely that what you are needing is a way to make a, say 2-to-1 aspect ratio element, to actually span two columns, not be trapped in one. Doing this is a lot like what we just did above, but adding in rules to do that column spanning.
[style="--aspect-ratio: 1/1;"] {
grid-column: span 1;
}
[style="--aspect-ratio: 2/1;"] {
grid-column: span 2;
}
[style="--aspect-ratio: 3/1;"] {
grid-column: span 3;
}
If we toss grid-auto-flow: dense; in there too, we can get items with a variety of aspect ratios packing in nicely as they see fit.

Now is a good time to mention there little ways to screw up exact aspect ratios here. The line-height on some text might push a box taller than you want. If you want to use grid-gap, that might throw ratios out of whack. If you need to get super exact with the ratios, you might have more luck hard-coding values.
Doing column spanning also gets tricky if you're in a grid that doesn't have a set number of rows. Perhaps you're doing a repeat/auto-fill thing. You might end up in a scenario with unequal columns that won't be friendly to aspect ratios. Perhaps we can dive into that another time.
Scenario 3) Force stuff
Grid has a two-dimensional layout capability and, if we like, we could get our aspect ratios just by forcing the grid areas to the height and width we want. For instance, nothing is stopping you from hard-coding heights and widths into columns and rows:
.grid {
display: grid;
grid-template-columns: 200px 100px 100px;
grid-template-rows: 100px 200px 300px;
}
We normally don't think that way, because we want elements to be flexible and fluid, hence the percentage-based techniques used above for aspect ratios. Still, it's a thing you can do.
See the Pen Aspect Ratio Boxes Filling by Chris Coyier (@chriscoyier) on CodePen.
This example forces grid areas to be the size they are and the elements stretch to fill, but you could fix the element sizes as well.
Real world example
Ben Goshow wrote to me trying to pull this off, which is what spurred this:

Part of the issue there was not only getting the boxes to have aspect ratios, but then having alignment ability inside. There are a couple of ways to approach that, but I'd argue the easiest way is nested grids. Make the grid element display: grid; and use the alignment capabilities of that new internal grid.
See the Pen CSS Grid Items with Aspect Ratio and Internal Alignment by Chris Coyier (@chriscoyier) on CodePen.
Note in this demo instead of spanning rows, the elements are explicitly placed (not required, an example alternative layout method).

Aspect Ratios for Grid Items is a post from CSS-Tricks
Source: CssTricks


Robust React User Interfaces with Finite State Machines

User interfaces can be expressed by two things:

The state of the UI
Actions that can change that state

From credit card payment devices and gas pump screens to the software that your company creates, user interfaces react to the actions of the user and other sources and change their state accordingly. This concept isn't just limited to technology, it's a fundamental part of how everything works:

For every action, there is an equal and opposite reaction.
- Isaac Newton

This is a concept we can apply to developing better user interfaces, but before we go there, I want you to try something. Consider a photo gallery interface with this user interaction flow:

Show a search input and a search button that allows the user to search for photos
When the search button is clicked, fetch photos with the search term from Flickr
Display the search results in a grid of small sized photos
When a photo is clicked/tapped, show the full size photo
When a full-sized photo is clicked/tapped again, go back to the gallery view

Now think about how you would develop it. Maybe even try programming it in React. I'll wait; I'm just an article. I'm not going anywhere.
Finished? Awesome! That wasn't too difficult, right? Now think about the following scenarios that you might have forgotten:

What if the user clicks the search button repeatedly?
What if the user wants to cancel the search while it's in-flight?
Is the search button disabled while searching?
What if the user mischievously enables the disabled button?
Is there any indication that the results are loading?
What happens if there's an error? Can the user retry the search?
What if the user searches and then clicks a photo? What should happen?

These are just some of the potential problems that can arise during planning, development, or testing. Few things are worse in software integrationthan thinking that you've covered every possible use case, and then discovering (or receiving) new edge cases that will further complicate your code once you account for them. It's especially difficult to jump into a pre-existing project where all of these use cases are undocumented, but instead hidden in spaghetti code and left for you to decipher.
Stating the obvious
What if we could determine all possible UI states that can result from all possible actions performed on each state? And what if we can visualize these states, actions, and transitions between states? Designers intuitively do this, in what are called "user flows" (or "UX Flows"), to depict what the next state of the UI should be depending on the user interaction.
Picture credit: Simplified Checkout Process by Michael Pons
In computer science terms, there is a computational model called finite automata, or "finite state machines" (FSM), that can express the same type of information. That is, they describe which state comes next when an action is performed on the current state. Just like user flows, these finite state machines can be visualized in a clear and unambiguous way. For example, here is the state transition diagram describing the FSM of a traffic light:

What is a finite state machine?
A state machine is a useful way of modeling behavior in an application: for every action, there is a reaction in the form of a state change. There's 5 parts to a classical finite state machine:

A set of states (e.g., idle, loading, success, error, etc.)
A set of actions (e.g., SEARCH, CANCEL, SELECT_PHOTO, etc.)
An initial state (e.g., idle)
A transition function (e.g., transition('idle', 'SEARCH') == 'loading')
Final states (which don't apply to this article.)

Deterministic finite state machines (which is what we'll be dealing with) have some constraints, as well:

There are a finite number of possible states
There are a finite number of possible actions (these are the "finite" parts)
The application can only be in one of these states at a time
Given a currentState and an action, the transition function must always return the same nextState (this is the "deterministic" part)

Representing finite state machines
A finite state machine can be represented as a mapping from a state to its "transitions", where each transition is an action and the nextState that follows that action. This mapping is just a plain JavaScript object.
Let's consider an American traffic light example, one of the simplest FSM examples. Assume we start on green, then transition to yellow after some TIMER, and then RED after another TIMER, and then back to green after another TIMER:
const machine = {
green: { TIMER: 'yellow' },
yellow: { TIMER: 'red' },
red: { TIMER: 'green' }
};
const initialState = 'green';
A transition function answers the question:
Given the current state and an action, what will the next state be?
With our setup, transitioning to the next state based on an action (in this case, TIMER) is just a look-up of the currentState and action in the machine object, since:

machine[currentState] gives us the next action mapping, e.g.: machine['green'] == {TIMER: 'yellow'}
machine[currentState][action] gives us the next state from the action, e.g.: machine['green']['TIMER'] == 'yellow':
// ...
function transition(currentState, action) {
return machine[currentState][action];
}

transition('green', 'TIMER');
// => 'yellow'

Instead of using if/else or switch statements to determine the next state, e.g., if (currentState === 'green') return 'yellow';, we moved all of that logic into a plain JavaScript object that can be serialized into JSON. That's a strategy that will pay off greatly in terms of testing, visualization, reuse, analysis, flexibility, and configurability.
See the Pen Simple finite state machine example by David Khourshid (@davidkpiano) on CodePen.
Finite State Machines in React
Taking a look at a more complicated example, let's see how we can represent our gallery app using a finite state machine. The app can be in one of several states:

start - the initial search page view
loading - search results fetching view
error - search failed view
gallery - successful search results view
photo - detailed single photo view

And several actions can be performed, either by the user or the app itself:

SEARCH - user clicks the "search" button
SEARCH_SUCCESS - search succeeded with the queried photos
SEARCH_FAILURE - search failed due to an error
CANCEL_SEARCH - user clicks the "cancel search" button
SELECT_PHOTO - user clicks a photo in the gallery
EXIT_PHOTO - user clicks to exit the detailed photo view

The best way to visualize how these states and actions come together, at first, is with two very powerful tools: pencil and paper. Draw arrows between the states, and label the arrows with actions that cause transitions between the states:
We can now represent these transitions in an object, just like in the traffic light example:
const galleryMachine = {
start: {
SEARCH: 'loading'
},
loading: {
SEARCH_SUCCESS: 'gallery',
SEARCH_FAILURE: 'error',
CANCEL_SEARCH: 'gallery'
},
error: {
SEARCH: 'loading'
},
gallery: {
SEARCH: 'loading',
SELECT_PHOTO: 'photo'
},
photo: {
EXIT_PHOTO: 'gallery'
}
};

const initialState = 'start';
Now let's see how we can incorporate this finite state machine configuration and the transition function into our gallery app. In the App's component state, there will be a single property that will indicate the current finite state, gallery:
class App extends React.Component {
constructor(props) {
super(props);

this.state = {
gallery: 'start', // initial finite state
query: '',
items: []
};
}
// ...
The transition function will be a method of this App class, so that we can retrieve the current finite state:
// ...
transition(action) {
const currentGalleryState = this.state.gallery;
const nextGalleryState =
galleryMachine[currentGalleryState][action.type];

if (nextGalleryState) {
const nextState = this.command(nextGalleryState, action);

this.setState({
gallery: nextGalleryState,
...nextState // extended state
});
}
}
// ...
This looks similar to the previously described transition(currentState, action) function, with a few differences:

The action is an object with a type property that specifies the string action type, e.g., type: 'SEARCH'
Only the action is passed in since we can retrieve the current finite state from this.state.gallery
The entire app state will be updated with the next finite state, i.e., nextGalleryState, as well as any extended state (nextState) that results from executing a command based on the next state and action payload (see the "Executing commands" section)

Executing commands
When a state change occurs, "side effects" (or "commands" as we'll refer to them) might be executed. For example, when a user clicks the "Search" button and a 'SEARCH' action is emitted, the state will transition to 'loading', and an async Flickr search should be executed (otherwise, 'loading' would be a lie, and developers should never lie).
We can handle these side effects in a command(nextState, action) method that determines what to execute given the next finite state and action payload, as well as what the extended state should be:
// ...
command(nextState, action) {
switch (nextState) {
case 'loading':
// execute the search command
this.search(action.query);
break;
case 'gallery':
if (action.items) {
// update the state with the found items
return { items: action.items };
}
break;
case 'photo':
if (action.item) {
// update the state with the selected photo item
return { photo: action.item };
}
break;
default:
break;
}
}
// ...
Actions can have payloads other than the action's type, which the app state might need to be updated with. For example, when a 'SEARCH' action succeeds, a 'SEARCH_SUCCESS' action can be emitted with the items from the search result:
// ...
fetchJsonp(
`https://api.flickr.com/services/feeds/photos_public.gne?lang=en-us&format=json&tags=${encodedQuery}`,
{ jsonpCallback: 'jsoncallback' })
.then(res => res.json())
.then(data => {
this.transition({ type: 'SEARCH_SUCCESS', items: data.items });
})
.catch(error => {
this.transition({ type: 'SEARCH_FAILURE' });
});
// ...
The command() method above will immediately return any extended state (i.e., state other than the finite state) that this.state should be updated with in this.setState(...), along with the finite state change.
The final machine-controlled app
Since we've declaratively configured the finite state machine for the app, we can render the proper UI in a cleaner way by conditionally rendering based on the current finite state:
// ...
render() {
const galleryState = this.state.gallery;

return (
<div className="ui-app" data-state={galleryState}>
{this.renderForm(galleryState)}
{this.renderGallery(galleryState)}
{this.renderPhoto(galleryState)}
</div>
);
}
// ...
The final result:
See the Pen Gallery app with Finite State Machines by David Khourshid (@davidkpiano) on CodePen.
Finite state in CSS
You might have noticed data-state={galleryState} in the code above. By setting that data-attribute, we can conditionally style any part of our app using an attribute selector:
.ui-app {
// ...

&[data-state="start"] {
justify-content: center;
}

&[data-state="loading"] {
.ui-item {
opacity: .5;
}
}
}
This is preferable to using className because you can enforce the constraint that only a single value at a time can be set for data-state, and the specificity is the same as using a class. Attribute selectors also supported in most popular CSS-in-JS solutions.
Advantages and resources
Using finite state machines for describing the behavior of complex applications is nothing new. Traditionally, this was done with switch and goto statements, but by describing finite state machines as a declarative mapping between states, actions, and next states, you can use that data to visualize the state transitions:

Furthermore, using declarative finite state machines allows you to:

Store, share, and configure application logic anywhere - similar components, other apps, in databases, in other languages, etc.
Make collaboration easier with designers and project managers
Statically analyze and optimize state transitions, including states that are impossible to reach
Easily change application logic without fear
Automate integration tests

Conclusion and takeaways
Finite state machines are an abstraction for modeling the parts of your app that can be represented as finite states, and almost all apps have those parts. The FSM coding patterns presented in this article:

Can be used with any existing state management setup; e.g., Redux or MobX
Can be adapted to any framework (not just React), or no framework at all
Are not written in stone; the developer can adapt the patterns to their coding style
Are not applicable to every single situation or use-case

From now on, when you encounter "boolean flag" variables such as isLoaded or isSuccess, I encourage you to stop and think about how your app state can be modeled as a finite state machine instead. That way, you can refactor your app to represent state as state === 'loaded' or state === 'success', using enumerated states in place of boolean flags.
Resources
I gave a talk at React Rally 2017 about using finite automata and statecharts to create better user interfaces, if you want to learn more about the motivation and principles:
[youtube https://www.youtube.com/watch?v=VU1NKX6Qkxc&w=560&h=315]
Slides: Infinitely Better UIs with Finite Automata
Here are some further resources:

Pure UI by Guillermo Rauch
Pure UI Control by Adam Solove
Wikipedia: Finite State Machines
Statecharts: A Visual Formalism for Complex Systems by David Harel (PDF)
Managing State in JavaScript with State Machines by Krasimir Tsonev
Rambling Thoughts on React and Finite State Machines by Ryan Florence

Robust React User Interfaces with Finite State Machines is a post from CSS-Tricks
Source: CssTricks


Creating a Star to Heart Animation with SVG and Vanilla JavaScript

In my previous article, I've shown how to smoothly transition from one state to another using vanilla JavaScript. Make sure you check that one out first because I'll be referencing some things I explained there in a lot of detail, like demos given as examples, formulas for various timing functions or how not to reverse the timing function when going back from the final state of a transition to the initial one.

The last example showcased making the shape of a mouth to go from sad to glad by changing the d attribute of the path we used to draw this mouth.
Manipulating the path data can be taken to the next level to give us more interesting results, like a star morphing into a heart.
The star to heart animation we'll be coding.
The idea
Both are made out of five cubic Bézier curves. The interactive demo below shows the individual curves and the points where these curves are connected. Clicking any curve or point highlights it, as well as its corresponding curve/point from the other shape.
See the Pen by thebabydino (@thebabydino) on CodePen.
Note that all of these curves are created as cubic ones, even if, for some of them, the two control points coincide.
The shapes for both the star and the heart are pretty simplistic and unrealistic ones, but they'll do.
The starting code
As seen in the face animation example, I often choose to generate such shapes with Pug, but here, since this path data we generate will also need to be manipulated with JavaScript for the transition, going all JavaScript, including computing the coordinates and putting them into the d attribute seems like the best option.
This means we don't need to write much in terms of markup:
<svg>
<path id='shape'/>
</svg>
In terms of JavaScript, we start by getting the SVG element and the path element - this is the shape that morphs from a star into a heart and back. We also set a viewBox attribute on the SVG element such that its dimensions along the two axes are equal and the (0,0) point is dead in the middle. This means the coordinates of the top left corner are (-.5*D,-.5*D), where D is the value for the viewBox dimensions. And last, but not least, we create an object to store info about the initial and final states of the transition and about how to go from the interpolated values to the actual attribute values we need to set on our SVG shape.
const _SVG = document.querySelector('svg'),
_SHAPE = document.getElementById('shape'),
D = 1000,
O = { ini: {}, fin: {}, afn: {} };

(function init() {
_SVG.setAttribute('viewBox', [-.5*D, -.5*D, D, D].join(' '));
})();
Now that we got this out of the way, we can move on to the more interesting part!
The geometry of the shapes
The initial coordinates of the end points and control points are those for which we get the star and the final ones are the ones for which we get the heart. The range for each coordinate is the difference between its final value and its initial one. Here, we also rotate the shape as we morph it because we want the star to point up and we change the fill to go from the golden star to the crimson heart.
Alright, but how do we get the coordinates of the end and control points in the two cases?
Star
In the case of the star, we start with a regular pentagram. The end points of our curves are at the intersection between the pentagram edges and we use the pentagram vertices as control points.
Regular pentagram with vertex and edge crossing points highlighted as control points and end points of five cubic Bézier curves (live).
Getting the vertices of our regular pentagram is pretty straightforward given the radius (or diameter) of its circumcircle, which we take to be a fraction of the viewBox size of our SVG (considered here square for simplicity, we're not going for tight packing in this case). But how do we get their intersections?
First of all, let's consider the small pentagon highlighted inside the pentagram in the illustration below. Since the pentagram is regular, the small pentagon whose vertices coincide with the edge intersections of the pentagram is also regular. It also has the same incircle as the pentagram and, therefore, the same inradius.
Regular pentagram and inner regular pentagon share the same incircle (live).
So if we compute the pentagram inradius, then we also have the inradius of the inner pentagon, which, together with the central angle corresponding to an edge of a regular pentagon, allows us to get the circumradius of this pentagon, which in turn allows us to compute its vertex coordinates and these are exactly the edge intersections of the pentagram and the endpoints of our cubic Bézier curves.
Our regular pentagram is represented by the Schläfli symbol {5/2}, meaning that it has 5 vertices, and, given these 5 vertex points equally distributed on its circumcircle, 360°/5 = 72° apart, we start from the first, skip the next point on the circle and connect to the second one (this is the meaning of the 2 in the symbol; 1 would describe a pentagon as we don't skip any points, we connect to the first). And so on - we keep skipping the point right after.
In the interactive demo below, select either pentagon or pentagram to see how they get constructed.
See the Pen by thebabydino (@thebabydino) on CodePen.
This way, we get that the central angle corresponding to an edge of the regular pentagram is twice of that corresponding to the regular pentagon with the same vertices. We have 1·(360°/5) = 1·72° = 72° (or 1·(2·π/5) in radians) for the pentagon versus 2·(360°/5) = 2·72° = 144° (2·(2·π/5) in radians) for the pentagram. In general, given a regular polygon (whether it's a convex or a star polygon doesn't matter) with the Schläfli symbol {p,q}, the central angle corresponding to one of its edges is q·(360°/p) (q·(2·π/p) in radians).
Central angle corresponding to an edge of a regular polygon: pentagram (left, 144°) vs. pentagon (right, 72°) (live).
We also know the pentagram circumradius, which we said we take as a fraction of the square viewBox size. This means we can get the pentagram inradius (which is equal to that of the small pentagon) from a right triangle where we know the hypotenuse (it's the pentagram circumradius) and an acute angle (half the central angle corresponding to the pentagram edge).
Computing the inradius of a regular pentagram from a right triangle where the hypotenuse is the pentagram circumradius and the acute angle between the two is half the central angle corresponding to a pentagram edge (live).
The cosine of half the central angle is the inradius over the circumradius, which gives us that the inradius is the circumradius multiplied with this cosine value.
Now that we have the inradius of the small regular pentagon inside our pentagram, we can compute its circumradius from a similar right triangle having the circumradius as hypotenuse, half the central angle as one of the acute angles and the inradius as the cathetus adjacent to this acute angle.
The illustration below highlights a right triangle formed from a circumradius of a regular pentagon, its inradius and half an edge. From this triangle, we can compute the circumradius if we know the inradius and the central angle corresponding to a pentagon edge as the acute angle between these two radii is half this central angle.
Computing the circumradius of a regular pentagon from a right triangle where it's the hypotenuse, while the catheti are the inradius and half the pentagon edge and the acute angle between the two radii is half the central angle corresponding to a pentagon edge (live).
Remember that, in this case, the central angle is not the same as for the pentagram, it's half of it (360°/5 = 72°).
Good, now that we have this radius, we can get all the coordinates we want. They're the coordinates of points distributed at equal angles on two circles. We have 5 points on the outer circle (the circumcircle of our pentagram) and 5 on the inner one (the circumcircle of the small pentagon). That's 10 points in total, with angles of 360°/10 = 36° in between the radial lines they're on.
The end and control points are distributed on the circumradius of the inner pentagon and on that of the pentagram respectively (live).
We know the radii of both these circles. The radius of the outer one is the regular pentagram circumradius, which we take to be some arbitrary fraction of the viewBox dimension (.5 or .25 or .32 or whatever value we feel would work best). The radius of the inner one is the circumradius of the small regular pentagon formed inside the pentagram, which we can compute as a function of the central angle corresponding to one of its edges and its inradius, which is equal to that of the pentagram and therefore we can compute from the pentagram circumradius and the central angle corresponding to a pentagram edge.
So, at this point, we can generate the path data that draws our star, it doesn't depend on anything that's still unknown.
So let's do that and put all of the above into code!
We start by creating a getStarPoints(f) function which depends on an arbitrary factor (f) that's going to help us get the pentagram circumradius from the viewBox size. This function returns an array of coordinates we later use for interpolation.
Within this function, we first compute the constant stuff that won't change as we progress through it - the pentagram circumradius (radius of the outer circle), the central (base) angles corresponding to one edge of a regular pentagram and polygon, the inradius shared by the pentagram and the inner pentagon whose vertices are the points where the pentagram edges cross each other, the circumradius of this inner pentagon and, finally, the total number of distinct points whose coordinates we need to compute and the base angle for this distribution.
After that, within a loop, we compute the coordinates of the points we want and we push them into the array of coordinates.
const P = 5; /* number of cubic curves/ polygon vertices */

function getStarPoints(f = .5) {
const RCO = f*D /* outer (pentagram) circumradius */,
BAS = 2*(2*Math.PI/P) /* base angle for star poly */,
BAC = 2*Math.PI/P /* base angle for convex poly */,
RI = RCO*Math.cos(.5*BAS) /*pentagram/ inner pentagon inradius */,
RCI = RI/Math.cos(.5*BAC) /* inner pentagon circumradius */,
ND = 2*P /* total number of distinct points we need to get */,
BAD = 2*Math.PI/ND /* base angle for point distribution */,
PTS = [] /* array we fill with point coordinates */;

for(let i = 0; i < ND; i++) {}

return PTS;
}
To compute the coordinates of our points, we use the radius of the circle they're on and the angle of the radial line connecting them to the origin with respect to the horizontal axis, as illustrated by the interactive demo below (drag the point to see how its Cartesian coordinates change):
See the Pen by thebabydino (@thebabydino) on CodePen.
In our case, the current radius is the radius of the outer circle (pentagram circumradius RCO) for even index points (0, 2, ...) and the radius of the inner circle (inner pentagon circumradius RCI) for odd index points (1, 3, ...), while the angle of the radial line connecting the current point to the origin is the point index (i) multiplied with the base angle for point distribution (BAD, which happens to be 36° or π/10 in our particular case).
So within the loop we have:
for(let i = 0; i < ND; i++) {
let cr = i%2 ? RCI : RCO,
ca = i*BAD,
x = Math.round(cr*Math.cos(ca)),
y = Math.round(cr*Math.sin(ca));
}
Since we've chosen a pretty big value for the viewBox size, we can safely round the coordinate values so that our code looks cleaner, without decimals.
As for pushing these coordinates into the points array, we do this twice when we're on the outer circle (the even indices case) because that's where we actually have two control points overlapping, but only for the star, so we'll need to move each of these overlapping points into different positions to get the heart.
for(let i = 0; i < ND; i++) {
/* same as before */

PTS.push([x, y]);
if(!(i%2)) PTS.push([x, y]);
}
Next, we put data into our object O. For the path data (d) attribute, we store the array of points we get when calling the above function as the initial value. We also create a function for generating the actual attribute value (the path data string in this case - inserting commands in between the pairs of coordinates, so that the browser knows what to do with those coordinates). Finally, we take every attribute we have stored data for and we set its value to the value returned by the previously mentioned function:
(function init() {
/* same as before */

O.d = {
ini: getStarPoints(),
afn: function(pts) {
return pts.reduce((a, c, i) => {
return a + (i%3 ? ' ' : 'C') + c
}, `M${pts[pts.length - 1]}`)
}
};

for(let p in O) _SHAPE.setAttribute(p, O[p].afn(O[p].ini))
})();
The result can be seen in the Pen below:
See the Pen by thebabydino (@thebabydino) on CodePen.
This is a promising start. However, we want the first tip of the generating pentagram to point down and the first tip of the resulting star to point up. Currently, they're both pointing right. This is because we start from 0° (3 o'clock). So in order to start from 6 o'clock, we add 90° (π/2 in radians) to every current angle in the getStarPoints() function.
ca = i*BAD + .5*Math.PI
This makes the first tip of the generating pentagram and resulting star to point down. To rotate the star, we need to set its transform attribute to a half circle rotation. In order to do so, we first set an initial rotation angle to -180. Afterwards, we set the function that generates the actual attribute value to a function that generates a string from a function name and an argument:
function fnStr(fname, farg) { return `${fname}(${farg})` };

(function init() {
/* same as before */

O.transform = { ini: -180, afn: (ang) => fnStr('rotate', ang) };

/* same as before */
})();
We also give our star a golden fill in a similar fashion. We set an RGB array to the initial value in the fill case and we use a similar function to generate the actual attribute value:
(function init() {
/* same as before */

O.fill = { ini: [255, 215, 0], afn: (rgb) => fnStr('rgb', rgb) };

/* same as before */
})();
We now have a nice golden SVG star, made up of five cubic Bézier curves:
See the Pen by thebabydino (@thebabydino) on CodePen.
Heart
Since we have the star, let's next see how we can get the heart!
We start with two intersecting circles of equal radii, both a fraction (let's say .25 for the time being) of the viewBox size. These circles intersect in such a way that the segment connecting their central points is on the x axis and the segment connecting their intersection points is on the y axis. We also take these two segments to be equal.
We start with two circles of equal radius whose central points are on the horizontal axis and which intersect on the vertical axis (live).
Next, we draw diameters through the upper intersection point and then tangents through the opposite points of these diameters. These tangents intersect on the y axis.
Constructing diameters through the upper intersection point and tangents to the circle at the opposite ends of these diameters, tangents which intersect on the vertical axis (live).
The upper intersection point and the diametrically opposite points make up three of the five end points we need. The other two end points split the outer half circle arcs into two equal parts, thus giving us four quarter circle arcs.
Highlighting the end points of the cubic Bézier curves that make up the heart and the coinciding control points of the bottom one of these curves (live).
Both control points for the curve at the bottom coincide with the intersection of the the two tangents drawn previously. But what about the other four curves? How can we go from circular arcs to cubic Bézier curves?
We don't have a cubic Bézier curve equivalent for a quarter circle arc, but we can find a very good approximation, as explained in this article.
The gist of it is that we start from a quarter circle arc of radius R and draw tangents to the end points of this arc (N and Q). These tangents intersect at P. The quadrilateral ONPQ has all angles equal to 90° (or π/2), three of them by construction (O corresponds to a 90° arc and the tangent to a point of that circle is always perpendicular onto the radial line to the same point) and the final one by computation (the sum of angles in a quadrilateral is always 360° and the other three angles add up to 270°). This makes ONPQ a rectangle. But ONPQ also has two consecutive edges equal (OQ and ON are both radial lines, equal to R in length), which makes it a square of edge R. So the lengths of NP and QP are also equal to R.
Approximating a quarter circle arc with a cubic Bézier curve (live).
The control points of the cubic curve approximating our arc are on the tangent lines NP and QP, at C·R away from the end points, where C is the constant the previously linked article computes to be .551915.
Given all of this, we can now start computing the coordinates of the end points and control points of the cubic curves making up our star.
Due to the way we've chosen to construct this heart, TO0SO1 (see figure below) is a square since it has all edges equal (all are radii of one of our two equal circles) and its diagonals are equal by construction (we said the distance between the central points equals that between the intersection points). Here, O is the intersection of the diagonals and OT is half the ST diagonal. T and S are on the y axis, so their x coordinate is 0. Their y coordinate in absolute value equals the OT segment, which is half the diagonal (as is the OS segment).
The TO0SO1 square (live).
We can split any square of edge length l into two equal right isosceles triangles where the catheti coincide with the square edges and the hypotenuse coincides with a diagonal.
Any square can be split into two congruent right isosceles triangles (live).
Using one of these right triangles, we can compute the hypotenuse (and therefore the square diagonal) using Pythagora's theorem: d² = l² + l². This gives us the square diagonal as a function of the edge d = √(2∙l) = l∙√2 (conversely, the edge as a function of the diagonal is l = d/√2). It also means that half the diagonal is d/2 = (l∙√2)/2 = l/√2.
Applying this to our TO0SO1 square of edge length R, we get that the y coordinate of T (which, in absolute value, equals half this square's diagonal) is -R/√2 and the y coordinate of S is R/√2.
The coordinates of the vertices of the TO0SO1 square (live).
Similarly, the Ok points are on the x axis, so their y coordinates are 0, while their x coordinates are given by the half diagonal OOk: ±R/√2.
TO0SO1 being a square also means all of its angles are 90° (π/2 in radians) angles.
The TAkBkS quadrilaterals (live).
In the illustration above, the TBk segments are diameter segments, meaning that the TBk arcs are half circle, or 180° arcs and we've split them into two equal halves with the Ak points, getting two equal 90° arcs - TAk and AkBk, which correspond to two equal 90° angles, ∠TOkAk and ∠AkOkBk.
Given that ∠TOkS are 90° angles and ∠TOkAk are also 90° angles by construction, it results that the SAk segments are also diameter segments. This gives us that in the TAkBkS quadrilaterals, the diagonals TBk and SAk are perpendicular, equal and cross each other in the middle (TOk, OkBk, SOk and OkAk are all equal to the initial circle radius R). This means the TAkBkS quadrilaterals are squares whose diagonals are 2∙R.
From here we can get that the edge length of the TAkBkS quadrilaterals is 2∙R/√2 = R∙√2. Since all angles of a square are 90° ones and the TS edge coincides with the vertical axis, this means the TAk and SBk edges are horizontal, parallel to the x axis and their length gives us the x coordinates of the Ak and Bk points: ±R∙√2.
Since TAk and SBk are horizontal segments, the y coordinates of the Ak and Bk points equal those of the T (-R/√2) and S (R/√2) points respectively.
The coordinates of the vertices of the TAkBkS squares (live).
Another thing we get from here is that, since TAkBkS are squares, AkBk are parallel with TS, which is on the y (vertical) axis, therefore the AkBk segments are vertical. Additionally, since the x axis is parallel to the TAk and SBk segments and it cuts the TS, it results that it also cuts the AkBk segments in half.
Now let's move on to the control points.
We start with the overlapping control points for the bottom curve.
The TB0CB1 quadrilateral (live).
The TB0CB1 quadrilateral has all angles equal to 90° (∠T since TO0SO1 is a square, ∠Bk by construction since the BkC segments are tangent to the circle at Bk and therefore perpendicular onto the radial lines OkBk at that point; and finally, ∠C can only be 90° since the sum of angles in a quadrilateral is 360° and the other three angles add up to 270°), which makes it a rectangle. It also has two consecutive edges equal - TB0 and TB1 are both diameters of the initial squares and therefore both equal to 2∙R. All of this makes it a square of edge 2∙R.
From here, we can get its diagonal TC - it's 2∙R∙√2. Since C is on the y axis, its x coordinate is 0. Its y coordinate is the length of the OC segment. The OC segment is the TC segment minus the OT segment: 2∙R∙√2 - R/√2 = 4∙R/√2 - R/√2 = 3∙R/√2.
The coordinates of the vertices of the TB0CB1 square (live).
So we now have the coordinates of the two coinciding control points for the bottom curve are (0,3∙R/√2).
In order to get the coordinates of the control points for the other curves, we draw tangents through their endpoints and we get the intersections of these tangents at Dk and Ek.
The TOkAkDk and AkOkBkEk quadrilaterals (live).
In the TOkAkDk quadrilaterals, we have that all angles are 90° (right) angles, three of them by construction (∠DkTOk and ∠DkAkOk are the angles between the radial and tangent lines at T and Ak respectively, while ∠TOkAk are the angles corresponding to the quarter circle arcs TAk) and the fourth by computation (the sum of angles in a quadrilateral is 360° and the other three add up to 270°). This makes TOkAkDk rectangles. Since they have two consecutive edges equal (OkT and OkAk are radial segments of length R), they are also squares.
This means the diagonals TAk and OkDk are R∙√2. We already know that TAk are horizontal and, since the diagonals of a square are perpendicular, it results the OkDk segments are vertical. This means the Ok and Dk points have the same x coordinate, which we've already computed for Ok to be ±R/√2. Since we know the length of OkDk, we can also get the y coordinates - they're the diagonal length (R∙√2) with minus in front.
Similarly, in the AkOkBkEk quadrilaterals, we have that all angles are 90° (right) angles, three of them by construction (∠EkAkOk and ∠EkBkOk are the angles between the radial and tangent lines at Ak and Bk respectively, while ∠AkOkBk are the angles corresponding to the quarter circle arcs AkBk) and the fourth by computation (the sum of angles in a quadrilateral is 360° and the other three add up to 270°). This makes AkOkBkEk rectangles. Since they have two consecutive edges equal (OkAk and OkBk are radial segments of length R), they are also squares.
From here, we get the diagonals AkBk and OkEk are R∙√2. We know the AkBk segments are vertical and split into half by the horizontal axis, which means the OkEk segments are on this axis and the y coordinates of the Ek points are 0. Since the x coordinates of the Ok points are ±R/√2 and the OkEk segments are R∙√2, we can compute those of the Ek points as well - they're ±3∙R/√2.
The coordinates of the newly computed vertices of the TOₖAₖDₖ and AₖOₖBₖEₖ squares (live).
Alright, but these intersection points for the tangents are not the control points we need to get the circular arc approximations. The control points we want are on the TDk, AkDk, AkEk and BkEk segments at about 55% (this value is given by the constant C computed in the previously mentioned article) away from the curve end points (T, Ak, Bk). This means the segments from the endpoints to the control points are C∙R.
In this situation, the coordinates of our control points are 1 - C of those of the end points (T, Ak and Bk) plus C of those of the points where the tangents at the end points intersect (Dk and Ek).
So let's put all of this into JavaScript code!
Just like in the star case, we start with a getStarPoints(f) function which depends on an arbitrary factor (f) that's going to help us get the radius of the helper circles from the viewBox size. This function also returns an array of coordinates we later use for interpolation.
Inside, we compute the stuff that doesn't change throughout the function. First off, the radius of the helper circles. From that, the half diagonal of the small squares whose edge equals this helper circle radius, half diagonal which is also the circumradius of these squares. Afterwards, the coordinates of the end points of our cubic curves (the T, Ak, Bk points), in absolute value for the ones along the horizontal axis. Then we move on to the coordinates of the points where the tangents through the end points intersect (the C, Dk, Ek points). These either coincide with the control points (C) or can help us get the control points (this is the case for Dk and Ek).
function getHeartPoints(f = .25) {
const R = f*D /* helper circle radius */,
RC = Math.round(R/Math.SQRT2) /* circumradius of square of edge R */,
XT = 0, YT = -RC /* coords of point T */,
XA = 2*RC, YA = -RC /* coords of A points (x in abs value) */,
XB = 2*RC, YB = RC /* coords of B points (x in abs value) */,
XC = 0, YC = 3*RC /* coords of point C */,
XD = RC, YD = -2*RC /* coords of D points (x in abs value) */,
XE = 3*RC, YE = 0 /* coords of E points (x in abs value) */;
}
The interactive demo below shows the coordinates of these points on click:
See the Pen by thebabydino (@thebabydino) on CodePen.
Now we can also get the control points from the end points and the points where the tangents through the end points intersect:
function getHeartPoints(f = .25) {
/* same as before */
const /* const for cubic curve approx of quarter circle */
C = .551915,
CC = 1 - C,
/* coords of ctrl points on TD segs */
XTD = Math.round(CC*XT + C*XD), YTD = Math.round(CC*YT + C*YD),
/* coords of ctrl points on AD segs */
XAD = Math.round(CC*XA + C*XD), YAD = Math.round(CC*YA + C*YD),
/* coords of ctrl points on AE segs */
XAE = Math.round(CC*XA + C*XE), YAE = Math.round(CC*YA + C*YE),
/* coords of ctrl points on BE segs */
XBE = Math.round(CC*XB + C*XE), YBE = Math.round(CC*YB + C*YE);

/* same as before */
}
Next, we need to put the relevant coordinates into an array and return this array. In the case of the star, we started with the bottom curve and then went clockwise, so we do the same here. For every curve, we push two sets of coordinates for the control points and then one set for the point where the current curve ends.
See the Pen by thebabydino (@thebabydino) on CodePen.
Note that in the case of the first (bottom) curve, the two control points coincide, so we push the same pair of coordinates twice. The code doesn't look anywhere near as nice as in the case of the star, but it will have to suffice:
return [
[XC, YC], [XC, YC], [-XB, YB],
[-XBE, YBE], [-XAE, YAE], [-XA, YA],
[-XAD, YAD], [-XTD, YTD], [XT, YT],
[XTD, YTD], [XAD, YAD], [XA, YA],
[XAE, YAE], [XBE, YBE], [XB, YB]
];
We can now take our star demo and use the getHeartPoints() function for the final state, no rotation and a crimson fill instead. Then, we set the current state to the final shape, just so that we can see the heart:
function fnStr(fname, farg) { return `${fname}(${farg})` };

(function init() {
_SVG.setAttribute('viewBox', [-.5*D, -.5*D, D, D].join(' '));

O.d = {
ini: getStarPoints(),
fin: getHeartPoints(),
afn: function(pts) {
return pts.reduce((a, c, i) => {
return a + (i%3 ? ' ' : 'C') + c
}, `M${pts[pts.length - 1]}`)
}
};

O.transform = {
ini: -180,
fin: 0,
afn: (ang) => fnStr('rotate', ang)
};

O.fill = {
ini: [255, 215, 0],
fin: [220, 20, 60],
afn: (rgb) => fnStr('rgb', rgb)
};

for(let p in O) _SHAPE.setAttribute(p, O[p].afn(O[p].fin))
})();
This gives us a nice looking heart:
See the Pen by thebabydino (@thebabydino) on CodePen.
Ensuring consistent shape alignment
However, if we place the two shapes one on top of the other with no fill or transform, just a stroke, we see the alignment looks pretty bad:
See the Pen by thebabydino (@thebabydino) on CodePen.
The easiest way to solve this issue is to shift the heart up by an amount depending on the radius of the helper circles:
return [ /* same coords */ ].map(([x, y]) => [x, y - .09*R])
We now have much better alignment, regardless of how we tweak the f factor in either case. This is the factor that determines the pentagram circumradius relative to the viewBox size in the star case (when the default is .5) and the radius of the helper circles relative to the same viewBox size in the heart case (when the default is .25).
See the Pen by thebabydino (@thebabydino) on CodePen.
Switching between the two shapes
We want to go from one shape to the other on click. In order to do this, we set a direction dir variable which is 1 when we go from star to heart and -1 when we go from heart to star. Initially, it's -1, as if we've just switched from heart to star.
Then we add a 'click' event listener on the _SHAPE element and code what happens in this situation - we change the sign of the direction (dir) variable and we change the shape's attributes so that we go from a golden star to a crimson heart or the other way around:
let dir = -1;

(function init() {
/* same as before */

_SHAPE.addEventListener('click', e => {
dir *= -1;

for(let p in O)
_SHAPE.setAttribute(p, O[p].afn(O[p][dir > 0 ? 'fin' : 'ini']));
}, false);
})();
And we're now switching between the two shapes on click:
See the Pen by thebabydino (@thebabydino) on CodePen.
Morphing from one shape to another
What we really want however is not an abrupt change from one shape to another, but a gradual one. So we use the interpolation techniques explained in the previous article to achieve this.
We first decide on a total number of frames for our transition (NF) and choose the kind of timing functions we want to use - an ease-in-out type of function for transitioning the path shape from star to heart, a bounce-ini-fin type of function for the rotation angle and an ease-out one for the fill. We only include these, though we could later add others in case we change our mind and want to explore other options as well.
/* same as before */
const NF = 50,
TFN = {
'ease-out': function(k) {
return 1 - Math.pow(1 - k, 1.675)
},
'ease-in-out': function(k) {
return .5*(Math.sin((k - .5)*Math.PI) + 1)
},
'bounce-ini-fin': function(k, s = -.65*Math.PI, e = -s) {
return (Math.sin(k*(e - s) + s) - Math.sin(s))/(Math.sin(e) - Math.sin(s))
}
};
We then specify which of these timing functions we use for each property we transition:
(function init() {
/* same as before */

O.d = {
/* same as before */
tfn: 'ease-in-out'
};

O.transform = {
/* same as before */
tfn: 'bounce-ini-fin'
};

O.fill = {
/* same as before */
tfn: 'ease-out'
};

/* same as before */
})();
We move on to adding request ID (rID) and current frame (cf) variables, an update() function we first call on click, then on every refresh of the display until the transition finishes and we call a stopAni() function to exit this animation loop. Within the update() function, we... well, update the current frame cf, compute a progress k and decide whether we've reached the end of the transition and we need to exit the animation loop or we carry on.
We also add a multiplier m variable which we use so that we don't reverse the timing functions when we go from the final state (heart) back to the initial one (star).
let rID = null, cf = 0, m;

function stopAni() {
cancelAnimationFrame(rID);
rID = null;
};

function update() {
cf += dir;

let k = cf/NF;

if(!(cf%NF)) {
stopAni();
return
}

rID = requestAnimationFrame(update)
};
Then we need to change what we do on click:
addEventListener('click', e => {
if(rID) stopAni();
dir *= -1;
m = .5*(1 - dir);
update();
}, false);
Within the update() function, we want to set the attributes we transition to some intermediate values (depending on the progress k). As seen in the previous article, it's good to have the ranges between the final and initial values precomputed at the beginning, before even setting the listener, so that's our next step: creating a function that computes the range between numbers, whether as such or in arrays, no matter how deep and then using this function to set the ranges for the properties we want to transition.
function range(ini, fin) {
return typeof ini == 'number' ?
fin - ini :
ini.map((c, i) => range(ini[i], fin[i]))
};

(function init() {
/* same as before */

for(let p in O) {
O[p].rng = range(O[p].ini, O[p].fin);
_SHAPE.setAttribute(p, O[p].afn(O[p].ini));
}

/* same as before */
})();
Now all that's left to do is the interpolation part in the update() function. Using a loop, we go through all the attributes we want to smoothly change from one end state to the other. Within this loop, we set their current value to the one we get as the result of an interpolation function which depends on the initial value(s), range(s) of the current attribute (ini and rng), on the timing function we use (tfn) and on the progress (k):
function update() {
/* same as before */

for(let p in O) {
let c = O[p];

_SHAPE.setAttribute(p, c.afn(int(c.ini, c.rng, TFN[c.tfn], k)));
}

/* same as before */
};
The last step is to write this interpolation function. It's pretty similar to the one that gives us the range values:
function int(ini, rng, tfn, k) {
return typeof ini == 'number' ?
Math.round(ini + (m + dir*tfn(m + dir*k))*rng) :
ini.map((c, i) => int(ini[i], rng[i], tfn, k))
};
This finally gives us a shape that morphs from star to heart on click and goes back to star on a second click!
See the Pen by thebabydino (@thebabydino) on CodePen.
It's almost what we wanted - there's still one tiny issue. For cyclic values like angle values, we don't want to go back by half a circle on the second click. Instead, we want to continue going in the same direction for another half circle. Adding this half circle from after the second click with the one traveled after the first click, we get a full circle so we're right back where we started.
We put this into code by adding an optional continuity property and tweaking the updating and interpolating functions a bit:
function int(ini, rng, tfn, k, cnt) {
return typeof ini == 'number' ?
Math.round(ini + cnt*(m + dir*tfn(m + dir*k))*rng) :
ini.map((c, i) => int(ini[i], rng[i], tfn, k, cnt))
};

function update() {
/* same as before */

for(let p in O) {
let c = O[p];

_SHAPE.setAttribute(p, c.afn(int(c.ini, c.rng, TFN[c.tfn], k, c.cnt ? dir : 1)));
}

/* same as before */
};

(function init() {
/* same as before */

O.transform = {
ini: -180,
fin: 0,
afn: (ang) => fnStr('rotate', ang),
tfn: 'bounce-ini-fin',
cnt: 1
};

/* same as before */
})();
We now have the result we've been after: a shape that morphs from a golden star into a crimson heart and rotates clockwise by half a circle every time it goes from one state to the other:
See the Pen by thebabydino (@thebabydino) on CodePen.

Creating a Star to Heart Animation with SVG and Vanilla JavaScript is a post from CSS-Tricks
Source: CssTricks


The Art of Comments

I believe commenting code is important. Most of all, I believe commenting is misunderstood. I'm tentative to write this article at all. I am not a commenting expert (if there is such a thing) and have definitely written code that was poorly commented, not commented at all, and have written comments that are superfluous.

I tweeted out the other day that "I hear conflicting opinions on whether or not you should write comments. But I get thank you's from junior devs for writing them so I'll continue." The responses I received were varied, but what caught my eye was that for every person agreeing that commenting was necessary, they all had different reasons for believing this.
Commenting is a more nuanced thing than we give it credit for. There is no nomenclature for commenting (not that there should be) but lumping all comments together is an oversimplification. The example in this comic that was tweeted in response is true:
From Abstrusegoose
This is where I think a lot of the misconceptions of comments lie. The book Clean Code by Robert C. Martin talks about this: that comments shouldn't be necessary because code should be self-documenting. That if you feel a comment is necessary, you should rewrite it to be more legible. I both agree and disagree with this. In the process of writing a comment, you can often find things that could be written better, but it's not an either/or. I might still be able to rewrite that code to be more self-documenting and also write a comment as well, for the following reason:
Code can describe how, but it cannot explain why.
This isn't a new concept, but it's a common theme I notice in helpful comments that I have come across. The ability to communicate something that the code cannot, or cannot concisely.
All of that said, there is just not one right way or one reason to write a comment. In order to better learn, let's dig into some of the many beneficial types of comments that might all serve a different purpose, followed by patterns we might want to avoid.
Good comments
What is the Why
Many examples of good comments can be housed under this category. Code explains what you'd like the computer to take action on. You'll hear people talk about declarative code because it describes the logic precisely but without describing all of the steps like a recipe. It lets the computer do the heavy lifting. We could also write our comments to be a bit more declarative
/*
We had to write this function because the browser
interprets that everything is a box
*/
This doesn't describe what the code below it will do. It doesn't describe the actions it will take. But if you found a more elegant way of rewriting this function, you could feel confident in doing so because your code is likely the solution to the same problem in a different way.
Because of this, less maintenance is required (we'll dig more into this further on). If you found a better way to write this, you probably wouldn't need to rewrite the comment. You could also quickly understand whether you could rewrite another section of code to make this function unnecessary without spending a long time parsing all the steps to make the whole.
Clarifying something that is not legible by regular human beings
When you look at a long line of regex, can you immediately grok what's going on? If you can, you're in the minority, and even if you can at this moment, you might not be able to next year. What about a browser hack? Have you ever seen this in your code?
.selector { [;property: value;]; }
what about
var isFF = /a/[-1]=='a';
The first one targets Chrome ≤ 28, Safari ≤ 7, Opera ≥ 14, the second one is Firefox versions 2-3. I have written code that needs something like this. In order to avoid another maintainer or a future me assuming I took some Salvia before heading to work that day, it's great to tell people what the heck that's for. Especially in preparation for a time when we don't have to support that browser anymore, or the browser bug is fixed and we can remove it.
Something that is clear and legible to you is not necessarily clear to others
Who's smart? We are! Who writes clean code? We do! We don't have to comment, look how clear it is. The problem with this way of thinking is that we all have deeper knowledge in different areas. On small teams where people's skillsets and expertise are more of a circle than a venn diagram, this is less of an issue than big groups that change teams or get junior devs or interns frequently. But I'd probably still make room for those newcomers or for future you. On bigger teams where there are junior engineers or even just engineers from all types of background, people might not outrightly tell you they need you to comment, but many of these people will also express gratitude when you do.
Comments like chapters of a book
If this very article was written as one big hunk rather than broken up into sections with whitespace and smaller headings, it would be harder to skim through. Maybe not all of what I'm saying applies to you. Commenting sections or pieces allows people to skip to a part most relevant to them. But alas! You say. We have functional programming, imports, and modules for this now.
It's true! We break things down into smaller bits so that they are more manageable, and thank goodness for that. But even in smaller sections of code, you'll necessarily come to a piece that has to be a bit longer. Being able quickly grasp what is relevant or a label for an area that's a bit different can speed up productivity.
A guide to keep the logic straight while writing the code
This one is an interesting one! These are not the kind of comments you keep, and thus could also be found in the "bad patterns" section. Many times when I'm working on a bigger project with a lot of moving parts, breaking things up into the actions I'm going to take is extremely helpful. This could look like
// get the request from the server and give an error if it failed
// do x thing with that request
// format the data like so
Then I can easily focus on one thing at a time. But when left in your code as is, these comments can be screwy to read later. They're so useful while you're writing it but once you're finished can merely be a duplication of what the code does, forcing the reader to read the same thing twice in two different ways. It doesn't make them any less valuable to write, though.
My perfect-world suggestion would be to use these comments at the time of writing and then revisit them after. As you delete them, you could ask "does this do this in the most elegant and legible way possible?" "Is there another comment I might replace this with that will explain why this is necessary?" "What would I think is the most useful thing to express to future me or other from another mother?"
This is OK to refactor
Have you ever had a really aggressive product deadline? Perhaps you implemented a feature that you yourself disagreed with, or they told you it was "temporary" and "just an AB test so it doesn't matter". *Cue horror music* … and then it lived on… forever…
As embarrassing as it might be, writing comments like
// this isn't my best work, we had to get it in by the deadline
is rather helpful. As a maintainer, when I run across comments like this, I'll save buckets of time trying to figure out what the heck is wrong with this person and envisioning ways I could sabotage their morning commute. I'll immediately stop trying to figure out what parts of this code I should preserve and instead focus on what can be refactored. The only warning I'll give is to try not to make this type of coding your fallback (we'll discuss this in detail further on).
Commenting as a teaching tool
Are you a PHP shop that just was given a client that's all Ruby? Maybe it's totally standard Ruby but your team is in slightly over their heads. Are you writing a tutorial for someone? These are the limited examples for when writing out the how can be helpful. The person is literally learning on the spot and might not be able to just infer what it's doing because they've never seen it before in their lives. Comment that sh*t. Learning is humbling enough without them having to ask you aloud what they could more easily learn on their own.
I StackOverflow'd the bejeezus outta this
Did you just copy paste a whole block of code from Stack Overflow and modify it to fit your needs? This isn't a great practice but we've all been there. Something I've done that's saved me in the past is to put the link to the post where I found it. But! Then we won't get credit for that code! You might say. You're optimizing for the wrong thing would be my answer.
Inevitably people have different coding styles and the author of the solution solved a problem in a different way than you would if you knew the area deeper. Why does this matter? Because later, you might be smarter. You might level up in this area and then you'll spend less time scratching your head at why you wrote it that way, or learn from the other person's approach. Plus, you can always look back at the post, and see if any new replies came in that shed more light on the subject. There might even be another, better answer later.
Bad Comments
Writing comments gets a bad wrap sometimes, and that's because bad comments do indeed exist. Let's talk about some things to avoid while writing them.
They just say what it's already doing
John Papa made the accurate joke that this:
// if foo equals bar ...
If (foo === bar) {

} // end if
is a big pain. Why? Because you're actually reading everything twice in two different ways. It gives no more information, in fact, it makes you have to process things in two different formats, which is mental overhead rather than helpful. We've all written comments like this. Perhaps because we didn't understand it well enough ourselves or we were overly worried about reading it later. For whatever the reason, it's always good to take a step back and try to look at the code and comment from the perspective of someone reading it rather than you as the author, if you can.
It wasn't maintained
Bad documentation can be worse than no documentation. There's nothing more frustrating than coming across a block of code where the comment says something completely different than what's expressed below. Worse than time-wasting, it's misleading.
One solution to this is making sure that whatever code you are updating, you're maintaining the comments as well. And certainly having less and only more meaningful comments makes this upkeep less arduous. But commenting and maintaining comments are all part of an engineer's job. The comment is in your code, it is your job to work on it, even if it means deleting it.
If your comments are of good quality to begin with, and express why and not the how, you may find that this problem takes care of itself. For instance, if I write
// we need to FLIP this animation to be more performant in every browser
and refactor this code later to go from using getBoundingClientRect() to getBBox(), the comment still applies. The function exists for the same reason, but the details of how are what has changed.
You could have used a better name
I've definitely seen people write code (or done this myself) where the variable or functions names are one letter, and then comment what the thing is. This is a waste. We all hate typing, but if you are using a variable or function name repeatedly, I don't want to scan up the whole document where you explained what the name itself could do. I get it, naming is hard. But some comments take the place of something that could easily be written more precisely.
The comments are an excuse for not writing the code better to begin with
This is the crux of the issue for a lot of people. If you are writing code that is haphazard, and leaning back on your comments to clarify, this means the comments are holding back your programming. This is a horse-behind-the-cart kind of scenario. Unfortunately, even as the author it's not so easy to determine which is which.
We lie to ourselves in myriad ways. We might spend the time writing a comment that could be better spent making the code cleaner to begin with. We might also tell ourselves we don't need to comment our code because our code is well-written, even if other people might not agree.
There are lazy crutches in both directions. Just do your best. Try not to rely on just one correct way and instead write your code, and then read it. Try to envision you are both the author and maintainer, or how that code might look to a younger you. What information would you need to be as productive as possible?

People tend to, lately, get on one side or the other of "whether you should write comments", but I would argue that that conversation is not nuanced enough. Hopefully opening the floor to a deeper conversation about how to write meaningful comments bridges the gap.
Even so, it can be a lot to parse. Haha get it? Anyways, I'll leave you with some (better) humor. A while back there was a Stack Overflow post about the best comments people have written or seen. You can definitely waste some time in here. Pretty funny stuff.

The Art of Comments is a post from CSS-Tricks
Source: CssTricks


Writing Smarter Animation Code

If you've ever coded an animation that's longer than 10 seconds with dozens or even hundreds of choreographed elements, you know how challenging it can be to avoid the dreaded "wall of code". Worse yet, editing an animation that was built by someone else (or even yourself 2 months ago) can be nightmarish.
In these videos, I'll show you the techniques that the pros use keep their code clean, manageable, and easy to revise. Scripted animation provides you the opportunity to create animations that are incredibly dynamic and flexible. My goal is for you to have fun without getting bogged down by the process.
We'll be using GSAP for all the animation. If you haven't used it yet, you'll quickly see why it's so popular - the workflow benefits are substantial.

See the Pen SVG Wars: May the morph be with you. (Craig Roblewsky) on CodePen.
The demo above from Craig Roblewsky is a great example of the types of complex animations I want to help you build.
This article is intended for those who have a basic understanding of GSAP and want to approach their code in a smarter, more efficient way. However, even if you haven't used GSAP, or prefer another animation tool, I think you'll be intrigued by these solutions to some of the common problems that all animators face. Sit back, watch and enjoy!
Video 1: Overview of the techniques
The video below will give you a quick behind-the-scenes look at how Craig structured his code in the SVG Wars animation and the many benefits of these workflow strategies.
[youtube https://www.youtube.com/watch?v=ZbTI85lmu9Q&w=560&h=315]
Although this is a detailed and complex animation, the code is surprisingly easy to work with. It's written using the same approach that we at GreenSock use for any animation longer than a few seconds. The secret to this technique is two-fold:

Break your animation into smaller timelines that get glued together in a master (parent) timeline.
Use functions to create and return those smaller timelines.

This makes your code modular and easy to edit.
Video 2: Detailed Example
I'll show you exactly how to build a sequence using functions that create and return timelines. You'll see how packing everything into one big timeline (no modular nesting) results in the intimidating "Wall of Code". I'll then break the animation down into separate timelines and use a parameterized function that does all the heavy lifting with 60% less code!
[youtube https://www.youtube.com/watch?v=8ETMjqhQRCs&w=560&h=315]
Let's review the key points...
Avoid the dreaded wall of code
A common strategy (especially for beginners) is to create one big timeline containing all of the animation code. Although a timeline offers tons of features that accommodate this style of coding, it's just a basic reality of any programming endeavor that too much code in one place will become unwieldy.
Let's upgrade the code so that we can apply the same techniques Craig used in the SVG wars animation...
See the Pen Wall of Code on CodePen.
Be sure to investigate the code in the "JS" tab. Even for something this simple, the code can be hard to scan and edit, especially for someone new to the project. Imagine if that timeline had 100 lines. Mentally parsing it all can be a chore.
Create a separate timeline for each panel
By separating the animation for each panel into its own timeline, the code becomes easier to read and edit.
var panel1 = new TimelineLite();
panel1.from(...);
...

var panel2 = new TimelineLite();
panel2.from(...);
...

var panel3 = new TimelineLite();
panel3.from(...);
...
Now it's much easier to do a quick scan and find the code for panel2. However, when these timelines are created they will all play instantly, but we want them sequenced.
See the Pen
No problem - just nest them in a parent timeline in whatever order we want.
Nest each timeline using add()
One of the greatest features of GSAP's timeline tools (TimelineLite / TimelineMax) is the ability to nest animations as deeply as you want (place timelines inside of other timelines).
The add() method allows you add any tween, timeline, label or callback anywhere in a timeline. By default, things are placed at the end of the timeline which is perfect for sequencing. In order to schedule these 3 timelines to run in succession we will add each of them to a master timeline like so:
//create a new parent timeline
var master = new TimelineMax();

//add child timelines
master.add(panel1)
.add(panel2)
.add(panel3);
Demo with all code for this stage:
See the Pen
The animation looks the same, but the code is much more refined and easy to parse mentally.
Some key benefits of nesting timelines are that you can:

Scan the code more easily.
Change the order of sections by just moving the add() code.
Change the speed of an individual timeline.
Make one section repeat multiple times.
Have precise control over the placement of each timeline using the position parameter (beyond the scope of this article).

Use functions to create and return timelines
The last step in optimizing this code is to create a function that generates the animations for each panel. Functions are inherently powerful in that they:

Can be called many times.
Can be parameterized in order to vary the animations they build.
Allow you to define local variables that won't conflict with other code.

Since each panel is built using the same HTML structure and the same animation style, there is a lot of repetitive code that we can eliminate by using a function to create the timelines. Simply tell that function which panel to operate on and it will do the rest.
Our function takes in a single panel parameter that is used in the selector string for all the tweens in the timeline:
function createPanel(panel) {
var tl = new TimelineLite();
tl.from(panel + " .bg", 0.4, {scale:0, ease:Power1.easeInOut})
.from(panel + " .bg", 0.3, {rotation:90, ease:Power1.easeInOut}, 0)
.staggerFrom(panel + " .text span", 1.1, {y:-50, opacity:0, ease:Elastic.easeOut}, 0.06)
.addLabel("out", "+=1")
.staggerTo(panel + " .text span", 0.3, {opacity:0, y:50, ease:Power1.easeIn}, -0.06, "out")
.to(panel + " .bg", 0.4, {scale:0, rotation:-90, ease:Power1.easeInOut});
return tl; //very important that the timeline gets returned
}
We can then build a sequence out of all the timelines by placing each one in a parent timeline using add().
var master = new TimelineMax();
master.add(createPanel(".panel1"))
.add(createPanel(".panel2"))
.add(createPanel(".panel3"));
Completed demo with full code:
See the Pen
This animation was purposefully designed to be relatively simple and use one function that could do all the heavy lifting. Your real-world projects may have more variance but even if each child animation is unique, I still recommend using functions to create each section of your complex animations.
Check out this example in the wonderful pen from Sarah Drasner that's built using functions that return timelines to illustrate how to do exactly that!
See the Pen
And of course the same technique is used on the main GSAP page animation:
See the Pen
GSDevTools
You may have noticed that fancy timeline controller used in some of the demos and the videos. GSDevTools was designed to super-charge your workflow by allowing you to quickly navigate and control any GSAP tween or timeline. To find out more about GSDevTools visit greensock.com/GSDevTools.
Conclusion
Next time you've got a moderately complex animation project, try these techniques and see how much more fun it is and how quickly you can experiment. Your coworkers will sing your praises when they need to edit one of your animations. Once you get the hang of modularizing your code and tapping into GSAP's advanced capabilities, it'll probably open up a whole new world of possibilities. Don't forget to use functions to handle repetitive tasks.
As with all projects, you'll probably have a client or art director ask:

"Can you slow the whole thing down a bit?"
"Can you take that 10-second part in the middle and move it to the end?"
"Can you speed up the end and make it loop a few times?"
"Can you jump to that part at the end so I can check the copy?"
"Can we add this new, stupid idea I just thought of in the middle?"

Previously, these requests would trigger a panic attack and put the entire project at risk, but now you can simply say "gimme 2 seconds..."
Additional Resources
To find out more about GSAP and what it can do, check out the following links:

GreenSock Animation Platform (GSAP)
GSAP Getting Started Guide
Official GSAP Video Training
GSAP Documentation
GSAP Showcase
GreenSock Support Forums
GSDevTools
Club GreenSock (get bonus plugins/tools)

CSS-Tricks readers can use the coupon code CSS-Tricks for 25% off a Club GreenSock membership which gets you a bunch of extras like MorphSVG and GSDevTools (referenced in this article). Valid through 11/14/2017.

Writing Smarter Animation Code is a post from CSS-Tricks
Source: CssTricks


5 things CSS developers wish they knew before they started

You can learn anything, but you can't learn everything 🙃
So accept that, and focus on what matters to you
— Una Kravets 👩🏻‍💻 (@Una) September 1, 2017

Una Kravets is absolutely right. In modern CSS development, there are so many things to learn. For someone starting out today, it's hard to know where to start.
Here is a list of things I wish I had known if I were to start all over again.

1. Don't underestimate CSS
It looks easy. After all, it's just a set of rules that selects an element and modifies it based on a set of properties and values.
CSS is that, but also so much more!
A successful CSS project requires the most impeccable architecture. Poorly written CSS is brittle and quickly becomes difficult to maintain. It's critical you learn how to organize your code in order to create maintainable structures with a long lifespan.
But even an excellent code base has to deal with the insane amount of devices, screen sizes, capabilities, and user preferences. Not to mention accessibility, internationalization, and browser support!
CSS is like a bear cub: cute and inoffensive but as he grows, he'll eat you alive.

Learn to read code before writing and delivering code.
It's your responsibility to stay up to date with best practice. MDN, W3C, A List Apart, and CSS-Tricks are your source of truth.
The web has no shape; each device is different. Embrace diversity and understand the environment we live in.

2. Share and participate
Sharing is so important! How I wish someone had told me that when I started. It took me ten years to understand the value of sharing; when I did, it completely changed how I viewed my work and how I collaborate with others.
You'll be a better developer if you surround yourself with good developers, so get involved in open source projects. The CSS community is full of kind and generous developers. The sooner the better.
Share everything you learn. The path is as important as the end result; even the tiniest things can make a difference to others.

Learn Git. Git is the language of open source and you definitely want to be part of it.
Get involved in an open source project.
Share! Write a blog, documentation, or tweets; speak at meetups and conferences.
Find an accountability partner, someone that will push you to share consistently.

3. Pick the right tools
Your code editor should be an extension of your mind.
It doesn't matter if you use Atom, VSCode or old school Vim; the better you shape your tool to your thought process, the better developer you'll become. You'll not only gain speed but also have an uninterrupted thought line that results in fluid ideas.
The terminal is your friend.
There is a lot more about being a CSS developer than actually writing CSS. Building your code, compiling, linting, formatting, and browser live refresh are only a small part of what you'll have to deal with on a daily basis.

Research which IDE is best for you. There are high performance text editors like Vim or easier to use options like Atom or VSCode.
Pick up your way around the terminal and learn CLI as soon as possible. The short book "Working the command line" is a great starting point.

4. Get to know the browser
The browser is not only your canvas, but also a powerful inspector to debug your code, test performance, and learn from others.
Learning how the browser renders your code is an eye-opening experience that will take your coding skills to the next level.
Every browser is different; get to know those differences and embrace them. Love them for what they are. (Yes, even IE.)

Spend time looking around the inspector.
You'll not be able to own every single device; get a BrowserStack or CrossBrowserTesting account, it's worth it.
Install every browser you can and learn how each one of them renders your code.

5. Learn to write maintainable CSS
It'll probably take you years, but if there is just one single skill a CSS developer should have, it is to write maintainable structures.
This means knowing exactly how the cascade, the box model, and specificity works. Master CSS architecture models, learn their pros and cons and how to implement them.
Remember that a modular architecture leads to independent modules, good performance, accessible structures, and responsive components (AKA: CSS happiness).

Learn about CSS architectures, keep up with the trends, and have an opinion!
Follow people that are paving the CSS roads like Harry Roberts, Una Kravets, Brad Frost, Ben Frain, Sara Soueidan, Chris Coyier, Eric Meyer, Jen Simmons, Rachel Andrew, and many many others.

The future looks bright
Modern CSS is amazing. Its future is even better. I love CSS and enjoy every second I spend coding.
If you need help, you can reach out to me or probably any of the CSS developers mentioned in this article. You might be surprised by how kind and generous the CSS community can be.
What do you think about my advice? What other advice would you give? Let me know what you think in the comments.

5 things CSS developers wish they knew before they started is a post from CSS-Tricks
Source: CssTricks