 Welcome to Style Documentation for the Resource Limited. My name is Betsy Hebel and today we are going to be talking about ways to get style guides done in the real world as opposed to the happy fairy world where you actually have three months to take to stop the world and do this. And so whenever you're getting things done under resource constraints, be it making a style guide or anything else, you need to follow some basic steps. First off, you need to have a thing that you're aiming for. If you don't have a vision where you want to go, you're going to track back and forth and you're going to kind of fiddle along. Second, you need to figure out baby steps that will get you there. And then you need to scale these baby steps a bit further down. You're always going to really overestimate how much you can get done in any given baby step at first. And so be realistic. Take a few times to go, no, really, I'm going to have 20 minutes a day to devote to this. What can I do in 20 minutes? You're also going to have changing circumstances to adapt to. If you're taking 20 minutes a day to do this, then you're going to be coding and your teammates are going to be coding for a lot more than 20 minutes of those days. You need to hit for a moving target. So nothing is going to really be quite what you expect at the end. The vision that you have at first is great. It keeps you motivated and it keeps you focused. But resign yourself to the fact that that's not what you're going to get. What you're going to get is something that's actually kind of cooler. Then you go do the thing. So this is the vision. What we have here is the 18F style guide. 18F is a division of the US government. I like this as an example style guide because 18F is a collection of small teams that consults for other government agencies. I could use other examples like Google's material design here. But since material design is built for Google scale companies and since most of us do not work at Google scale companies, something like this that's a little tinier is a bit not only more realistic, but also more adapted to our specific needs, not Google's needs. We talk a lot about getting everyone on the same page where our business logic is concerned. We talk about developing a shared ubiquitous language that we can share with stakeholders. But the thing is we need a separate shared ubiquitous language for our user interface logic. When we are doing web development, we distribute this user interface logic through the HTML and CSS and JavaScript and keeping this organized is not actually an easy task because it's so distributed. This coherent model that we're going to build is what lets us do that and not go insane. Goodness, that's ablest language. I'm sorry, guys. And the thing is you already have an accidental style guide. Your accidental style guide is your code base. All of your forms look basically like each other, I think, probably. And this is achieved via liberal use of copy and paste. This is great if you've got a small team or a small UI or anything like that. But as you scale up, it gets a little trickier to deal with. You start onboarding newer developers and they don't know what to copy and paste from. They don't know what the right parts of the accidental style guide are. Rails gives you a lot of really useful structures for organizing your business logic. Not as many as some people would like, but enough. If you open up a new Rails app, you know where the controllers are going to be and you know roughly what they're going to do. The same is not really true if you code. Every shop has its own funky little way of doing it. And that's not transparent. Also, realistically, stakeholders who are not you, especially designers, are going to have a lot more opinions about the results of the view code than they are about the results of business logic. They can see it. It's easy to talk about and easy to think about. So there is an example app. I'm going to be turning into it a few different times in this talk. When I talk about a coherent model of the user interface, I want to again stress this is about looking at repeated user interface concepts. These are not in the context of the user interface domain cat photo modules. Their cards are showcases. The reason I'm making this distinction is because a designer might want to reuse the same concept to display dog photos. Or they might want to reuse, or you're probably going to also be displaying cat photos in another way and if you're making a cat photo sharing website. Style guides should also go a little deeper than your branding guidelines. A lot of people go, okay, we use Helvetica and stop there. But a style guide can give you a lot more. You can talk about the look and feel of individual widgets. This tends to be as much or more about the affordances of specific components as it is about their aesthetics. You can talk about how they're arranged. Are the labels next to the form fields or on top of them? Where do error messages go? We can also talk about what UI problems are given which is useful for solving. You can say use carousels if you need to display several bits of cards, but otherwise just use a grid. Or you can say only display notifications if they're relevant to the user's current goal. And this is going to look basically like the bootstrap documentation when you're done. So you might be thinking, this is overkill, we just use bootstrap. Just is a really funny word in software development. It is usually a marker for someone trying to push their assumptions on you without realizing it. And the thing is none of the people who have ever pushed back and said that to me were actually just using bootstrap. If you think your shop just uses bootstrap, I'd like to ask yourself the following questions. Are you using all of bootstrap or just a subset? Are you only ever using bootstrap or do you have custom UI elements that aren't part of it? Do you have undocumented bits and pieces of code or rules around how you're using the bootstrap elements? And again, most importantly, you often copy and paste markup around to preserve these undocumented rules. That's the most useful real-world heuristic I can give you. And so if any of these statements are true about your site, your style guide is not the same as the bootstrap documentation. I'd like to encourage you to document the ways in which it's different and you don't necessarily need to be super fancy about this. It can be annotations with links that say more docs at this link. This link happens to be the bootstrap docs. But still, documenting these deviations is very important. There are a few other barriers to style guide adoption that aren't just, oh, why do we need this? They are, it's a lot of work. They are, it's a lot of work and my boss will not let me do this because it's a lot of work. There's also a few fuzzier ones. If you build your style guide very inflexibly, it's not going to accommodate a real-world user interface very well. Similarly, you might have a designer who believes in a lot of exceptions to the rules rather than just a few. And finally, if you make a style guide once and then assume it's set in stone, it's going to be just another set of dead documentation. It's going to slowly drift away from reality. We live in the real world. Our software is held together by Love and Duck Tape. And I say we for a reason. Like probably most of you, I'm a veteran of the, we can always make it better tomorrow, School of Agile. And because of that, I can tell you that actually you can do this incrementally. You can get this bright, shiny dream world in the real world. The first thing we need to do is let go of the idea that a style guide is ever going to be done. It's in 15 years since the Agile manifesto. We have all embraced a notion that our software is iteratively built and never quite finished. It follows that our documentation, like the code at mirrors, needs to be responsive to changing needs, needs to be malleable. I've worked with a style guide before that was this pretty thing that the designers went off in a room and built over the course of a few months. It was great for about five months after they finished. But then the lead designer left and we replaced them. And our new designer went into another room for another two months or so, and built us a new style guide and it was beautiful too. But we are suddenly faced with this dilemma. Do we stop the world and migrate to this? Do we leave our user interface inconsistent state? What do we do? And none of these options were great for our users and a lot of them involved us taking time to not ship code. So when we view these things as perfect versus worthless, when we hold up this perfect ideal in our head and expect that it's actually even all that useful in the real world, we suddenly stop doing iterative processes because we think there's no point. The history of industry has proven time and time again that iterative processes work much better than stop the world processes or heaven for fend, never doing anything at all. Who here has written brownfield test suites before? So taken a uncovered or under covered code base and written some tests around it. That's a lot to your hands than I expected. You're all really lucky because when you do this, this kind of sucks. You tend to pick one UI path and write an integration test for it. Or you pick one method in one class and you start writing unit tests for all the cases and it's really, really terrible. You do it for features you're working on anyway at the time, but it's still really, really terrible. You're trying to maintain some kind of velocity in your feature. And you don't have any kind of proper test harness. You're needing to build that simultaneously. And so you kind of fake it and go, good enough, maybe, and move on. But the next test after that, still not fun or anything, but it sucks a lot less. You already have a minimum viable test harness in place and so you can just write your test. Or you can maybe even flesh out your test harness a little and make it a little more full featured. And eventually it gets easier and easier and easier and then it gets easy. And that is the greatest feeling. And I'd like you to think about Brownfield Style Guide documentation in the exact same way, because it is the same thing. The great news about looking at Brownfield Style Guide documentation, like Brownfield testing, as an iterative process, is that lets us sidestep many of the real world concerns I outline for you about style guides. It also forces us to figure out a set of baby steps that lets us maintain velocity while we build out our style guide. It forces us to make things a little bit better with every little baby step so that we can prove to our teammates and our bosses that this actually is worth doing. And it forces us right away to grapple with the dead documentation problem. If someone didn't stop the Royal Doc project and released on April 27th, 2014, I know coming into the project that it was relevant then. I can adjust my mental model of how accurate it is based on like some mental heuristics around code entropy. So if I'm coming to that project circa May 2016, I can know that probably many of the database tables are about the same. They might have a few more columns, but the general structure's still there. But I can throw out anything the documentation says about the controllers as completely irrelevant. However, if I have bits and bobs of documentation that don't have dates on them, I don't really have any way of knowing how useful any given piece of it is. So the second it starts to drift away from reality and I notice it's inaccurate. I can't make the same value preserving code entropy type guesswork because I don't know when it was accurate. And so I just kind of need to dismiss the entire thing. So again, we need to solve the documentation problem really very much first. But it also lets us sidestep the flexibility problem. When we document what we've already got and leave the rest of it for late and leave any kind of organization for later, we know our style guide covers real world use cases, yay. So I'm going to teach you a three step process for getting a style guide up in currently. We're going to use three steps over and over and over again in which we identify UI component, codify it, and then document it. Step one, identifying is super easy. We just look at our app. When you look at these screens side by side, they've both got pictures of cart or they've both got cards on them and they've also got tab sets. So if we attack tab sets first, when we get to the step, reformalize these components and code. When we do this, we try to refactor what you've already got to me and more internally consistent. This sets us up to document it later. And it also helps us sell this process to the rest of our team. We can't always say this new process changes in documentation is going to be magic and solve all our problems because we don't have, our teammates cannot be expected at that point to have context for why this is magic and why this will solve their problems. But it is very easy to say, hey, I improved these five lines of code and get people to say, yay. So this is going to be something we use to help build trust as well as set ourselves up for success with documentation. So as a heads up, we are hitting the code on slides part of this talk. It's the last day. It is after lunch. I'm really sorry. Please just focus on the broad outlines. Most of the slides have helpful bright red circles on them to point you to the interesting parts. At the end of the talk, I'm going to be giving you a link to a blog post and it's going to have all the code samples in it. So you can look up every bit of code on these slides later if you want reference. Please, again, think of this as a general overview. It happens to include code. And of course, this slide has no helpful red lines on it. But also, I'm mostly just throwing this up to show you unrefactored code that's kind of repetitive. And I'm going to skimp past it and overlay these two things. And gosh, unrefactored code is really repetitive sometimes. This is an overlay of those two things. Note that you can't really tell because it just looks like text. And because this is a Rails project, we're going to use a helper to refactor this. Note that I'm putting the output at HTML in a comment directly above method name. This makes reading the method quickly much easier. It gives you a literal representation, which can be a lot easier to read than content tag. It's a lot easier for your designer to read than content tag because your designer knows HTML if you're lucky, but is not going to learning Ruby, probably. And also helps you search for code more easily in large projects, which is a lifesaver. And so we move our tab code to use that helper. It's nice and pretty, yay. Look how nice, look how short. This is what your code base actually looks like, right? That's okay. Five years ago, front end Betsy was a bit of a snob and probably would have not said this is okay, but I was wrong then. Market frameworks like Bootstrap and Foundation, which are what's going to usually give you these huge sets of classes, are really useful rapid prototyping tools. And in the real world, it's fine that you don't always have a chance to go back and make your prototype nice. Also, five years old front end snob Betsy when she said, ew, a presentational markup was actually missing the thing that's really wrong with this. When you look at these two examples, the semantic versus presentational nerd fight obscures the actual difference between them. The first one at the top is us using the markup to list out a collection of attributes that the tabs have. The second is us condensing that set of the attributes into a useful abstraction that builds out the shared ubiquitous language of the user interface. And so how do we get from one to do quickly? We cheat. And this cheat, incidentally, is great even if you're not necessarily as comfortable as CSS. If you're using Rails, you probably already have SCSS installed. And that's a markup preprocessor that gives us a few different options like Mixins, placeholders, and classic stems that we can use to include existing CSS classes into new ones, much like Ruby modules. So all we really need to do here, at least on the first pass, is make a parent class that encapsulates the concept and then just sling all the CSS more detail classes into it using class extension. This is not the world's prettiest SCSS, but again, it's better than what we had before. And in a lot of ways, that's all that counts. Generally, this particular approach is pretty safe. The fact that we're making a new parent class helps us limit the area of effective refactors. But sometimes, an abstraction requires a few nested tags, and you can't collapse them quite this easily. And you maybe can't fix them how you have. Or maybe you do try this approach and something weird happens with the cascade because CSS is a very global oriented language. And then you go, no, and back up a bit. In that case, the next most heavyweight mitigation technique I have for you is building a nested helper. This is starting to get into the end of code that's clever for clever's sake. So if your markup is simple, it might not be practical. Abstraction is really only useful when the thing you're abstracting is complex. So, yeah, sorry. Helper nesting looks like DSL magic from the outside, but it's the simplest possible form of Ruby DSL magic. What we do is we build the outer tag and then say this inside is going to be the content of a block that's passed to it. Then we yield control to that block. But what if you've got something even more complex? When we look at these screenshots, these are both cards, but they're really different kinds of cards. And so you need a lot of configuration options. When I was a much dunger developer, the way I would do this would be like the mega helper approach. And I'd be really proud of myself because I was making fewer lines of code. But it would be a really bad abstraction and I would not be able to read it four months later. Helper nesting can help with this. But when I look at this particular instance of helper nesting, I wonder how to make it clear that the body methods are really only ever intended for use within the parent method. I can hope the people look at this code and get it. But if they guess wrong, then the errors might not give them useful feedback. On the other hand, when I'm trying to solve this problem for my coworkers, I need to make sure I'm not building some huge non-railsy thing. Because no one wants to learn the hipster Betsy framework that's not documented. And so what I do is I take form four as an inspiration and form builders. I'm not straying super far from the Rails way here. I'm leveraging its metaphors so that you can use them to understand this code. And this is great. It helps me sell this code to my teammates. If code does not improve my teammates' lives immediately, I'm not going to get buy in for that code, nor should I. We don't need to change the pattern we're using all that much. We're still using the build a thing and then yield control pattern. It's just that instead of building one parent tag, we're building an object that knows how to render the entire component. Note that we're passing in the view context. This is the class all helpers are included into when you build a Rails view. We grab it using self and inject it into the component builder. There are a few different schools of thought about how you're supposed to inject view context into non-helper things that use views. And I like this method, it's least magic of them. Little verbose, but no magic and that's good. Your basic component builder is going to have three major parts. Initialization, a rendering shell, and a collection of sub-renders. The only thing you need to do in the initialization step is grab the view context and stick it in an attribute. I'm using H for that here, which is convention I borrowed from Draper. I usually hate single letter variable names, but here the convention lets us focus on all the times we call content tag or link to or other actual methods. If we're just typing view context over and over it obscures what's important about the code. The other thing you can do if you need to in initialization step is configure top level CSS attributes or repeated text or stuff like that. In general, we want to keep this configuration pretty lightweight. We want to push the bulk of the work to the sub-renders. So next we build a render shell. This looks remarkably like the parent of a nested helper. It's the exact same thing. And so again, we're just building out the outer tag and then we're yielding control to the block. The sub-renders are going to do the bulk of the work. They're going to output all of the different bits that form the main body of the component. And note that again here, we're still adding comments that illuminate what the markup generated is so that we can anchor ourselves. I personally find code that's very content tag heavy hard to read. And this is a great way of removing that layer of abstraction temporarily so I can focus on what's going on rather than what this code is doing. Again, when we've got this all assembled up, the way we implement this in the view looks a bit like this. When you are testing these, please use Noka-Gerry or pick your XML parser, I don't care what. You're going to be tempted at first to try to test them using plain strings, or maybe regex that matches against those plain strings. And that's going to be really, really brittle. It will seem simpler at first. It will not be simpler in two months. Learn from my mistakes. And again, all of these techniques I've shown you are in many cases pretty heavy weight. You don't always need to find a nail for any given new hammer. If your gut tells you at least techniques are overkill for your project, trust your gut. Once you finish codifying a view pattern, the next and final step is documenting it. And this is super easy because we've made these code comments and you start the documentation for us. For bonus points, what you can do is you can use RDoC's include directive to link to any given partial or so that you might be using within your code. And those will actually be inlined into RDoC by magic, which is a really great way of making your documentation auto-update. And auto-updating documentation is super important because then you do not need to actively maintain it. And it can stay reliable without further input from you. But only your developers are ever going to look at your RDoC, probably. We want a communication tool that lets us communicate with designers and maybe even other stakeholders. We want something like this. Luckily, it is much less hard to build than you might think looking at this like nice finish looking thing. Since this is style documentation for the resource constrained rather than style documentation, happy unicorn fairyland, we need to ruthlessly prioritize what we're going to include on the first pass. The great news is that that's not that much. There are two real world use cases that this document is actually going to be used for. We just need to make something that encompasses both of them. They are a developer's skins, or a developer is given a wire frame and skins through the style guide for a plausible looking element, which they then copy and paste into their current working code. The other is the designer and developer are talking and they point to things. And so given these use cases, our minimum viable product just needs pictures of components and example code for those components. Anything else on top of that, like use case descriptions and et cetera, is great, especially if you've got a larger team. But you don't need to do that in the first pass. And I advise you to not do that in the first pass and burn yourself out. There are a few different tools we can use to do this. My favorite tool for doing it in Ruby is a tool called hologram. It's a gem, just install it like normal. The best tool for you, if you're using a JavaScript heavy front end, like Angular, Ember, React, whatever, I think that's what the kids these days are using, is going to be a tool called KSS. You want the node version of KSS, and you want this for two reasons. And one of them is that the node version of KSS is actually the only version of KSS that has a lot of the features I'm going to be talking about as important later. The other is that your style guide generator language always wants to match your view implementation language. So I'm going to be using hologram in all of my code examples. This is RailsConf. It works by a little like our doc, really. You put special documentation comments in your CSS files, and the processor turns them into documentation. Putting your docs in your CSS, or someplace else central, is a great little nudge for your tree mates that keeps documentation from dying. It's really easy to forget or deprioritize documentation when you keep it in docrandomstuff.markdown. It's harder when it's right above the code you're working on, yelling, I'm here, fix me. You're going to feel really guilty if you don't. And so a good style guide generator is also going to give special status to your code examples that can get showing you here. Hologram's output looks a little like this. You're getting a super happy little picture of a card right above the code that makes the card go. We're fulfilling both of the needs of our style guide MVP right in one tool. It gives us both of these by not magic, but writing. We could stop here, but we can also get a little better. We've built out all these cool few helpers that codify our abstractions. And hologram processors are just executing Ruby, just like KSS node processors are just executing JavaScript. And so we can put our helpers in these examples. This takes a little bit more work to set up. It's a little finicky. It's a little Rails version dependent. It's too much code to be worth putting on a slide, but it's linked in the blog post that I'm going to be showing you later. If you can do this, I advise you to. It is super magic because then your markup changes when you update your helpers. All of these changes automatically propagate to your style guide. And so again, you don't need to do as much maintenance work going on. Living style guides are way more important and are way more useful than the kind that you set and forget. So the ideal is something that looks a little bit like this. Note that the example both outputs the HTML that the helpers generate and the helpers themselves. This is really important for helping out designers. It lets them prototype rapidly using your actual style guide primitives. And they can do this even if they're not necessarily that comfortable with code because it's right there for them to copy. And I'm going to describe something for you that you think will never have happened, but it has happened to me multiple times. And that is that a designer actually does make one of these prototypes. And then the designer comes to me and gives me this prototype. And I go, hey, I'm just going to wire this up really quickly. And it goes really smoothly and it goes really wonderfully. And then I notice something that's not quite right. Like there's a little bit of content that works differently in the real world than it did in the designer's happy, lorem ipsum. I'm going to make things up world. And so then what we can do, because we have this shared understanding, because we have this shared code that we have built out and documented, is we can pair on how to make things better. We don't need, we get to lose that process where a designer and a developer start yelling at each other in JIRA or giving passive aggressive once every three days comments in JIRA about impracticality and ugliness because we can just go and talk to each other. And we've got this mediating document that helps with that. It lets us work in this really fast, happy, user-oriented way. And it's a lot more fun if you're doing that. If you have a style guide that lets you collaborate really effectively and happily and then it doesn't matter if it is a messy and ever-changing working document. Honestly, I think that kind of helps. It means that it's accessible and it means that when we need to update it, then making those updates is accessible rather than something we need to treat as a big deal. So if you take one and only one thing from this talk, it's that that is the goal and it's that you can achieve it. The one core truth in the Vagel is if it works for your team, roll with it. It's important to understand the building blocks of UUI. It's important to use abstraction to effectively manage those building blocks. It's important to constantly communicate about what those building blocks are to keep everyone on the same page. Whichever methods you use, you can get to the stream. You deserve to get to the stream. Good luck. So here's a link to both the blog post with code samples and a blog post from Pivotal that helps use that hologram up with Rails in some nice ways that keeps guard that uses guard to auto update things. This is me. My name's Betsy. I'm on the internet in a few places. My Twitter is mostly feminism in pictures of my cat and occasionally science fiction and occasionally also code. I work for an organization called Act Blue. We build fundraising tech for Democrats and we amplify the voices of small-dollar donors. Our average donation size is about $30, and since 2004 when we were founded, we have raised 1.1 billion. About 1.1 billion of that has been in the last one month, two months alone. Like about that, okay. And this helps these donors' voices be heard in a real way by aggregating it. So it really helps us keep the party more focused on the needs of people who don't have huge sums to donate. It means a lot to me. We're committed to a modern web development stack and a culturally and technically sustainable approach. And we're hiring. Please talk to me or to my boss who's going to raise his hand now if you're interested. I'd like to thank Coreline, Ada MK, Chris Hoffman, the people of Arlington, Ruby, and Zeal and Act Blue for all giving me feedback on early versions of this talk and helping me make it hopefully good. Any questions? Absolutely. And I'm going to be tweeting out this, tweeting out the link to right after I step off the stage. We are located in Massachusetts, but we're very remote-friendly. I live in D.C. We probably have more remote developers than non-remote at this point, and it's a great remote culture. I can say that from experience. Cool. Thank you for coming.