University of New England's Website Awarded 2024 Webby Honoree

Webby Awards logo

Happy Spring! We’re jumping into the turn of the season with some exciting news… Redfin Solutions, LLC has been recognized as a 2024 Webby Honoree! We’ve been working hard with one of our fantastic clients, University of New England, and decided to showcase their site to the world. The site was awarded in the category: “Websites and Mobile Sites - Best Mobile Visual Design - Function.”

Since 1996, The Webby Awards have been paramount internationally in recognizing excellence in the digital landscape. In each category, two awards are presented per category: The Webby Award and The Webby People’s Voice Award, along with honorees for each category. We’re ecstatic to have been given the accolade of Webby Honoree and  highlighted alongside the sites of various major brands including Apple Vision Pro, Gucci Ancora Fashion Show 2024, and Ritz-Carlton! View the official Webby Awards listing for this category to see University of New England’s site among other top contenders.

Congratulations to all those who have had sites recognized, and we wish the best of luck for sites who are now in the final voting phase.

UNE's site on mobile and desktop
Topic

Polypane: A Command Center for Developers

In the vast world of web development tools, a gem emerges that stands out every so often. Polypane is one such jewel, and its brilliance is the culmination of relentless hard work, forward thinking, and an ability to understand the needs of developers. The mastermind behind this tool is its founder, Kilian Valkhof. His commitment to creating a tool with an accessibility and developer-first mentality is evident in every feature. But what's even more heartwarming is Kilian's direct approach. You can actually email him; lo and behold, he responds quickly. How many tools can you say that about? Before I delve deeper into the brilliance of Polypane, I must give a hearty shoutout to Syntax, the podcast where I first heard about this groundbreaking tool.

Why Polypane Feels Like a Must-Have:

1. Comprehensive Yet Compact: Polypane isn't just another tool; it feels like a command center for developers. Gone are the days of juggling multiple tools to complete a simple task. With Polypane, everything from responsive layouts to customizing breakpoints to accessibility simulators is under one roof. And it's all presented on a single screen!

2. Horizontal Shift/Layout Debugging: I've lost count of the hours I've spent trying to figure out what's causing that pesky layout shift. Polypane highlights the offending element in red, making debugging a game-changer. 🤯

Layout debugging

3. Target Size: In our quest for sleek designs, it's easy to forget that elements need ample space between them for easy touch access. Polypane ensures you never overlook this with its target box feature, emphasizing accessibility.

Target size

4. Color Picker: Have you ever come across a color on a page and wished to know its exact value? With the inbuilt color picker, you can do just that. And what's even more exciting? The anticipation of new color spaces like OKLAB being added.

5. Advanced Overlay: The level of detail Kilian has integrated into Polypane's overlay is mind-boggling. From highlighting headings, landmarks, and links to showing the focus order, this overlay is a developer's dream.

advanced overlay

6. Screenshot Editor: With Polypane's screenshot editor, you can annotate and download screenshots of multiple screen sizes all in one shot. Sharing insights and issues found with your team has never been this straightforward.

screenshot editor

7. Accessibility Analyzer: Ensuring websites are accessible is paramount, and Polypane's analyzer makes this task easy. Customizable to include best practices, it even celebrates your good work with a burst of colorful party flair! I'd love to see an added capability where developers can export results to share with teams and clients.

8. Editable Text Content: A recent discovery of mine, this feature lets you test components by editing the text directly on the site. How often have you struggled to “Edit as HTML” in dev tools? It's invaluable when you need to visualize how different content fits.

editable text content

9. Meta/Open Graph Panel: In the age of social media, visualizing how your content appears on various platforms is crucial. The Meta/Open Graph feature lets you instantly preview social shares in a single panel to see exactly how your content will look when shared.

10. Live CSS Editing: For those who find the constant back-and-forth between browser and editor time-consuming. This feature makes real-time CSS changes right within Polypane. Tweaking and testing selectors is right there!

Experience Polypane Firsthand:

For those on the fence about diving into Polypane, the good news is that there's a 14-day trial period available, with no credit card required. It offers an ample window to explore its rich features and understand firsthand the efficiencies it can bring to your development workflow.

