github.com/aeharding/excellent-css
- Syntactically easy: selector, property, value
selector [, selector2, ...] [:pseudo-class] { property: value; [property2: value2; ...] }
- Not a programming language
- Constantly evolving -- CSS 1, 2, 2.1, 3
- Support for a HUGE device matrix
- FF, Safari, Chrome, IE 9/10/11/Edge on Tablets, phones, desktops (WP, iPhone, Windows 10, Mac OS X)
(It even broke the syntax highlighting.).flex { -ms-box-orient: horizontal; display: -ms-flexbox; display: -webkit-flex; display: -moz-flex; display: -ms-flex; display: flex; }
- Everything's a global
- CSS specificity
- normalize.css
* { box-sizing: border-box }
- No big library cough bootstrap cough
- NOT a reset -- a normaliz-er
- Preserves useful browser defaults
- Correct bugs/inconsistencies
- VERY simple, each rule is justified [source]
- Always should be your base
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
<div class="modal fade" tabindex="-1" role="dialog" aria-labelledby="gridSystemModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="gridSystemModalLabel">Modal title</h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-4">.col-md-4</div>
<div class="col-md-4 col-md-offset-4">.col-md-4 .col-md-offset-4</div>
</div>
<div class="row">
<div class="col-md-3 col-md-offset-3">.col-md-3 .col-md-offset-3</div>
<div class="col-md-2 col-md-offset-4">.col-md-2 .col-md-offset-4</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">.col-md-6 .col-md-offset-3</div>
</div>
<div class="row">
<div class="col-sm-9">
Level 1: .col-sm-9
<div class="row">
<div class="col-xs-8 col-sm-6">
Level 2: .col-xs-8 .col-sm-6
</div>
<div class="col-xs-4 col-sm-6">
Level 2: .col-xs-4 .col-sm-6
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
divdivdivdivdivdivdivdivdivdivdivdivdivdivdivdivdivdivdivdivdivdivdivdiv .generic-class-name.generic-class-name.generic-class-name.generic-class-name.generic-class-name
Touch CSS? => Bootstrap
- Specificity war
- Upgrading / removal
Reasons you use bootstrap:
- You can't CSS
- Somebody told you to
- EMs, REMs
- BEM
- Many files
- Remove whitespace
Use instead of px
Equal to the computed font-size
of the element, inherited
Equal to the computed font-size
of the :root
Note: except border: 1px solid black
https://css-tricks.com/bem-101/
/* Block component */
.button {}
/* Element that depends upon the block */
.button__price {}
/* Modifier that changes the style of the block */
.button--orange {}
.button--big {}
<a href="#" class="button button--orange"></a>
(Namespace .am4-button
if needed)
- Block names should correspond to filenames
.am4-button--primary {} ==> button.scss
- Specificity is no longer a problem!
- ONLY nest for
:hover
,:active
, etc. - DO NOT nest for the sake of nesting
- ONLY nest for
- Scoping/conflicts fixed!
myProject/
src/
sass/
app.scss
_variables.scss
_zindex.scss
otherComponent.scss
anotherComponent.scss
core/
button.scss
form.scss
@import 'normalize';
@import 'variables';
@import 'zindex';
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
@import 'core/button';
@import 'core/form';
@import 'otherComponent';
@import 'anotherComponent';
(Remember to setup includePaths
.)
(Or have a plan!)
<ol>
<li>boom</li>
<li>boom 2</li>
</ol>
<ol>
<li>boom
</li><li>boom 2</li>
</ol>
li {
float: left;
}
or grunt-htmlclean
!
// app.scss
@import 'bourbon';
@include keyframes(my-animation) {
0% {
@include transform(translate(0, 0));
}
100% {
@include transform(translate(0, -1em));
}
}
=> Vendor prefixing
https://github.com/postcss/autoprefixer
"postcss"
// gulpfile.js
.pipe(postcss([ autoprefixer({ browsers: ['last 2 versions'] }) ]))
@keyframes my-animation {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(0, -1em);
}
}
=> Vendor prefixing
(I prefer autoprefixer.)
A customizable, lightweight (use what you need), semantic grid
.am4-welcome {
@include outer-container;
}
.am4-welcome__aside {
@include span-columns(3);
}
.am4-welcome__content {
@include span-columns(9);
}
<div class="am4-welcome">
<div class="am4-welcome__aside"></div>
<main class="am4-welcome__content">
<!-- Hello, world! -->
</main>
</main>
Set your own breakpoints, gutter size, etc.
- Linting
- Pixel-by-pixel
Everyone is should be doing it.
rules:
border-zero:
- 1
- convention: '0'
brace-style:
- 1
- allow-single-line: true
clean-import-paths:
- 0
- filename-extension: false
leading-underscore: false
[...]
- It's unmaintainable, shitty, and your only option
- PhantomCSS vs WebdriverCSS
WebdriverCSS | PhantomCSS |
---|---|
Slow | Fast-ish |
All devices | Webkit |
Buggy | Very buggy |
phantomcss.screenshot("#feedback-form");
Don't use jQuery for animations
- CSS fallback
- "We're not in 2008 anymore"
- Brute forcing the DOM
- Animating to dynamic heights
- CSS3 Animation Events spec
- Use ngAnimate, React Animation, etc.
/* The starting CSS styles for the enter animation */
.jht-page--fade-in.ng-enter {
transition: 0.5s linear all;
opacity: 0;
}
/* The finishing CSS styles for the enter animation */
.jht-page--fade-in.ng-enter.ng-enter-active {
opacity: 1;
}