by Varya Stepanova from SC5
Senior Software Specialist at SC5 Online
TMG (Amsterdam, the Netherlands); Yandex (Moscow, Russia)
Components on the web: libraries, SGDD, BEM. Techs: CSS, JavaScript, etc.
Cascading Style Sheets (CSS) is a style sheet language used for describing the look and formatting of a document written in a markup language. Wikipedia
First published in 1996
<form class="b-mail-domik g-js" method="post" action="https://passport.yandex.com/passport?mode=auth&from=mail&origin=hostroot_com_nol_enter&retpath=https%3A%2F%2Fmail.yandex.com">
<i class="b-mail-domik__roof"></i>
<table class="b-mail-domik__shadow">
<tbody>
<tr>
<td class="b-mail-domik__shadow__lt"> </td>
<td class="b-mail-domik__shadow__t"></td>
<td class="b-mail-domik__shadow__rt"> </td>
</tr>
<tr>
<td class="b-mail-domik__shadow__l"> </td>
<td class="b-mail-domik__shadow__m">
<div class="b-mail-domik__form">
<div class="b-mail-domik__username">
<label class="b-hint-input g-js" for="b-mail-domik-username11" style="display: block;">username</label>
<div class="b-input"><input tabindex="1" name="login" id="b-mail-domik-username11" class="b-input__text" autocapitalize="off" autocorrect="off" aria-label="username"></div>
</div>
<div class="b-mail-domik__password">
<label class="b-hint-input g-js" for="b-mail-domik-password11">password</label>
<div class="b-input"><input type="password" tabindex="2" name="passwd" id="b-mail-domik-password11" class="b-input__text" aria-label="password"></div>
</div>
<div class="b-mail-domik__permanent"><input type="hidden" name="twoweeks" value="yes"><input type="checkbox" tabindex="3" id="b-mail-domik-permament11" class="b-mail-domik__check"> <label for="b-mail-domik-permament11">don't remember me</label></div>
<div class="b-mail-domik__button b-mail-domik__button_qr"><span class="b-mail-button b-mail-button_default b-mail-button_button b-mail-button_grey-26px b-mail-button_26px b-mail-button_lead"><span class="b-mail-button__inner"><span class="b-mail-button__text">Log in</span></span><input type="submit" tabindex="4" class="b-mail-button__button" value="Log in"></span><a href="https://passport.yandex.com/auth/?mode=qr&retpath=https%3A%2F%2Fmail.yandex.com" class="js-button-qr b-mail-button b-mail-button_default b-mail-button_button b-mail-button_grey-26px b-mail-button_26px b-mail-button_dependent"><span class="b-mail-button__inner"><span class="b-mail-button__ico b-mail-button__ico_qr"></span></span></a></div>
<div class="b-mail-domik__remember"><a tabindex="5" class="b-mail-domik__remind js-count-click" href="https://passport.yandex.com/passport?mode=restore" data-metrika="Клики на 'Вспомнить пароль'" data-paranja="check">Forgot your password?</a></div>
<div class="b-mail-domik__social"><a class="b-mail-domik__social-link js-social-link" data-provider="fb"><i class="b-mail-domik__social-icon b-mail-domik__social-icon_provider_fb"></i></a><a class="b-mail-domik__social-link js-social-link" data-provider="tw"><i class="b-mail-domik__social-icon b-mail-domik__social-icon_provider_tw"></i></a><a class="b-mail-domik__social-link js-social-link" data-provider="gg"><i class="b-mail-domik__social-icon b-mail-domik__social-icon_provider_gg"></i></a></div>
</div>
</td>
<td class="b-mail-domik__shadow__r"> </td>
</tr>
<tr>
<td class="b-mail-domik__shadow__lb"> </td>
<td class="b-mail-domik__shadow__b"></td>
<td class="b-mail-domik__shadow__rb"> </td>
</tr>
</tbody>
</table>
<div class="antivirus js-antivirus">Yandex.Mail has <a href="http://www.drweb.com/" target="_blank"></a> virus protection</div>
</form>
H1 { color: blue }
P EM { font-weight: bold }
A:link IMG { border: 2px solid blue }
A:visited IMG { border: 2px solid red }
A:active IMG { border: 2px solid lime }
a { /* Affects all the links */
color: red;
}
ul li a { /* Affects all the links in lists */
color: green;
}
Specificity is the means by which a browser decides which property values are the most relevant to an element and gets to be applied. Specificity is only based on the matching rules which are composed of selectors of different sorts.
<div id="test">
<span>Text</span>
</div>
div#test span { color: green }
span { color: red }
div span { color: blue }
<div class="sidebar">Left floated sidebar</div>
.sidebar { /* Does it redefine `div.sidebar`?! */
float: right;
}
body .sidebar { /* Overwrites 'div.sidebar {}' */
float: right;
}
.navbar-inverse .navbar-nav>li>a {
color: #999;
}
#home-menu-container #home-menu li a {
color: red;
}
body #home-menu ul li a {
color: blue !important;
}
#content div div {
float: left;
}
@import url('i-need-this.css');
100 pages in projects
.person div a {
color: pink;
}
Can I remove it? Will it break something? Maybe it is for a third-party HTML code?
This is not hard in CSS | This is! |
---|---|
|
|
How do we architect encapsulated components?
<body class="page">
<div class="header">
<img class="logo" ... />
<div class="search">...</div>
<div class="menu">...</div>
</div>
<div class="layout">
<div class="sidebar">...</div>
<div class="menu">...</div>
</div>
<ul id="menu">
<li>Tab 1</li>
<li>Tab 2</li>
<ul>
#menu {
/* styles for element */
}
Someday you will need to repeat the block at the same page
<div class="tabbed-pane">
<ul>
<li class="tabbed-pane--tab">Tab1</li>
<li class="tabbed-pane--tab">Tab2</li>
<li class="tabbed-pane--tab">Tab3</li>
</ul>
<div class="tabbed-pane--pane">
...
</div>
</div>
.block {
/* styles for block */
}
.block--element {
/* styles for element */
}
<ul class="menu">
<li class="item">Tab 1</li>
<li class="item">Tab 2</li>
<ul>
.menu .item {
/* styles for element */
}
<div class="panels">
<div class="item">
<ul class="goods">
<li class="item">
<!--
Remember: non-deterministic matches
-->
</li>
</ul>
</div>
</div>
<ul class="menu menu_footer">
<li class="menu--item">...</li>
...
</ul>
.menu_footer {
font-size: 0.8em;
}
.block {
/* styles for block */
}
.block_modifier {
/* styles for modifier */
}
.block--element {
/* styles for element */
}
<ul class="menu">
<li class="menu--item">Tab 1</li>
<li class="menu--item menu--item_current">Tab 2</li>
<li class="menu--item">Tab 3</li>
</ul>
.block
/* styles for block */
}
.block--element {
/* styles for element */
}
.block--element_modifier {
/* styles for modified element
}
<ul class="menu footer">...<ul>
.menu.footer { /* combined selector */
font-size: 0.8em;
}
<ul class="menu">
<li class="menu--item current">Tab 2</li>
<ul>
.menu--item.current { /* combined selector */
background-color: red;
}
You would suffer when redefining
.menu--item.current {
background: white;
}
.menu_dark .menu--item {
background: black; /* Still white, baby */
}
.block {
/* styles for block */
&_modifier {
/* styles for modifier */
}
&--element {
/* styles for element */
}
}
<h1 class="title">An example heading</h1>
.title {
background-color: red;
}
import styles from "./styles.css";
element.innerHTML =
`<h1 class="${styles.title}">
An example heading
</h1>`;
<h1 class="_styles__title_309571057">
An example heading
</h1>
._styles__title_309571057 {
background-color: red;
}
<!-- Import element -->
<link rel="import" href="my-lib/google-map.html">
<!-- Use element -->
<google-map lat="37.790" long="-122.390"></google-map>
<!-- Polyfill Web Components support for older browsers -->
<script src="webcomponents.min.js"></script>
<!-- Import element -->
<link rel="import" href="google-map.html">
<!-- Use element -->
<google-map lat="37.790" long="-122.390"></google-map>
A living styleguide represents UI components of your website with exact the same styles which you use across the project.
Styleguide Driven Development is the practise of using the styleguide as the focal point for all front-end UI development tasks.
npm install sc5-styleguide
http://styleguide.sc5.io
// A button suitable for giving a star to someone.
//
// :hover - Subtle hover highlight.
// .star-given - A highlight indicating you've already given a star.
// .star-given:hover - Subtle hover highlight on top of star-given styling.
// .disabled - Dims the button to indicate it cannot be used.
//
// Styleguide 2.1.3.
a.button.star{
...
&.star-given{
...
}
&.disabled{
...
}
}
gulp.task('styleguide:generate', function() {
return gulp.src('*.scss') // Or *.less, or *.css
.pipe(styleguide.generate({
rootPath: './output',
overviewPath: 'README.md'
}))
.pipe(gulp.dest(outputPath));
});
gulp.task('styleguide:applystyles', function() {
return gulp.src('main.scss')
.pipe(sass({
errLogToConsole: true
}))
.pipe(styleguide.applyStyles())
.pipe(gulp.dest('./output'));
});
gulp.task('styleguide',
['styleguide:generate', 'styleguide:applystyles']);
gulp.task('watch', ['styleguide'], function() {
gulp.watch(['*.scss'], ['styleguide']);
});
Varya Stepanova, SC5 Online
@varya_en
On the web: varya.me