When Bootstrap Attacks!
@pamelafox
press space bar for the next slide
a bit of background...
⟱
coursera
a modern web app?
Modern...
+
+
Not so modern...
+
too many bootstraps
Modern App: Bootstrap 2.1
Legacy Codebase: Bootstrap 1, Bootstrap 2.0
A SIMPLE GOAL:
PORT TO BOOTSTRAP 2
⟱
i'll JUST Follow
THE upgrade guide...!
2 days later
1 month later
bring in the recruits!
bootstrapv2athon!
a week of q/a!
FInally, 1 month later...
upgrading css
frameworks shouldn't
be that hard.
...so why was it?
⟱
my, grandma, what a big codebase you have...
207 *.template.php files
351 *controller.php files
143 *.js files
25 *.css files
class names, class names, everywhere!
HTML, CSS, PHP, PHPed JS
least greppable
class names ever
grep "alert" * -R
80
grep "label" * -R
329
grep "success" * -R
364
grep "info" * -R
1153
BOOTstrap: its js, too!
if i could turn back time....
aka what I'll do differently next time.
⟱
use less spaghetti,
more architecture
⬇
⬇
...but just one architecture!
use namespaced
bootstrap class names
grep 'tbs-alert' * -R
:%s/tbs-alert/tbs-alert2 * -R
Issue 1287: Prefix Bootstrap classes
Adding Prefixes to Bootstrap CSS classes
DON't use bootstrap
class names directly
<button class="coursera-submit-button">Sign Up</button>
.coursera-submit-button
@extends .btn
@extends .btn-info
&:hover
@extends .btn:hover
@extends .btn-info:hover
don't use class names in your js libraries
wysihtml5/editor.js: var defaults = {'prefix.css': ''}
var $toolbar = $(toolbarTemplate({prefix:options['prefix.css']}))
toolbar.js.jade:div(class=prefix+"-toolbar", role="toolbar", title="HTML editing toolbar")
coursera.editor.js:new WysiEditor({'prefix.css': 'coursera-wysihtml5'});
coursera.editor.styl: .coursera-wysihtml5
padding 0
Dynamic Selectors
don't use class names
in your js
<button class="coursera-submit-button">Sign Up</button>
<script>
$('.coursera-submit-button').on('click', signUp);
</script>
vs.
<button class="coursera-submit-button coursera-submit-js">Sign Up</button>
view.$('.coursera-submit-js').on('click', signUp);
vs.
<button class="coursera-submit-button" data-js="signup">Sign Up</button>
view.$('form [data-js=signup]').on('click', signUp);
test your frontend
mocha/chai/jsdom:
view.$('.course-forum-thread-showmore').click();
chai.expect(view.$('.course-forum-your-threads-listing tr:visible').size())
.to.be.equal(25);
chai.expect(view.$('.course-forum-thread-showmore').is(':visible'))
.to.be.equal(false);
selenium:
def expand_all_lectures(self):
sections = self.get_els('.course-item-list-header')
for section in sections:
if 'contracted' in section.get_attribute('class'):
section.click()
self.wait_for(lambda: 'contracted' not in section.get_attribute('class'))
diff your frontend
Automatic: Needle: Selenium+Nose
from needle.cases import NeedleTestCase class BBCNewsTest(NeedleTestCase): def test_masthead(self): self.driver.get('http://www.bbc.co.uk/news/') self.assertScreenshot('#blq-mast', 'bbc-masthead')
Also: Perceptual Diffs, PhantomCSS, CasperJS, SlimerJS
Manual Flow: Firefox screenshot + Kaleidoscope
CSS can break you.
use protection.
When Bootstrap Attacks!
By pamelafox
When Bootstrap Attacks!
- 15,518