Целью доклада не является разжигание возмущения, горение седалищ и оскорбление чувств программистов. Докладчик не собирается заканчивать спикерскую карьеру таким изысканным способом. Любое нарушение мировосприятия после этого доклада целиком и полностью на совести самого слушателя. Если это кто-то ещё читает, интересный факт: люди не чихают во сне. И вы прямо сейчас видите свой нос.
input:not(:checked) + input:checked + input:checked
+ * + * + * + * + * + * + * + * + * + * + *
+ * + * + * + * + * + * + * + * + * + * + * {
--cell-bg-color: hotpink;
--cell-num-color: white;
--cell-content: "X";
--cell-cursor: pointer;
}
border-style: SOLID
.promo {
display: block;
padding: 20px;
margin-bottom: 20px;
background-color: #09f;
color: #fff;
text-shadow: 0 0 1px rgba(0,0,0,0.25);
border-radius: 4px;
}
The single responsibility principle applied to CSS
.island {
display: block;
padding: 20px;
margin-bottom: 20px;
}
.promo {
background-color: #09f;
color: #fff;
text-shadow: 0 0 1px rgba(0,0,0,0.25);
border-radius: 4px;
}
The single responsibility principle applied to CSS
<figure class="app-column-item app-card">
<h3 class="talkname">...</h3>
<h4>Сергій Бабіч<br><small>Львів</small></h4>
<img class="app-card-img" src="babich.jpg"Сергій Бабіч">
<figcaption class="app-card-caption">
<p class="description">...</p>
<p>...</p>
</figcaption>
</figure>
npm install -g hermione
Тестируем пользовательские сценарии вместе с «Гермионой»
// .hermione.conf.js
module.exports = {
sets: {
desktop: {
files: 'tests/desktop'
}
},
browsers: {
chrome: {
desiredCapabilities: {
browserName: 'chrome'
}
}
}
};
github.com/gemini-testing/hermione
// tests/desktop/lvivcss.test.js
const assert = require('chai').assert;
describe('lvivcss', function() {
it('should be ok', function() {
return this.browser
.url('https://lvivcss.org')
.getText('h1.logo')
.then(function(title) {
assert.equal(title, `LvivCSS'19`)
})
.setWindowSize(1440, 540)
.assertView('plain', 'body')
.setWindowSize(1440, 520)
.assertView('boom', 'body');
});
});
github.com/gemini-testing/hermione
1440x540
1440x520
@mixin block($w, $h, $d, $x, $y, $z, $color, $angle: '0, 0, 0, 0') {
transform: translate3d($x, $y, $z) rotate3d(#{$angle});
will-change: transform;
.front { @include front($w, $h, $d, $color); }
.back { @include back($w, $h, $d, $color); }
.right { @include right($w, $h, $d, darken($color, 10%)); }
.left { @include left($w, $h, $d, darken($color, 10%)); }
.top { @include top($w, $h, $d, darken($color, 5%)); }
.bottom { @include bottom($w, $h, $d, darken($color, 5%)); }
}
#DailyCssImages - Day 17. Zombie
:root {
--r: 255;
--g: 20;
--b: 147;
--primary-color: rgb(var(--r), var(--g), var(--b));
}
.my-element {
--e-width: 200px;
--e-border-width: 20px;
background-color: var(--primary-color);
width: calc(var(--e-width) + var(--e-border-width));
}
<div class="one two">I have 40px margin</div>
:root {
--root-offset: 20px;
}
.one {
--offset: 40px;
}
.two {
margin: var(--offset, var(--root-offset, 30px));
}
CSS Custom Properties in Depth
<div class="two">I have 20px margin</div>
:root {
--root-offset: 20px;
}
.one {
--offset: 40px;
}
.two {
margin: var(--offset, var(--root-offset, 30px));
}
.animal {
--has-mustache: 1;
--has-paws: 1;
--has-tail: 1;
--has-documents: calc(
var(--has-mustache, 0) *
var(--has-paws, 0) *
var(--has-tail, 0)
);
}
.language {
--undefined-is-not-a-function: 1;
--is-js: var(--undefined-is-not-a-function, 0);
--is-css: calc(
1 - var(--is-js)
);
}
.human {
--can-frontend: 1;
--can-backend: 0;
--is-developer: calc(
var(--can-frontend) * var(--can-backend) +
var(--can-frontend) * (1 - var(--can-backend)) +
(1 - var(--can-frontend)) * var(--can-backend)
);
}
⬇️
.human {
--can-frontend: 1;
--can-backend: 0;
--is-developer: calc(
var(--can-frontend) +
(1 - var(--can-frontend)) * var(--can-backend)
);
}
.human {
--can-frontend: 1;
--can-backend: 0;
--is-developer: clamp(
0,
calc(var(--can-frontend) + var(--can-backend)),
1
);
}
clamp()
width: clamp(10px, 4em, 80px);
width: max(10px, min(4em, 80px));
max()
.human {
--can-frontend: 1;
--can-backend: 0;
/* not (A or B) = (not A) and (not B) */
--is-developer: calc(1 -
(1 - var(--can-frontend)) * (1 - var(--can-backend))
);
}
clamp()
Как хорошо вы знаете CSS? 👨🏼🏫
Даны следующие классы:
.red { color: red; }
.blue { color: blue; }
Какого цвета должны быть эти дивы?
<div class="red blue">
<div class="blue red">
twitter.com/mxstbr/status/1038073603311448064
<b style="background: #0B2429;
color: #F3AC3C;
zoom: 200;
left: -5.59px;
top: -8.3px;
position: absolute">k
#input[value='l'i] ~ #results #result55,
#input[value='la'i] ~ #results #result55,
#input[value='lau'i] ~ #results #result55,
#input[value='laur'i] ~ #results #result55,
#input[value='laura'i] ~ #results #result55 {
display: block;
}
#option[id]:checked ~ #results #result12,
#option[id]:checked ~ #results #result55 {
display: block;
}
body {
font-family: sans-serif;
}
h1, p {
font-family: "no-parens", sans-serif;
}
/* https://github.com/adobe-fonts/adobe-blank */
@font-face {
font-family: no-parens;
src: url("...");
unicode-range: U+0028, U+0029; /* () */
}
Removing parentheses in pure CSS
CSS.registerComputedValueHook({
inputProperties: ["transform", "--slide-*"],
outputProperties: ["transform"],
computedValue: function(input, output) {
const tx = input.get("--slide-x");
const ty = input.get("--slide-y");
const translate = new CSSTranslate(tx, ty);
output.set("transform",
new CSSTransformValue(
translate,
...input.get('transform')
)
);
}
});
CSS and Houdini
CSS.registerFunction({
"name": "--darken",
"inputArguments": ["<color>", "<percentage>"],
}, (color, percent) => {
const newColor = color.toHSL();
newColor.lightness *= (1 - percent.value/100);
return newColor;
});
.element {
color: --darken(tomato, 12%);
}
CSS and Houdini
CSS.registerFunction(
{
"name": "--random",
"per": "element",
},
() => CSS.number(Math.random())
);
@keyframes changeOrder {
from { z-index: 6; }
to { z-index: 1; }
}
label {
animation: changeOrder 3s infinite linear;
}
label:nth-of-type(1) { animation-delay: -0.0s; }
label:nth-of-type(2) { animation-delay: -0.5s; }
label:nth-of-type(3) { animation-delay: -1.0s; }
Are There Random Numbers in CSS?
:root {
--sidebar-width: 400px;
}
.closed {
--sidebar-width: 80px;
}
body {
transition: --sidebar-width 1s;
}
// JavaScript
CSS.registerProperty({
name: '--sidebar-width',
syntax: '<length>',
inherits: true,
initialValue: '80px'
});
/* CSS */
@property --sidebar-width {
syntax: "<length>";
inherits: true;
initialValue: 80px;
}