The features I mention only scratch the surface of Polypane's capabilities. But beyond its stellar features, Kilian's dedication resonates with me. It's evident he pours his heart and soul into Polypane, and the continuous improvements are a testament to this. In supporting Polypane, we aren't just using an excellent tool; we're backing individuals like Kilian, who are on a mission to better the web and ease the life of developers. Innovations like these inspire and push the boundaries of what's possible. Thank you, Kilian!

Topic

Making Developers' Lives Easier with Notion

Notion logo

A busy web development agency such as Redfin Solutions wouldn’t be complete without cohesive productivity software. We use Notion, a fantastic organization application that serves as our home base for all things project management, note taking, client documents, and more. I wanted to take some time to delineate the ways that Notion has helped our company, and highlight some of its best features for making our team’s lives that much easier. Here are a couple features in Notion that we use at Redfin Solutions.

Databases - Board View

Notion’s board view, also known as a Kanban board, provides a helpful visual aid of a task’s progression. A board may be populated from an existing database or created from scratch, with the user manually entering information to each card. Notion’s boards offer visual versatility in allowing the user to opt for different views of the same data, including list or gallery views. Each card may be expanded to enter additional information, as well as possessing the ability to assign a card to specific users who have access to the teamspace. Redfin Solutions uses Kanban boards frequently for project management, client onboarding processes, and more.

Kanban board in Notion
An example of a database board view, or Kanban board.

Application Programming Interface (API)

At Redfin Solutions, we use a variety of different online services and applications to optimize our productivity and efficiency. Notion’s API makes our lives easier by synching data from other applications directly to our databases in the teamspace. A developer-specific instance is the API’s ability to synch GitHub issues regarding a certain repository directly to Notion. On the operational end of the company, API is utilized to integrate Quickbooks Online and Zapier, to name a few. Automating workflows and sales with Notion’s API allows all members of our team to save time and energy for other tasks. Thank you, Notion!

