cfpb / capital-framework Goto Github PK
View Code? Open in Web Editor NEWThe Consumer Financial Protection Bureau's user interface framework
Home Page: https://cfpb.github.io/capital-framework/
License: Creative Commons Zero v1.0 Universal
The Consumer Financial Protection Bureau's user interface framework
Home Page: https://cfpb.github.io/capital-framework/
License: Creative Commons Zero v1.0 Universal
Originally posted by @himedlooff.
I know this is generic sounding but maybe we can focus this to something like "make bower compatible"?
Should we emulate topcoat.io's organization where modules are separate repo's?
Misc research
VIDEO: Nicolas Gallagher — CSS Application Architecture (SmashingConf)
The current state of the Web platform makes working with, and maintaining lots of HTML and CSS a painful task. Even modestly-sized applications can quickly end up with tens of thousands of lines of HTML and CSS. And dozens of developers may need to work with the UI code on a daily basis.
Without an HTML/CSS application architecture, things can quickly get out of hand. This talk will look at the design of the SUIT framework, and the use of tooling to support and test HTML/CSS development.
Another idea to centralize docs for all components and the master repo is to create a Capital Framework doc site using DOCter. Within this site we can centralize a lot of the info that is duplicated across each component README and CONTRIBUTING files. This would save us a lot of hassle if we need to make doc changes that affect all components because we would only have to change it once. Of course this means an initial change to all components where we slim down the README and CONTRIBUTING and add in links to the docs site but it's worth it in the long run.
Content to add to docs site:
Then edit each repo to link to the docs instead of duplicating information (with the exception of TERMS and anything else that should stay).
In order to properly test individual components we need a test page in each one. This page will be used to test acceptance criteria.
We'll need
Notes
You know what I mean. 😉
We've been using filenames like
typography.less
andbuttons.less
. I recently accepted a PR from @contolini where he usedcf-expandables.js/less
.What's the benefit of adding the prefix?
With jquery plugins I'm used to including the entire plugin's name in the filename but since expandables is part of a larger framework the prefix probably isn't necessary.
I dunno, seems kind of smart to add it. Incase they get thrown into a folder with a bunch of other scripts/stylesheets then there will be less potential conflict.
/shrug. I don't have a problem with it.
Aight, let's do it.
We need to figure out how we should handle dependency versions.
Steps
latest
, ~
, or a pinned version number in Capital Framework for both Bower and NPM. Decision: use ~
Because integrating the framework's build process (i.e., its Gruntfile) with an existing project's build process could be very messy.
It also ensures that updates to the framework's build process don't need to be manually integrated into the project's build.
Ultimately, this should make the integration step very simple: adding a single new Grunt task to the project's Gruntfile and setting options to fit the project's needs.
Inspiration:
We need both CSS and JS linting. There is an open question on when to run them. The options we are considering are:
grunt compile
Research
If people are interested in creating new components it would be nice to have a prioritized roadmap along with an inventory of older code that has already been written that could potentially be leveraged.
For example here is a list of JS Components pulled together by @danny8000 that we have written at the CFPB at one time or another:
It would be nice to describe what the tasks are doing so others can modify/tweak this repo for their own projects. For example in the Workflow section of the readme, step three says:
grunt vendor
– Pulls in Bower components.
This is good enough for the readme but there needs to be further explanation. For example this task also routes vendor assets for you, concatenates all of the cf components, rewrites img and font asset locations, etc. This is useful information to know and documented on our docs site.
Ideas for explaining the tasks
bower-install
exportsOverride
section of bower.json
into the demo
folder.concat
copy
demo
folder during the bower-install
task into the docs
folder....
See http://cfpb.github.io/capital-framework/
min-width
rules)I wonder what the best way to track pull requests for all these repositories is?
Ideas:
The main question:
Is script dependency something that we need in Capital Framework components, or is it something we only need in the Capital Framework demo when illustrating usage of our JS components?
Originally posted by @himedlooff.
https://github.com/nDmitry/grunt-autoprefixer
This will give us a much higher level of consistency between components when it comes to vendor prefix use.
To make debugging easier. This is now supported in LESS 1.5.
Explain how we are using gh-pages
via the grunt gh-pages
task.
Related: #22
As we want to distribute zip files for each release, we should think about using Grunt to create the releases via the GitHub API and eliminate the need to upload the file through the web interface.
This might leverage an existing task like grunt-release, or it could be an extension of grunt-cfpb-internal. I probably favor the latter.
Relevant issue on the Font Awesome repo: On IE8, font disapear when refresh
Comments in the minified JS files are excluding important comments (comments starting with a bang).
Each component has their own docs page, is there a way to tie them all together?
Ideas
Yeoman will allow you to construct a new project quickly so you don't have to cobble together all of the pieces yourself. By pieces I mean things like getting the latest jQuery, getting the latest modernizr, creating grunt tasks, pulling in frameworks and dependencies.
Yo scaffolds out a new application, writing your Grunt configuration and pulling in relevant Grunt tasks that you might need for your build.
http://yeoman.io/Yeoman builds upon a number of open-source tools to offer an opinionated workflow that helps developers achieve common tasks more easily. Grunt.js is one of these tools and powers our underlying build process and task plugin architecture.
On top of this architecture, we've highly customized tasks, profiles and systems which work well together and also provide developers with features like our generator system and Twitter Bower integration. Yeoman takes care of configuring your Gruntfile and setup to support Sass, CoffeeScript and Require.js/r.js out of the box. With additional features like wiring, an improved server and init, we like to think of ourselves as a helper project on top of Grunt.
Developers are free to continue using any Grunt tasks with Yeoman and there should remain a good level of cross-tool task compatibility.
http://yeoman.io/faq.html
Yeoman plans to completely subsume grunt-init
gruntjs/grunt-init#31
Generators are instructions on how to scaffold out a type of project. There are many existing generators but you can create your own to meet your needs. You can also create sub generators to scaffold out common templates that might be needed within a project.
The instructions mention a dist
folder but I can't find it. Should it be here?
Also then there is a mv front-end my-project
which I believe should be mv capital-framework my-project
(Links to internal URLs have been removed.)
js/
and css/
/dist
folder/dist
/dist/vendor
folderAs of version 1.4, LESS supports extending a style. Extend is sort of like the opposite of a mixin. Instead of adding all the properties of a mixed-in class into a class, it adds the extending selector to the selector list for output of the extended class.
The syntax for extend is designed to mimic the syntax of CSS pseudo-classes, and can be combined with pseudo-classes as long as any extends selectors come last.
For example:
div { background-color: #e0e0e0; } p:extend(div) { color: #101010; }Will output
div, p{ background-color: #e0e0e0; } p{ color: #101010; }As you may have noticed, this can significantly remove the amount of bloat in the output CSS compared to mixins.
The extend selector can be used on the same line as the class selector, or it can be nested as seen in this example:
.parent { font-size:12pt; } .child { &:extend(.parent); }By default, extend does not include nested elements of the extended style. To do this, you must add all to the selector in the extend expression.
For example:
.a.b.test, .test.c { color: orange; } .test { &:hover { color: green; } } .replacement :extend(.test) { }Outputs:
.a.b.test, .test.c { color: orange; } .test:hover { color: green; }But this:
.a.b.test, .test.c { color: orange; } .test { &:hover { color: green; } } .replacement :extend(.test all) { }Outputs:
.a.b.test, .test.c, .a.b.replacement, .replacement.c { color: orange; } .test:hover, .replacement:hover { color: green; }
RE: #25 we should be documenting how we are building our CSS/JS with Grunt so people know how to add new libraries and have them integrated properly.
Also Via @Scotchester
We need to figure out a way to deal with scripts that we don't want to build into the global JS files and only want to load on individual pages as needed. For example, a tablesort script may not need to be loaded in the global JS file; it could just be called by itself on pages where it is needed.
I think the way we're adding in html5shiv speaks to this so it's just a matter of documenting it. In fact we should document what we're doing in general because it might not be so obvious that you should be adding your site-wide js/css into main.js/main.less.
Status: Done!
Problem: Normalize is up to V3 now and V2 dropped IE7 support. Here is the thread where necolas talks about dropping IE7.
We can add IE7 support back in by comparing it to the commit where he took out support.
There is also an SCSS normalize project that allows you to specify if you want IE7 support. Seems like we could more easily backfill support by looking for instances of @if support-legacy-browser(ie, "7") { ...
in their code.
Keep in mind we should re-test the components when adding this. There also might be some CSS we can drop from our stylesheets once adding this but I'm not sure how we can figure that out easily.
Notes from OSCON 2013 courtesy of @Scotchester
Install from the Chrome Web Store
Run accessibility tests from the Audits tab.
Can access the API with Web Puppeteer. Tutorial on http://github.com/GoogleChrome (see slides for link).
Notes from OSCON 2013 courtesy of @Scotchester
Government child welfare organization, required to follow Section 508.
Tech constraints: Rspec, Capybara
Created a Capybara wrapper around the Chrome DevTools Accessibility Extension, baking the testing into their integration test suite. It's a drop-in replacement for a Selenium web driver in Capybara.
It generates a build failure like any other integration testing error.
To help locate problem spots, added a debugging snapshot right before the exceptions are thrown so that you can load it up in a browser and use the DevTools to see what's going on.
Accessibility testing in the browser and on the server.
QUAIL is a jQuery plugin for checking content against accessibility guidelines. It provides a flexible way to test for certain problems (say, images missing an alt text) and a collection of over 200 tests to get you started. Defining your own tests is easy, and you can pick-and-choose tests to focus on the needs of your own app.
FireEyes is our free accessibility testing plug-in. With the click of a button, it can provide a detailed and comprehensive report of any accessibility errors on any of the pages within your site. You can then send that error report to the WorldSpace public server where you can download it as an Excel or .csv file.
When you’ve got a big accessibility project, you need an automated testing tool that’s up to the task. WorldSpace combines the fast and thorough reporting capabilities of FireEyes and can use them across any quantity of pages. It also offers special features for managers, developers, and QA.
As noted by @danny8000, currently, individual components' Gruntfiles are largely the same. How can we make these more maintainable?
Discussed briefly with @himedlooff and more extensively with @contolini, I propose:
package.json
dependencies.node_modules
location, plus any component-specific Grunt tasks. Potential technique: cowboy/wesbos@5a2980aQuestion to be answered: Can we override a standard task with a custom one in the component's Gruntfile? (What happens if you are importing a standard task and then below you declare a task of the same name?) Or can we pass them options?
I propose that we use the CONTRIBUTING.md file from this repo for all Capital Framework components.
Currently within each component repository we have a CONTRIBUTING.md file. They all say the same exact thing. Recently we've been updating the contributing guidelines for this master repo. These edits are applicable to all components as well and it would be nice to update each component. We can save some effort on updating all of the component repos in the future if we 1) delete the CONTRIBUTING.md file in each component repo and 2) within each component README update the contributing link to point to the CONTRIBUTING.md of this repo. If we feel like a CONTRIBUTING.md file is necessary in each repo maybe we can replace all the content within that file with a link.
@Scotchester any thoughts?
We need to add a style guide section to CONTRIBUTING.md. Additions should be terse so it is easy to read and so people don't ignore it. If examples are needed link to them.
The following additions are needed:
unit()
to make calculations clear and using line breaks in unit()
to make long calculations easy to read.EditorConfig is a file format and collection of text editor plugins for maintaining consistent coding styles between different editors and IDEs.
From what I briefly read it's a way to set tabs, spaces, etc per project. So you'd open up this repo and there'd be an .editorconfig
file and your IDE would pick it up and automatically update your settings to keep these kinds of things consistent. This is how I imagine it works but I haven't looked into it really. Figured I'd first see if anyone has used it or knows what it really is.
The benefit I think is that if we needed to output a .CSS file for each component then that file would only contain the component styles and not any dependency styles. Only mixins or variables that are dependencies are used for styling the current component but not compiled into the .CSS.
We have another import option - reference. This means that any variables or mixins or selectors will be imported, but never output.
e.g. if you have
.a { color: green; }in a file and import it
@import (reference) "file.less";
then that file will not be output, but you could do.b { .a; }
A lot of "boilerplate" projects seem to suggest not cloning the full history of the project. This can be accomplished like so:
git clone --depth 1 git://[GHE]/flapjack/front-end.gitWhat do you guys think about this? Should these instructions be added to the README?
Another issue is that you can only fork a project once. Are there git tricks to get around that?
My workflow so far has been to do the following:
- Create a new (empty) repo at github
- Clone as I did above
- Push that clone to the new repo
edit: once everything is public, we may be able to simplify this by creating a yeoman generator
Yeah, end users should not fork the project, just clone as @ascott1 suggested.
I like the suggestion of adding that to the README, thanks @ascott1! Wish I had known about that option a long time ago...
Yeah, smart thinking it should definitely be in the readme.
Originally written by @himedlooff:
Status: Thinking of going with Topdoc as adoption and implementation seems to be much easier. See notes below.
Interesting article: http://addyosmani.com/blog/checking-in-front-end-dependencies/
I am pretty sure we're not willing to check in the third-party dependencies we rely on, but should we check in our own components?
Why can't we check in all Bower dependencies? What was most convincing to me was that it doesn't matter if you pin down your Bower dependencies because their might be child dependencies that aren't pinned down. I can see how this would cause headaches during a launch. I'm not sure if any third party dependency uses bower though so this point might be moot for now. The only way I can think of to control this particular issue would be to use a fork of every third party dependency and build/pin them down yourself.
Another (admittedly a minor) convenience is you could skip the grunt vendor step in each component and in the framework repo decreasing the complexity a little.
Also we should start using the bower.json
ignore
property.
ignore [array]:
An array of paths not needed in production that you want Bower to ignore when installing your package.
In general, for public repos, we don't want to "redistribute" others' code. I mean, we can in most instances, if their license permits it, but it's just easier if we don't, as a rule.
But you make a good point about our inability to control how third party components manage their own dependencies. I don't think forking and maintaing our own is an option.
Maybe we should talk to the OSWG and try to get a group consensus on whether or not we should do that?
(Interesting note about the
ignore
property... not sure why I didn't know that existed. But, is there an advantage to using that over specifying only the files you want via themain
option?)
Also in that article you linked to
Jørgen Borgesen
How do you handle files (from dependency packages) that are not needed by your application? A lot of the bower packages contains files for test, documentation, etc. Do you recommend adding them to source control? How about their bower.json file?Sindre Sorhus
Yeah, that’s currently the biggest issue with the Bower ecosystem. Package authors aren’t using theignore
property in bower.json to exclude unneeded files. You could however add some of the junk manually to your .gitignore. As for their bower.json, yes, as it’s used by Bower.
Hmm... so perhaps using both is the best policy, so that if someone else wants to use our package, their build process could potentially use either method to get the necessary files.
Via @Scotchester
We need to figure out a way to deal with scripts that we don't want to build into the global JS files and only want to load on individual pages as needed. For example, a tablesort script may not need to be loaded in the global JS file; it could just be called by itself on pages where it is needed.
It causes
grunt vendor
to skip its ownbower install
step, leaving things in the/bower_components
folder. Then the LESS build breaks when it looks for imported dependencies in the wrong place.Since many people might be in the habit of running
bower install
when cloning a project that uses Bower, we should set upgrunt vendor
so that it doesn't break if someone runsbower install
prior.An easy way to do this would be to just add a task to
grunt vendor
that deletes/bower_components
, but maybe there's a better way out there?
Would having
.bowerrc
point tosrc/vendor/
fix this?
I think probably not, because the grunt-bower task also does the
exportsOverride
bit, so it's not just a matter of getting the stock bower components in the right place.. But it's worth trying just to be sure!
Right, so I remember why we set it up this way (why
.bowerrc
doesn't point tosrc/vendor
): If we do it the way it's currently implemented, the grunt-bower task only copies the useful files intosrc/vendor
–.less
and.js
files, notREADME
s andpackage.json
s and such. If.bowerrc
points tosrc/vendor
, the entirety of each package's repo is pulled in.Let me know if you would like me to explain that over screensharing, Chris, where it might be easier to see in action.
Going to commit the easy fix for this for now.
Is this really an issue? If people followed the instructions (or if the instructions were more clear) then they wouldn't have this problem. Why bloat our gruntfile for cases like this?
The other thought was should we submit this to the grunt-bower repo as a bug?
We should have conventions on class names. In the hand book we say we use SMACSS but none of us really do. I'm partial to the BEM-ish style of:
.block{}
.block__element{}
.block--modifier{}
For example:
.site-search { .. }
.site-search--full { .. }
.site-search__field { .. }
.site-search__button { .. }
<form class="site-search site-search--full">
<input type="text" class="site-search__field">
<input type="Submit" value ="Search" class="site-search__button">
</form>
More info: http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/
Pros
Flexibility.
Non-BEM-ish
.nav { ... }
.nav > li { ... }
<ul class="nav">
<li></li>
<li></li>
<li></li>
</ul>
BEM-ish
.nav { ... }
.nav__item { ... }
<nav class="nav">
<div class="nav__item"></div>
<div class="nav__item"></div>
<div class="nav__item"></div>
</nav>
Thoughts
div
's to span
's easily. Or you could format the markup differently and nest .nav__item
further down the tree if you need to like this:<nav class="nav">
<div class="col-4">
<div class="nav__item"></div>
</div>
<div class="col-4">
<div class="nav__item"></div>
</div>
<div class="col-4">
<div class="nav__item"></div>
</div>
</nav>
.nav__item
is lower than .nav > li
or even .nav li
. Keeping specificity low in every day usage means you can leverage specificity later when you really need to override something.When using EM values I find it helpful to leave the calculation that got me the value inside of a comment. For example:
font-size: 0.875em; /* 14/16 = 0.875 */
This is helpful because it's hard to understand what these EM values mean sometimes. Like I haven't yet memorized that 0.875em
is 14px
in the context of 16px
. And if the context changes then it gets even more confusing.
The downside to commenting the calculation is it's harder to comment whole blocks of CSS because you can't do this:
/*.something {
font-size: 0.875em; /* 14/16 = 0.875 */
}*/
I think it's worth it though because it makes it clear what that value is incase it needs to be adjusted later. Also this is only an issue when writing .css
files.
With LESS you can use LESS comments which you can wrap with standard CSS comments like this:
/*.something {
font-size: 0.875em; // 14/16 = 0.875
}*/
OR... I've been playing around with the unit()
function which allows you to use a math expression inside of it. This is nice because the calculation is not inside of a comment anymore. Also when you need to calculate margins or other properties in EM's where the context is likely to affect the calculation it's much easier to do.
When changing from 22px to 28px font-size it's pretty easy:
h1 {
font-size: unit( 22 / @base-font-size-px, em );
margin: unit( 10 / 22, em ) 0;
}
h1 {
font-size: unit( 28 / @base-font-size-px, em );
margin: unit( 10 / 28, em ) 0;
}
This should be set up for this repo and each component.
Using mogo or wraith or something else.
The JS in the demo should be tested.
https://github.com/cfpb/capital-framework/blob/master/src/static/js/app.js
Might be worth talking to Beth Anne about connecting our GH projects to our GA account using ga-beacon.
A logo would make Capital classier. We can stick it on the demo page and we'll need one if we end up moving the framework to a dedicated GH org.
Any ideas? Perhaps the standard four column government-looking building? Or a silhouette of the Capitol building? Or something money-themed like a seal on a U.S. dollar bill?
RE: #34, if we decide to add script dependency management what should we use?
When building combined asset folders (e.g., dist/static/img
), in the current implementation, there is a possibility that two files with the same name would get put in that folder. Presumably, the first would get overridden by the second.
We should figure out how to sequester assets for each vendor component in their own folders (either dist/static/vendor/[type]
or dist/static/[type]/vendor
) to prevent such conflicts.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.