API diagram
A helpful diagram showing how APIs work. Source: Red Hat (https://www.redhat.com/en/topics/api/what-are-application-programming-interfaces)

Pages

This one may seem straightforward, but creating pages and subpages is the ultimate versatile tool when organizing processes, business tools, client profiles, and more. Notion’s pages are equipped with offering endless possibilities: from uploading a template, to populating data from a central database, it’s easy to keep things organized when everything has a separate page to refer back to. Below, you can see a snippet of a similar format that the Redfin team uses as its center of operations.

Pages grouped together in Notion
Creating pages under different categories easily optimises organization.

Artificial Intelligence

Following the latest trends, Notion has just released a new AI feature at the start of this year. While we haven’t been heavily using this since its release, its list of features is quite impressive. Notion has the ability to summarize a page of text, augment creative writing, improve note taking, and more. I hope to use these features when taking notes during meetings and writing processes for internal tasks, to name a few. Notion AI is available now for all users, and I’m excited to keep finding new ways to implement it into our workplace.

AI menu
Some of the features that Notion's AI offers.

Wrapping Up

We love this software and each one of us here use it every day. There’s a lot of similar brands to Notion available right now, but we like Notion for its ease of use, aesthetic appeal, customizability, and extensive features. We’re looking forward to many more projects made easier by this awesome application!

Topic

From Pune to Portland: Contractor Spotlight on Rishi Kulshreshtha

Portrait of contractor, Rishi

Meet Rishi, one of two international contractors here at Redfin Solutions. Rishi is a Drupal developer who started at our company in the summer of 2021. He currently resides in Pune, India, with plans to relocate to the United States in 2023! All of us at Redfin Solutions are so excited to have Rishi in-person at the office with us. I was so excited to speak with Rishi and learn more about his life in and out of the Drupal development community.

Rishi was born in Mumbai and moved to Pune in September 2015, where he still lives today with his wife and young son. Rishi recalls the day he moved to Pune with his wife for a new job opportunity, bringing along only a few bags of essentials. It took them years to adjust to the new city and way of life. He recounts on the realization that “every city and town is a charm on its own - you may like something, you may dislike something, but in the end, the city is the home that you’ll always respect and appreciate.”

Rishi and Hemangi on a balcony
Rishi and his wife, Hemangi, in Pune, India.

Rishi has been involved with web development for eleven years. Learning Drupal comes with a learning curve, as most Drupal developers know all too well. Rishi was trained in hard-code, but after garnering experience in various web technologies, he decided Drupal was his favorite of all due to the responsive and close-knitted community he had come to be a part of. “The slogan of Drupal is indeed true,” he says, “‘come for the software, stay for the community!’ That’s exactly what happened to me.”

Aside from Drupal core, Rishi has worked on a few modules to either resolve an existing issue or explore the possibility of a new feature in it. From the core, he contributed to layout builder. From the contributed modules list, he has worked on Hover Card, Socialfeed, Taxonomy Import, Google Analytics Counter, and Project Browser.

When Rishi was working at a previous company, there was a task related to Drupal migration. He was surfing the web for articles on layout migration, and found an article written by Redfin Solutions’ CTO, Chris Wells. This sparked Rishi’s interest in our company, and he researched more about our company and our presence in the Drupal community. The stars aligned for Rishi as he realized we were hiring at our company. “That was surreal,” he recounts, “without wasting any time I just applied for the position.”

Rishi was offered a contractor position with us in August 2021, and has been a fantastic teammate and friend of the Redfin Solutions crew ever since. “It has been more than a year now, but frankly speaking, every day here is refreshing,” he says.

Living in a different time zone, it goes without saying that there could be a few challenges. However, Redfin Solutions takes pride in its approach in offering employees and contractors a flexible schedule, allowing Rishi to work during India’s normal daytime hours. Through the power of the internet, Rishi is able to be more connected to our Portland-based team and clients around the nation now more than ever.

I asked Rishi what his favorite part of working for Redfin Solutions is. He replied, “the warmness of the leadership…[I] always feel welcome, be it some new achievement in my professional life, or a special moment from my personal life… they’re like a second family to me but 7,564 miles away!”

Rishi, Hemangi, and Ayan smiling on a street
Rishi and Hemangi with their son, Ayan.

Rishi plans to relocate to the United States to continue to work for Redfin Solutions. Although a massive leap and lifestyle change for him and his family, living in the United States has been a long-time dream of Rishi’s. He is ecstatic for a better quality of life, a better education for his son, and the experience to start life with a clean slate in a new country. Rishi is excited to experience the in-office culture with the United States crew. After collaborating virtually for so long, working in-person is sure to be a refreshing new experience.

Along with many others trying to make sense of the US visa process, Rishi recounts this being one of the more difficult parts of the move, but it has overall been relatively smooth. The coronavirus pandemic and ongoing wars have further exacerbated the swiftness of such a large transition, but Redfin Solutions has been working closely with Rishi and his family to make the process as easy as possible for all parties involved.

Rishi is looking forward to coming to the United States, and is excited to be immersed in a new culture. He says, “I'm sure my bond with Redfin is going to be [stronger] and it's going to be a life experience that I might share with my friends and family members in the future.”

Rishi and his wife, Hemangi, are planning to move to the United States in 2023 with their toddler son, Ayan. Hemangi is a Drupal developer as well, and we are excited to welcome her into a part-time Drupal developer position alongside Rishi’s full-time position at our company.

Ayan smiling
Rishi and Hemangi's son, Ayan.

As a last word, I asked Rishi what advice he might have to someone trying to get into web development. He says, “Don't be afraid of mistakes, it's human nature. Keep on practicing, and avoid shortcuts for the long run in the industry.” Rishi also recommends the following resources:

  • Drupal.org - because, of course!
  • drupalize.me - for understanding any concept in layman's terms.
  • understanddrupal.com - for detailed migrations.
  • DDEV - Chris Wells introduced this tool to Rishi; makes Rishi realize the drawbacks of using Lando & Vanilla docker.
  • PHPStorm - something he likes while working on Drupal projects.

Thank you, Rishi, for taking the time to talk with me and share your story. We wish you a very smooth transition and are excited to welcome you to our Portland office and to the United States.

Topic

Coding and Coronavirus: An Interview with Jessica Nolette

Meet Jessica, Redfin Solutions’ Junior Front-End Developer. Jessica’s journey to becoming a developer is unique and untraditional, catalyzed by the events of the coronavirus pandemic.

A lifelong Mainer, Jessica founded Flask Lounge in Portland’s West End in November 2007. Flask closed its doors for a year and a half due to the pandemic, rendering Jessica in a tough position, like many other business owners during this time. With a background in graphic design, Jessica took this opportunity to teach herself how to code.

In December 2020, Jessica began at Redfin Solutions as an intern and was hired as an employee in June 2021. Jessica’s story inspires others that it’s never too late to pursue a new career path, and obtaining a computer science degree isn’t the only route to follow to become a developer.

What first sparked your interest in developing?

“During college, I was a freelance graphic designer and did that while waiting tables to earn extra money. As clients needs evolved, I picked up doing web [development], so it’s been a while since I got interested in it.”

Was it hard to become a self-taught developer instead of going to school for it?

“My interest in developing was pushed to a priority when the pandemic hit because Flask was closed for a year and a half. I was temporarily jobless and saw it as an opportunity to find a new career path just in case I couldn’t reopen Flask. I had built apps in the past and was initially interested in being able to code and edit my apps, so that was my original plan in teaching myself. Then, I took a more structured foundation online course. Stanford had a Code in Place class which I had to apply for. It was six weeks of learning Python. I met with ten people from other countries twice a week, and we’d talk about coding assignments. This was a huge foundation course for me, and [Python] was really good to learn the basics.”

What advice do you have for someone learning to become self-taught in this field?

“Time spent at your keyboard determines your skills, not time spent in a classroom. It requires a lot of self-discipline, and you have to get over the fact [that you think] you’re not good enough or not experienced enough just because you don’t have a computer science degree.”

Do you find it difficult to balance ownership of Flask, developing at Redfin, and enjoying your personal life?

“I wouldn’t say it’s difficult. I’ve always been a learner and a multitasker, and able to balance keeping my family the number one priority and everything else is below that. Having a supportive family helps me improve my time and ambitions. I’ve worked hard to develop mindful practices to keep on schedule, and I’m extremely routined to help with how busy I am.”

What are some of the best resources you can recall using to learn coding in general?

“For me, it was Codeacademy and Wes Bos. I also took Stanford and Harvard online computer classes.”

Why did you decide to focus on Drupal specifically?

“I applied to the internship at Redfin [Solutions] because my friend, Christina, was a senior developer here. She encouraged me to take online classes, but to be honest, I had never heard of Drupal. If it had not been for Christina and the pandemic, I still might have never heard of Drupal. So, in learning Drupal now, it’s been mentorships and the Redfin [Solutions] team.”

What is your favorite part of being a developer?

“It’s an evolving practice, and technology is always changing…I love learning new things. I also enjoy the flexibility of being able to work from home.”

What is your least favorite part?

“It’s a blessing and a curse how quickly technology changes, so something you may have coded last week may not be the best practice for the following week. There are thousands of ways to code something, and I can get stuck down a rabbit hole of searching for the best way. Also, this is a good one, sitting in a chair all day and not moving around [or] giving myself breaks and walks. I get so into what I’m doing that I’ll sit all day and not move!”

Did you ever expect to be a developer prior to your journey to becoming one?

“To be an official developer is not something I anticipated pre-pandemic, but post-pandemic, it became my primary goal and focus. I wanted to prepare myself for a career change.”

Big thanks to Jessica for taking the time to share her story and impart some wisdom to aspiring developers.

Topic

Getting Started with Herman: Living Style Guides and Pattern Libraries

library with books in a pattern sorted by color

It all started with an innocent tweet:

https://twitter.com/mirisuzanne/status/948637526612324352

"Excited to announce our new open-source, Sass-driven pattern-library generator! Go design some systems!"

I follow Miriam on Twitter because I love everything she's ever done. At Redfin, we were huge fans of Susy, right up until she told us not to use it any more. And, like everyone else in the Drupal community and web developer community at large, we're hearing more and more about Atomic Design and the use of pattern libraries to build websites. We're encouraged to build and use canonical and living style guides. Many tools have come forward and, in the Drupal world, it looks like Pattern Lab has been a big winner.

At Redfin, we've tried a number of these tools, including Sam Richard's Style Prototyping approach, and attended trainings for Pattern Lab. We've also experimented with KSS for documenting Sass and generating a style guide.

Why Herman

What attracted me to Herman was the common predicament of the small-to-medium project and its budget's ability (or inability) to deliver on these prototypes. From the Herman announcement on Oddbird:

Creating the beautiful Salesforce Lightning Design System requires an ongoing full-time dedicated team. Those of us doing agency work don't often have that luxury, but our clients still need a system that will work for them.

So how can we make design systems part of an agile process – growing slowly along-side the application, the same way we write and maintain test-coverage as part of any project? How do we make documentation and design consistency the path of least resistance?

I'm a big believer in systems. That is, I'm a big believer in systems that work. If a human doesn't want to use a system because it's too much of a hurdle, the system has failed, not the human. So, the idea of "the path of least resistance" is appealing to me (or perhaps I'm just lazy but, nonetheless, systems should be built for the lazy).

So, Herman came along with all this promise and sparkle and I decided to give it a whirl. For starters, Herman is based largely in the foundations of SassDoc. SassDoc shares a similar purpose with KSS, though, having now played with it, I find its syntax just a bit easier to understand. Perhaps, since I've learned PHP Annotations for Drupal, the annotations in SassDoc feel natural.

Getting Started with SassDoc

To this end, Herman is actually just a "theme" for SassDoc. So, to get started, you are going to initialize a new SassDoc project. Like most of the front-end world today, new front-end projects are initialized using a tool like Yarn or NPM. At Redfin, we use Yarn, so we initialized our project using "yarn init" and answering the questions as appropriate.

Once we were initialized, we added in our two dependencies - SassDoc and the Herman theme:

yarn add sassdoc sassdoc-theme-herman

Once that finishes, you have scaffolded out a Herman project… kind of. What you now need is all your Sass! Create a sass folder to get started and put a style.scss file in there. We'll start with something simple:

.button { border-radius: 5px; background-color: green; color: white; font-weight: bold; }

Here's our first simple component we'd like to document. Maybe, if you were lucky, you had SOME kind of note in there before, like // typical button styles or something.

SassDoc uses a "three-slash" syntax to pull comments in as documentation. So, let's enhance that a bit.

/// Components: small, re-useable components used on the site. /// @group components /// @name Button /// @group components /// @example html /// <a href="#" class="button">Click me</a> %button { border-radius: 5px; background-color: green; color: white; font-weight: bold; }

The first comment, which is offset by a newline from the rest, is called a "free-floating comment." It's just "out there," and not attached to anything. However, note that using the "group" annotation (@group components) I was able to assign it to belong to a group. Using other annotations, like name and example, I'm able to generate my style guide (at the end of the day, just a static site).

To generate, you need to be in the root of your project and run:

node_modules/sassdoc/bin/sassdoc sass --theme=herman

And this gives you the following static site (find it by visiting /sassdoc/index.html off your site's root):

Moving On

Let's get something different put together, a little more advanced. Let's throw in a mixin.

@mixin embed-container($width, $height) { $ratio: ($height / $width) * 100%; position: relative; padding-bottom: $ratio; height: 0; overflow: hidden; max-width: 100%; iframe, object, embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } }

This mixin is inspired by Smashing Magazine's timeless article on the subject.

Now, let's annotate! Put this directly above your mixin.

/// Mixins: custom re-useable but configurable tools we use. /// @group Mixins /// Helper mixin to drop on the wrapper for an iframe /// that you would like to be responsive. /// /// @group Mixins /// @author Smashing Magazine /// /// @param {Length} $width - Element's width /// @param {Length} $height - Element's height /// @output CSS for the wrapper and the inner iframe that maintains the aspect /// ratio as it is resized. /// /// @example scss - /// .embed-container { /// @include embed-container(400px, 300px); /// }

The above documentation introduces us to the @parameter annotation, which allows us to document a parameter, its type, the name, a default value, and a description, using the syntax:

/// @param {type} $name [default value] - description

Also, note that we're not displaying markup here for our @example annotation; rather, we're using scss for the syntax to output. For mixins, this is incredibly helpful as it can show us what the compiled CSS is as a result of using this mixin! Let's go ahead and compile again (node_modules/sassdoc/bin/sassdoc sass --theme=herman).

UH-OH!

» [WARNING] Error compiling @example scss: no mixin named embed-container Backtrace: stdin:2 .embed-container { @include embed-container(400px, 300px); }

SIDE NOTE: In addition to being confused, I bet you're already tired of specifying --theme=herman on the command line every time, huh? Let's kill two birds with one stone.

Rather than specifying your Herman parameters every time on the command line, you can specify them in a JSON or YAML file. In that way, you then only specify -c /path/to/config every time. Of course, at this point, you're just robbing Peter to pay Paul. Switch one command line option out for another.

There's an even better option. Just name your config file .sassdocrc and put it in the root of your project and it will be automatically used. The entirety of that file (so far):

theme: herman

However, we haven't yet solved the problem of "no mixin named." See, the @example annotation from SassDoc doesn't natively support compiling Sass into its CSS counterpart. That's a gift from Herman. In order for Herman to compile the SCSS into CSS, though, each @example must be able to stand on its own, and this was the one area that really tripped me up. Thankfully, Miriam was there to help out.

To make this work, one option is to import the Sass file that we need in order for the example to stand on its own. Change your example to this:

/// @example scss - /// @import "style.scss" /// .embed-container { /// @include embed-container(400px, 300px); /// }

I'll save you some time before you run off ahead and compile--this still won't work. But, it's easy to fix. Go back to your .sassdocrc and specify a "herman" object with some configuration. (Full details on the herman object configuration.)

Make your .sassdocrc like this now:

theme: herman herman: sass: includepaths: - 'sass'

The includepaths directive is important so that Herman can resolve your import statements. Want to do one better? You can auto-import a path (or paths) using another declaration but, beware--nothing you auto-include should generate any actual Sass output or it will show up in EVERY example. This is best used for your utility files, like _extends.scss, _mixins.scss, etc. (Refer to our own Bundler Shell theme to see how we lay this out.) For example:

theme: herman herman: sass: includepaths: - 'sass' includes: - 'util/mixins'

If you auto-include your util/mixins (really ./sass/util/_mixins.scss) then you can make use of your mixins without needing to put the @import in every @example!

Another Side Note: README

If you are feeling harassed by "[WARNING] Description file not found: `./README.md` given." It's probably best to have a README.md for your project. This shows up as the text of the index.html page for the top-level of your SassDoc project. I just went ahead and created a simple one. This is a SassDoc configuration value, and if you'd rather create an introduction to your style guide that is separate from the main README for your project, you can set descriptionPath in your .sassdocrc file.

Level Up

This is all great but, we need to level up. What else does Herman offer?

No one can say it better than their own README:

In addition to the core SassDoc annotations, our @icons annotation allows you to display SVG icons from a given folder, and we extend the core @exampleannotation to display compiled Sass/Nunjucks output and render sample components. We also provide a @font annotation for displaying font-specimens, and @colors, @sizes, and @ratios annotations for displaying color-palettestext and spacing sizes, and modular ratios."

Icons

This one is easy so we'll start here. Add a comment and use @icons \<path-to-icons-relative-to-project-root> and you're there! It auto-generates your icon previews with filenames, even optimizing them as it goes. (Bear in mind your SVG's should specify a viewBox or they will likely be very, very tiny in the preview.) It expects a folder with individual SVG files per icon.

Font Stack Previews

Things start to get a little trickier starting here. For the fonts, colors, ratios, and sizes annotations, you will need to generate some JSON that the front-end JavaScript/templates can use. There's a plugin called sass-json that is doing this for you--taking sass maps and writing them out to encoded JSON--but you need to export your data in order to do this. So, let's dissect the font annotation first.

/// @font key (styles, to, show)

In this case, the ‘key' is the variable name of the Sass map holding the information about your font style, and the (styles, to, show) are a list of font weights/styles that you would like to display, for example: (regular, bold, bold italic).

Note that, at least for Google Fonts, the numbers are a more consistent thing to use when outside of the normal keywords of bold and regular. I didn't have success with previews using things like "semibold" or "light." (This is because they only support valid CSS values for font-weight - though there's discussion around that: https://github.com/oddbird/sassdoc-theme-herman/issues/250 ).

Finally, the second line is indented, to show that it's still part of the @font annotation, and it consists of any markup needed for the font to render correctly (JavaScript tag, link tag, etc).

So, in real life, this looks like:

/// @font sans-stack (300, 300 italic, regular, 600) /// <link href="https://fonts.googleapis.com/css?family=Work+Sans:300,400,600" rel="stylesheet"> $sans-stack: ( 'name': 'Work Sans', 'source': 'https://fonts.google.com/specimen/Work+Sans', 'stack': ("Helvetica Neue", "Lucida Grande"), );

For a web font like this, we use the name (that is, the actual font name you would use if you were to display it in a font-family property), source (this renders as an external link when the preview displays), and stack (which are the fallbacks you've chosen when this font is not available).

Getting that to render, though...

This is all the annotation related to the font, specifically, but now we need to include this Sass map into the "herman" map more globally. There's a handy mixin that Herman provides, called "herman-add" which we can use to do that. After the map, I put:

@include herman-add(‘fonts', ‘sans-stack', $sans-stack);

In order to use this herman-add mixin, you will need to include Herman's utilities (where this mixin is defined), so at the top of my file I put:

@import "../node_modules/sassdoc-theme-herman/scss/utilities/_utilities.scss";

Finally, we need to do a final export of the Herman map into JSON. At the bottom of my Sass file, I put:

@include herman-export;

This ensures that the herman map is exported to JSON so the front-end can pick it up. The Herman team is currently working on improving this process but, for now, this is still a pretty clean way to handle it. If you get a little cuter than I did with your partials, you can have a Sass file that only outputs the herman map JSON so you don't need to pollute your regular CSS with it if you don't want to.

Keep this pattern in mind, because most of Herman's awesomeness depends on it. You'll see as we move on.

Colors

Now that we've established a pattern, we're keen to keep following it. For color palettes to be generated in your SassDoc static site, we'll follow a similar pattern. First, the annotation:

/// @group colors /// @colors demo-colors $demo-colors: ( 'alto': #d8d8d8, 'scorpion': #5b5b5b, 'tree-poppy': #f36c38, 'white': white, 'wild-sand': #f5f5f5, 'grey-light': #d5dbe4, ); @include herman-add('colors', 'demo-colors', $demo-colors);

First, I use the @group annotation to put this in the ‘colors' navigation over at the left. Then, the actual @colors annotation puts the map key you're going to use to add to the Herman map. We add those colors in a map, and then finally use herman-add to map $demo-colors into $herman. In this way, the herman-export we call at the very end will ALSO now include this color palette in the static site.

Sizes

For text sizes, a great preview can be generated to show you the various headings or sizes you want to use. Sense a pattern yet? Let's look:

/// All the sizes that we have. /// @group sizing /// @sizes font-sizes {text} $font-sizes: ( 'base': 16px, 'important': 1.8rem, 'largest': 3rem, ); @include herman-add('sizes', 'font-sizes', $font-sizes);

Ratios

Ratios behave nearly identically:

/// Ratios we are using. /// @group sizing /// @ratios my-ratios $my-ratios: ( 'line-height': 1.4, 'gutter': 0.5, ); @include herman-add('ratios', 'my-ratios', $my-ratios);

The only thing to know is that you can optionally display text sizes (or spacing sizes, or page sizes) as rulers, though the default is to display a text preview. To do this, add the optional "{rulers}" or "{rulers-large}" after the sizes annotation (rather than "{text}" - which is the default).

Nunjucks - Martial arts the templates up a notch

For markup that is more complicated than some simple HTML, you can write a Nunjucks template to generate output for a preview. Let's enhance our button example with a Nunjucks template.

/// @group components /// @name buttonset /// @example njk /// {% set items = [{"name": "do something", "label": "open"}, {"name": "do something else", "label": "close"}] %} /// {% include 'buttonlist.njk' %} /// .buttonset { li { display: inline-block; list-style-type: none; margin-right: 1em; } a { display: inline-block; @extend %button; } }

You'll notice I still put this in the components group but I've turned my regular button into a buttonset. You'll also notice immediately the @example annotation this time specifies the "njk" syntax, meaning "compile Nunjucks code." When using njk in an annotation, you are required to specify a templatepath in your config. (Alternatively, you can specify an entire Nunjucks environment, but to do that you must be using the Node API version, which I am not.) Add this to your .sassdocrc inside herman:

nunjucks: templatepath: './templates'

So, I created a "templates" folder off the root of my project and put a simple buttonset.njk file in it. (Dear Drupalists, don't be scared of Nunjucks--it's Django/Jinja-based templates for JavaScript, just the same way Twig is Django/Jinja-based templates for PHP!)

{% block content %} <ul class="buttonset"> {% for item in items %} <li><a class="button" title="{{ item.name }}">{{ item.label }}</a></li> {% endfor %}` </ul> {% endblock %}

Now that I've configured a templates directory, and my syntax for using the templates is all set up, I get a fully rendered example. It includes (a) the Nunjucks language used to generate it, (b) the fully compiled HTML markup, and (c) a fully rendered example with all of my styles!

For bonus points, check out Nunjucks macros, which should help you further componentize your markup into easily-reproduced snippets. If we do it this way, we can sort of reverse the order. First, we import our njk file which defines our macro:

/// @name buttonset /// @example njk /// {% import 'buttonset.macro.njk' as mymacro %} /// {{ mymacro.buttonset([{"name": "do something", "label": "open"}, {"name": "do something else", "label": "close"}]) }}

...and our Nunjucks template is slightly different, wrapping the block with a macro call. A macro is similar to a "function."

{% macro buttonset(items) %} <ul class="buttonset"> {% for item in items %} <li><a class="button" title="{{ item.name }}">{{ item.label }}</a></li> {% endfor %} </ul> {% endmacro %}

The Power

So, by combining all of these elements directly into the Sass you're writing for your agile site, you can document on the fly and have an easy way to:

  • Reference and document your mixins
  • Display typography stacks and document when you should use each
  • Show heading sizes and spacing ratios for vertical rhythm
  • Discuss branding color palettes and describe how each should be used
  • Demonstrate the icon set available to the application quickly
  • ...and so much more!

The Review

So what do I like and dislike about this? What did I learn?

For someone like me, a lot of this was actually quite new coming in. Not just the fundamental concepts that Herman brought, but all of it. I had never used SassDoc before, though I'd played briefly with KSS. I'd never even heard of Nunjucks before, though I had used Twig. But also, the concepts that give Herman its power also add complexity to an already complex stack. You need to remember that, in a sense, everything is compiling twice. Once, it's compiling your Sass to be output (and then you're bringing that output into the static site via custom CSS), but it's also compiling all the SassDoc comments into a static site as well. These two different steps are nonetheless sourced largely from the same files, so all the pieces of the puzzle feel like they need to fit together just right for everything to work in harmony. Once that was fundamentally understood, the idea of the JSON encoding actually made total sense, and was OK to understand.

I also spent a lot of time getting bit by the Ruby bug. At Redfin, we sort of skipped over the whole Gulp / Node API thing. We used a lot of Ruby Sass and Compass and Bundler, until we recently switched to a stack based on Dart-Sass. While trying to learn, I tried to strip everything down to its fundamental elements, and that actually got me a few times. I should've started with a modern stack and used the node-sass implementation that I installed with my yarn install, and I wouldn't have had such issues. (With that said, we never would've improved Herman to support Ruby Sass!)

Overall, I believe that this is definitely good enough to go into our next project. Beyond that, I am confident in the Herman team that if I find any bugs as we use it, they will be responded to swiftly, which is hugely important for adoption of something kind of new like this.

UPDATE 04-09-2018: Added additional clarifications from Miriam.

 

Topic