Основы HTML, CSS и javascript

Оглавление

  1. Основы
    1. HTML, CSS и javascript
    2. Javascript и python - основные отличия
    3. HTML страница
    4. HTML: Основные теги
    5. CSS
    6. Javascript на странице
    7. Как создать проект
  2. CSS
    1. Значения
    2. Cелекторы
    3. Основные свойства
    4. Переменные
    5. Функция calc()
  3. Javascript
    1. Взаимодействие со страницей
    2. Элемент как объект
    3. События
  4. Подробнее о разном
    1. Больше CSS свойств
    2. Тег input
    3. CSS анимации
    4. Тег canvas
    5. canvas анимации
  5. Дополнительно
    1. Функция range()
    2. code и key любой клавиши
    3. Красивые кнопки
    4. 3D куб

HTML, CSS и javascript

Для написания интернет-страниц используют HTML, CSS и javascript.

HTML

Начнём с HTML. В HTML всё состоит из элементов. Элементы обозначаются тегами: <tag> - начало, </tag> - конец элемента.

Например, вот так выглядит этот абзац:

<p>Например, вот так выглядит этот абзац:</p>

Также бывают элементы, внутрь которых нельзя ничего добавить, у таких элементов нет закрывающего тега.

Внутри тега также пишутся атрибуты, в таком виде:

<tag атрибут1="значение" атрибут2="значение"></tag>

Например, для элемента ссылка, можно указать атрибут адрес ссылки:

<a href="https://yandex.ru/">Ссылка на яндекс</a>

CSS

CSS позволяет добавить на страницу стили и даже анимацию.

Для стилей есть атрибут style. Стили пишутся в таком виде:

<p style="стиль: значение; стиль: значение;"></p>

Например можно изменить цвет текста и фона:

<p style="color: green; background-color: pink;">Текст зелёного цвета на розовом фоне.</p>

Текст зелёного цвета на розовом фоне.

Можно сделать даже такую анимацию:

1
2
3
4
5
6

Этот куб сделан только с помощью HTML и CSS. В одной из глав, будет показано как сделать такой куб.

Javascript

Позволяет добавить интерактивность на страницу, чтобы кнопки нажимались, а ваш заказ в магазине отправлялся.

Для тех, кто не знает javascript:

Если вы знаете python, переходите на главу основные различия между javascript и python

Если нет, то на этом сайте можно изучить javascript

Javascript и python - основные отличия

Начнём, например, с того, что в javascript нет обязательного форматирования, то есть не обязательно ставить пробелы в теле цикла или функции.

Сразу скажу про функцию print(), в javascript эта функция не печатает текст в консоль, а нужна для печати на принтере. Функции input() в javascript нет.

Вместо функции print() можно использовать alert() - вывод на экран или console.log() - вывод в консоль (открывается в браузере по кнопке F12). Нажмите, чтобы вызвать функцию:
alert("Текст в alert"),
console.log("Текст в консоль")

Для комментариев в тексте используются два слэша: //комментарий.

В конце строк желательно ставить точку с запятой (;).

Изменение переменной на единицу можно записать так: a++ и a--, тоже, что и a += 1 и a -= 1

Переменные

В javascript для создания переменной необходимо перед её именем написать const или let:

const - значение этой переменной нельзя будет изменить

let - значение этой переменной можно изменять.

Желательно использовать let только тогда, когда вы собираетесь изменять значение - это упрощает отладку и понимание кода. В редакторах const и let переменные подсвечиваются разными цветами.

let a = "abc";
const b = "abc";

a = 123; // Значение 'a' измениться
b = 123; // Произойдёт ошибка: "Assignment to constant variable."

Фигурные скобки

В javascript вместо того, чтобы отделять, например, тело цикла, используются не пробелы, а фигурные скобки. Переменные, созданные внутри скобок, не видны снаружи. В них можно заключать также любую часть кода.

{
	Какие-либо действия;
}
{ Какие-либо действия; } // Можно и так
{ Действие; Действие; Действие; } // И так тоже

const a = "123";
{
	const a = "abc"; // Это уже другая переменная
	console.log(a); // Вывод: abc
}
console.log(a); // Вывод: 123

let b = "abc";
{
	console.log(b); // Вывод: abc
	b = "123";
}
console.log(b); // Вывод: 123

Логические операции

В javascript вместо and, or и not используются &&, || и ! соответственно.

!(a == 1 && b != 1) // not(a == 1 and b != 1)

Также, в javascript true и false пишутся с маленькой буквы.

!(a == true || b == false) // not(a is True or b is False)

Условный оператор

if (условие)
{
	Действия;
}
else if (условие) // Вместо elif
{
	Действия;
}
else
{
	Действия;
}

Условия обязательно писать в скобках.

Если вы делаете только одно действие по условию, можно записать короче:

if (условие) Одна команда;
else if (условие) Одна команда;
else Одна команда;

Цикл while

while (условие)
{
	Тело цикла;
}

Если вы хотите вначале выполнить тело цикла, а проверять условие после, есть оператор do

do
{
	Тело цикла; // Выполнится хотя бы один раз
} while (условие)

Если вы делаете только одно действие в цикле, можно записать короче:

while (условие) Одна команда;

do Одна команда;
while (условие)

Цикл for

В javascript нет функции range().

Если вы очень к ней привыкли: моя реализация функции range().

Цикл от 0 до 10 не включительно:

for (let i = 0; i < 10; i++) {
	Тело цикла;
}

В отличие от python, если в теле цикла вы измените i, то это повлияет на цикл:

for (let i = 0; i < 10; i++) i = 9;

В этом цикле на первой итерации i станет равнятся 9, после чего i увеличится на единицу (т. к. в цикле i++), и условие станет ложно (10 < 10) - конец цикла.

Цикл 'for el in [1, 2, 3]:':

for (const el of [1, 2, 3]) {
	Тело цикла;
}

Если вы делаете только одно действие в цикле, можно записать короче:

for (let i = 0; i < 10; i++) Одна команда;
for (const el of [1, 2, 3]) Одна команда;

Списки и строки

Обращение по индексу к элементу, которого нет, не вызовет ошибки, вы просто получите undefined.

Не работают отрицательные индексы для отсчёта с конца: "abcd"[-1] == undefined. (Можно хранить данные и в отрицательных индексах!)

Нет функции list() для создания пустого списка.

Метод push() для добавления элемента в конец списка (вместо append()).

Нет функции len(). Получение длины:

const length1 = "abc".length; // Длина строки
const length2 = ["abc", 15].length; // Длина списка

Для совмещения списков есть метод concat():

const a = ["abc", 15];
const b = [false, "45"];
const c = a.concat(b); // c == ["abc", 15, false, "45"]

Метод concat() может добавлять также любые значения:

const a = ["abc", 15].concat("qwerty", [false, "45"], true);
// a == ["abc", 15, "qwerty", false, "45", true]

Срезы

Для срезов, как в python (a[1:3]), в javascript есть метод slice.

const a = "abcd".slice(1, 3); // a == "bc"
const b = ["a", "1", true, 5].slice(1, 3); // b == ["1", true]

const c = "abcd".slice(-1); // c == "d"
const d = "abcd".slice(-3, -1); // d == "bc"

Для переворота списка есть метод reverse:

const a = ["a", "1", true, 5];
a.reverse(); // a == [5, true, "1", "a"]

Для переворота строки встроенного метода нет, но можно сделать так:

const a = "abcd".split("").reverse().join(""); // a == "dcba"

F-строки

В javascript тоже есть способ вставлять переменные в строки.

Для этого строку надо заключать не в обычные кавычки, а в косые (те, что на клавише с буквой Ё). А перед фугурными скобками нужно ставить знак доллара.

const name = "Иванов";
console.log(`Здравствуйте, ${name}.`);

Объекты

Объект может иметь свойства.

Именем свойства может быть слово, строка или число. Пример объекта:

const person = {
	"name": "Вася",
	age: 25,
	1: "Что-то ещё",
}
// Получить значения:
const p_name = person.name; // Обычный способ
const p_age = person["age"]; // С помощью квадратных скобок
const p_1 = person[1]; // Значение числового свойства

Функции

В javascript функции объявляются таким способом:

function имя_функции(аргументы)
{
	тело функции;
}

Функция, принимающая любое количество аргументов:

function myCoolFunction(...args) { console.log(...args); }

В javascript функции можно вызывать даже до объявления:

log("function test");
function log(text)
{
	console.log(text);
}

Функции можно класть в переменные:

const log = function (text)
{
	console.log(text);
}
// Стрелочная функция:
const log2 = (text) =>
{
	console.log(text);
}
// Ещё короче:
const log3 = (text) => console.log(text);

В python есть лямбда-функции, в которых можно писать только одну строку, в javascript такой проблемы нет.

Метод списка, который позволяет пройти по всем элементам:

const a = [2, 5, 3, 1, 1];
a.forEach(el => {
	if (el > 2) console.log("more then 2");
	if (el < 3) console.log("less then 3");
});

Класс Math

В javascript объект Math импортировать не нужно.

Функции max и min находятся в Math:

const a = Math.max(4, 6, 3); // a == 6
const b = Math.min(...[3, 4, 2, 6, "1"]); // b == 1

Модули в Javascript

Модули в javascript работают только если страница находится на сервере!

Как и в python, можно импортировать объекты из других файлов. Объекты, которые вы хотите импортировать, должны быть помечены словом export.

Основной файл:

import log from "./functions.js";
log("123");

Файл functions.js (в той же папке):

export function log(text)
{
	console.log(text);
}

Классы

В javascript вместо метода __init__ есть метод constructor.

Вместо self - this.

Поля класса можно объявлять вне конструктора.

В javascript не нужно писать this первым параметром!

class Person
{
	can_swim = true;
	constructor(name, age) {
		this.name = name;
		this.age = age;
	}

	print_name() {
		console.log(this.name);
	}
	get_age() {
		return this.age;
	}
}

Создание экземпляра класса:

const tom = new Person("Tom", 45);
tom.print_name();
tom.can_swim = false;

Наследование:

class Worker extends Person
{
	constructor(name, work) {
		super(name, 30); // вместо super().__init__(name, 30)
		//Вызов родительского конструктора обязателен
		//Он должен быть в самом начале
		this.work = work;
		this.can_swim = false;
	}
	print_name() {
		super.print_name();
		console.log("work: " + this.work);
	}
}

Проверка, принадлежит ли объект к классу:

const worker = new Worker("John", "Miner");
const number = 15;

const a = worker instanceof Worker; // a == true
const b = worker instanceof Person; // b == true
const c = number instanceof Person; // c == false
			

Если не поставить ;

В большинстве случаев это ничего не изменит, но иногда могут появиться неожиданные ошибки. Например:

const a = [[10, 20], [30, 40]]

[1].forEach(num => console.log(num)); // Кажется, что выведется цифра 1, но нет! Выведятся числа 30 и 40!

Для тех, кто не знает, что делает forEach: он для каждого элемента вызывает функцию, которую вы ему передали. В этом случае функция просто выводит в консоль элемент.

Почему вывод будет 30 и 40? Потому что интерпретатор воспринимает этот код так:

const a = [[10, 20], [30, 40]][1].forEach(num => console.log(num));

Элемент с индексом 1 как раз [30, 40], а в переменной 'a' будет undefined.

Для избежания такой проблемы достаточно поставить ; в конце первой строчки.

А оно-то по-другому!

То, что в javascript по-другому.

[a, b] = [b, a] вместо: a, b = b, a

В javascript есть объекты null, undefined, NaN и Infinity:

NaN - объект типа число, хоть и означает Not a Number, то есть Не Число

Infinity - объект типа число, бесконечность

null, undefined - тоже, что и None в python

console.log(NaN == NaN); // Вывод: false. NaN не равно NaN!
console.log(isNaN(NaN)); // Вывод: true. Проверять надо так
const a = "2" + 1; // a == '21', ошибки не будет!
const b = "2" - 1; // b == 1, ошибки не будет!
const c = "4" / 2; // c == 2, ошибки не будет!
const d = "2" * 3; // d == 6, а не '222'!
const e = [2] * 3; // e == 6, а не ['2', '2', '2']!
const f = "a" * 3; // isNaN(f), а не 'aaa'!
const g = [2, 1] * 2; // isNaN(g), а не ['2', '1', '2', '1']!
const h = 5 / 0; // h == Infinity, ошибки не будет!

Оператор in в javascript проверяет не то, есть ли в списке такой элемент, а есть ли такое свойство.

const a = ["a", "b", "c"];
console.log(1 in a); // Вывод: true. Так как в списке есть элемент с таким индексом

const b = {a: "123", b: "abc"};
console.log("a" in b); // Вывод: true. Так как в объекте есть значение по ключу 'a'

В javascript нет целочисленного деления (// - в python), но можно сделать его так:

const a = Math.floor(15 / 2);

В javascript нет функций int, float, str, вместо них можно использовать parseInt, parseFloat и `${что-то}` соответственно. Функции parseInt и parseFloat не выдают ошибку в случае, если нельзя переобразовать в число, а просто вернут NaN.

HTML страница

Для корректной работы каждая HTML страница должна быть составлена по определённому шаблону:

<!DOCTYPE html>
<html lang="ru">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
</head>
<body>
	<!-- Содержимое страницы -->
</body>
</html>

Шаблон страницы с комментариями:

<!DOCTYPE html>
<!-- Тип документа -->

<html lang="ru">
<!-- Начало HTML страницы, атрибут lang указывает язык вашей страницы для правильной работы поисковых систем -->

<head> <!-- Начало служебной части страницы -->

	<meta charset="UTF-8">
	<!-- Указывает, что надо использовать кодировку UTF-8, иначе вместо руских букв будут закорючки -->

	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<!-- Ширина страницы изменится по ширине экрана телефона -->

	<title>Document</title>
	<!-- Заголовок страницы, тот, что написан на вкладке -->

</head> <!-- Конец служебной части -->
<body> <!-- Начало содержимого страницы -->

	<!-- Сюда и надо добавлять тексты, кнопки и картинки -->

</body> <!-- Конец содержимого -->
</html> <!-- Конец страницы -->

HTML: Основные теги

Немного о том, что можно добавить в body

Универсальный тег div - можно назвать его контейнером для элементов. Отделить часть страницы, добавить отдельный блок, или когда стандартные теги не подходят.

Тег span можно вставлять внутрь текста без видимых изменений.

<p>Тег span можно вставлять <span>внутрь текста</span> без видимых изменений.</p>
<p>Абзац</p>
<p><i>Наклонный</i> и <b>жирный</b> текст.</p>

Картинки

<img scr="Ссылка на картинку">

Ссылки


<a href="Адрес ссылки" target="_blank">Текст ссылки</a>

target="_blank" - значит открывать ссылку в новой вкладке (желательно всегда добавлять)

Вместо текста в ссылку можно вставить другие теги, например, картинку:

<a href="https://yandex.ru/" target="_blank">
	<img scr="Ссылка на картинку">
</a>

Ввод данных

<button>Кнопка</button>
<input type="text">
<input type="number">
<input type="date">
<input type="color">
<input type="range">
<input type="checkbox">
<input type="radio" name="input-radio">
<input type="radio" name="input-radio">

Для input типа radio необходимо указать атрибут name, чтобы всегда был выбран только один.

Больше о теге input в главе Тег input.

Таблицы

С помощью таблиц легко расположить элементы на странице.

<table>
	<tr><th>Заголовок 1</th><th>Заголовок 2</th></tr>
	<tr><td>Ячейка 1</td><td>Ячейка 2</td></tr>
	<tr><td>Ячейка 3</td><td>Ячейка 4</td></tr>
</table>
Заголовок 1Заголовок 2
Ячейка 1Ячейка 2
Ячейка 3Ячейка 4

<table> - Таблица

<tr> - Строка

<td> - Ячейка

<th> - Ячейка, заголовок

Заголовки

<h1>Заголовок</h1>

<h2>Заголовок</h2>

<h3>Заголовок</h3>

<h4>Заголовок</h4>

<h5>Заголовок</h5>
<h6>Заголовок</h6>

Списки

<ul>

</ul>

<ol>

  1. <li>Элемент списка</li>
  2. <li>Элемент списка</li>
  3. <li>Элемент списка</li>

</ol>

CSS

С помощью CSS можно делать очень красочные и анимированные сайты. Здесь будут рассмотрены только основы.

В CSS есть наследование стилей, то есть если вы укажите шрифт у body, то у элементов внутри него тоже применится этот шрифт. Но если у элемента внутри body тоже будет указан шрифт, то применится он. Наследование работает не со всеми свойствами и тегами.

Добавление стилей

Способ 1: Внутри HTML тега, в атрибуте style:

<p style="стиль: значение; стиль: значение;"></p>

Такой способ усложняет написание HTML.

Способ 2: Внутри head:

<head>
	<style>
		/* Стили */
	</style>
	<!-- Либо в отдельном файле (.css): -->
	<link rel="stylesheet" href="styles.css"> <!-- Ссылка на файл (styles.css) со стилями -->
</head>

Написание стилей

Для написания стилей необходимо указать, к каким элементам они будут применятся.

Элемент можно указывать по тегу, id или классу.

id нужен для получения элемента в javascript
Классы как раз для стилей.

<p class="имена классов через пробел"></p>

Имена классов и id можно писать любые, главное - одно слово, так как имена разделяются пробелами.

Стили указываются по такому формату:

селектор {
	свойство: значение;
	свойство: значение;
}

Точка с запятой в конце свойства обязательна!

Для выбора всех элементов по *** необходимо написать:

Для указания стиля к разным элементам перечислите их через запятую.

Например, сделаем всем абзацам (<p>) и элементам с классом pink розовый цвет букв, а элементам с классом crossed сделаем зачеркнутые буквы:

p, .pink {
	color: pink;
}
.crossed {
	text-decoration: line-through;
}

<p>Абзац</p>

<span class="pink crossed">Элемент с классом blue и crossed</span>


Указать элемент можно также через его родительские элементы:

p span { /* Стили для span который внутри абзаца */
	color: pink;
}

<span>span не внутри абзаца</span>

<p>Абзац<span>span внутри абзаца</span></p>


Другие способы указания элементов, а также свойства которые есть у элементов будут рассмотрены в следующих темах.

Javascript на странице

Добавить javascript на страницу можно несколькими способами.

Весь код на странице будет находится в общей памяти. То есть, если в одном из скриптов вы создадите переменную или функцию, то она будет доступна и в других скриптах на вашей странице (по-другому при использовании модулей).

Вариант 1: Добавить код прямо в HTML файл.

Для этого необходимо добавить тег script, внутри него можно писать любой код. Тег можно добавить в head или в body.

<head>
	<script>
		// Любой код
		console.log("Hello world!");
	</script>
</head>

Имейте в виду, что страница строится сверху вниз, и если вы поставите скрипт в начале, вы не сможете в нём получить элементы страницы, так как они ещё не созданы.

<body>
	<script>
		// Абзац ещё не создан, его не получится получить в коде
	</script>
	<p>Абзац с текстом</p>
	<script>
		// Абзац уже создан, его можно получить в коде
	</script>
</body>

Вариант 2: Добавить на страницу ссылку на файл.

В отличие от предыдущего варианта, тегу можно добавить атрибут defer, который означает, что код запустится после создания всей страницы.

<head>
	<script src="./main.js" defer></script>
</head>

Атрибут scr указывает где файл. Как писать путь файла:

"./" - значит: в той же папке где и страница

"../" - значит: на уровне выше

Примеры:

"js/main.js" - значит в папке js, которая находится в той же папке, что и страница, файл main.js

"../js/main.js" - значит на уровне выше, чем файл страницы в папке js файл main.js

Обратите внимание, что скрипты выполняются по-очереди - сверху вниз. Поэтому, если у вас есть файл с функциями, его нужно загрузить раньше, чем файл, где вы их используете.

<head>
	<script src="./functions.js" defer></script> <!-- Сначала выполнится этот -->
	<script src="./main.js" defer></script> <!-- Потом этот -->
</head>

Вариант 3: Использование модулей

Работают, только если страница находится на сервере!

В этом случае каждый файл будет находиться в отдельной памяти. Вы сможете не беспокоиться о том, что вы уже использовали это имя функции в другом файле.

Для доступа к объектам из другого файла нужно будет писать import, а в файле, из которого вы импортируете - export, перед тем, что вы хотите экспортировать.

При использовании модулей, в HTML достаточно написать только скрипт, с которого начинается ваша программа. Ваш скрипт сам загрузит файлы, которые вы указали в import, а те файлы тоже сами догрузят необходимое.

Для использования модулей необходимо добавить атрибут type="module".

Модули всегда запускаются после загрузки страницы, атрибут defer не нужен.

<head>
	<script src="./main.js" type="module"></script>
</head>

Файл main.js (в той же папке):

import log from "./functions.js";
log("123");

Файл functions.js (в той же папке):

export function log(text)
{
	console.log(text);
}

Как создать проект

Для редактирования HTML, CSS и javascript я рекомендую студию Visual Studio Code.

Создайте папку для проекта, в этой папке создайте два файла:

index.html - стандартное имя главной HTML страницы на сайте.

styles.css - для стилей.

Создайте папку js, и в этой папке файл main.js

Если вы работаете в студии VS Code, то можете в папке с вашим проектом нажать "ПКМ -> Открыть с помощью Code" - для открытия студии в этой папке.

Заполните HTML файл

<!DOCTYPE html>
<html lang="ru">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<link rel="stylesheet" href="styles.css">
	<!-- Место для других js файлов -->
	<script src="js/main.js" defer></script>
</head>
<body>
	<!-- Содержимое страницы -->
</body>
</html>

С использованием js модулей

<!DOCTYPE html>
<html lang="ru">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<link rel="stylesheet" href="styles.css">
	<script src="out/main.js" type="module"></script>
</head>
<body>
	<!-- Содержимое страницы -->
</body>
</html>

CSS значения

Цвета

Цвета можно указывать названием, в формате RGB, RGBA, HSL, HSLA, а также шестнадцатеричным значением.

color: blue;
color: #00ffff;
color: rgb(125, 15, 200);
color: rgba(125, 15, 200, 0.5);

Единицы измерения

В CSS существуют разные единицы измерения:

Не рекомендуется указывать размер в пикселях, так как размер экрана у всех разный.

Процент размера шрифта берётся от его изначального размера в браузере.

Ширина, указанная в процентах, считается относительно ширины родительского элемента.

inherit и initial

Указываются вместо любого значения, означают:

inherit - значение свойства наследуется у родительского элемента.

initial - устанавливается исходное значения свойства.

CSS селекторы

В CSS много способов указания элементов, также существуют псевдо-классы, которые позволяют менять стили, например, при наведении курсора на элемент.

Выбор элементов

Указать элемент можно, написав его тег, класс или id. Для применения стиля к разным элементам их можно написать через запятую:

тег, .класс, #id { }

Для указания элемента с определённым классом или id, нужно написать тег и имя класса (или id) без пробелов:

p.bold { } /* Стили для p, у которого класс bold */

Можно указать элемент через те, в которые он вложен, написав через пробел:

p span { } /* Стили для span, который внутри p */
<p><span>Стили поменяются здесь</span></p>
<div><span>А здесь нет</span></div>
<p>
	<div>
		<span>А здесь поменяются, так как span внутри p</span>
	</div>
</p>

Для указания элементов по их родительскому, необходимо написать символ >:

p > span { } /* Стили для span, у которого родительский элемент p */
<p><span>Стили поменяются здесь</span></p>
<div><span>А здесь нет</span></div>
<p>
	<div>
		<span>И здесь нет, так как у span родительский элемент div</span>
	</div>
</p>

Также можно указать элемент, который находится строго после другого, написав символ +:

span + span { } /* Стили для span, который идёт после span*/
<span>Здесь стили не поменяются</span>
<span>Стили поменяются здесь</span>
<span>И здесь тоже</span>
<p>Здесь - нет, т. к. не span</p>
<span>И здесь тоже нет, т. к. предыдущий элемент p</span>

Все селекторы можно изучить по ссылке.

Псевдо-классы

Псевдо-классы позволяют указывать элементы более конкретно, а также менять стили при взаимодействии пользователя со страницей.

:first-child и :last-child - позволяют выбрать первый и последний элемент.

:nth-child(n) - позволяет выбрать n-ный элемент:

span:first-child { } /* Стили для span, который первый внутри чего-либо */
span:nth-child(2) { } /* Стили для span, который второй внутри чего-либо */
span:last-child { } /* Стили для span, который последний внутри чего-либо */
<p>
	<span>Этот span - :first-child и :nth-child(1)</span>
	<span>Этот span - :nth-child(2)</span>
	<span>Этот span - :nth-child(3)</span>
	<span>Этот span - :last-child и :nth-child(4)</span>
</p>

:hover - позволяет выбрать элемент, на который навели курсор:

span:hover { color: red; }

span элемент:

Наведите сюда курсор.

:focus - позволяет выбрать элемент, который в фокусе:

input:focus { background-color: lightblue; }

input элемент (нажмите на него):

:active - позволяет выбрать элемент, на который нажимают:

button:active { color: red; }

button элемент:

Все псевдо-классы можно изучить по ссылке.

CSS: Основные свойства

Цвета

color - цвет текста.

background-color - цвет фона.

width и height

Свойства width и height соответственно.

Значения этих свойств можно установить в:

Также существуют свойства min-width, max-width и min-height, max-height - для указания максимальных и минимальных размеров.

Например, вы можете указать ширину в 50%, но не больше чем 600px и не меньше, чем 100px:

width: 50%;
min-width: 100px;
max-width: 600px;
		

Рамка

border: толщина стиль цвет;
border-radius: радиус;

Например:

p {
	border: 3px solid lime;
	border-radius: 5px;
}

Абзац с рамкой

Виды рамки:

solid
dashed
dotted
double
groove
ridge
inset
outset

Можно настроить свойства рамки по отдельности:

Рамку можно настроить для всех сторон индивидуально, дописав сторону к свойству:

Все стороны: top, right, bottom, left.

Отступы

Отступ от границы элемента до:

Как выглядит элемент с margin, border и padding:

margin
border
padding
Содержимое элемента, например, текст.

Два div'а без margin и padding:

Первый div
Второй div

С margin и padding:

Первый div
Второй div

Отступы тоже можно настроить для всех сторон индивидуально, дописав сторону к свойству:

Текст

Свойства для настройки текста:

text-decoration примеры:

none underline line-through overline

По умолчанию линия под текстом будет прерываться:

Добро пожаловать, хорошего дня!

С text-decoration-skip-ink: none:

Добро пожаловать, хорошего дня!

text-align примеры:

text-align: left

text-align: center

text-align: right

text-align: justify. Для демонстрации необходимо больше текста. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In a placerat metus. Etiam in felis laoreet, tempor est sed, consequat orci.

text-align: left. Для сравнения с justify. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In a placerat metus. Etiam in felis laoreet, tempor est sed, consequat orci.

position

Устанавливает способ позиционирования элемента на странице.

Значения:

При absolute и fixed элемент перестаёт занимать место среди других элементов.

Пример sticky: панель вверху с кнопками "Назад", "На главную" и "Сменить тему".

Для указания положения элементов необходимо использовать свойства top, right, bottom и left

Пример:

.container {
	position: relative;
	min-height: 100px;
	background-color: gray;
}
.element1, .element2 {
	position: absolute;
	width: 50px;
	height: 50px;
	top: 20px;
	left: 10px;
	background-color: lime;
}
.element2 {
	top: -20px;
	left: 70px;
}

display

Устанавливает, как элемент должен быть показан в документе.

Все значения display на этом сайте.

Css: Переменные

Переменные должны начинаться с двойного дефиса:

--имя-переменной: любое значение;

Для использования своей переменной в качестве значения, необходимо написать её внутри var():

color: var(--ваша-переменная);

Использовать переменные можно, например, для того, чтобы сделать разные темы на сайте:

Цвет, шрифт, размер шрифта - всё можно указать переменными.

Значения всех переменных можно определить в одном месте и потом менять у <body> класс (с помощью javascript):

.light-theme {
	--color-text: black;
	--color-back: white;
}
.dark-theme {
	--color-text: white;
	--color-back: black;
}

body {
	background-color: var(--color-back);
	color: var(--color-text);
}
<body class="light-theme">
	<p>Текст</p>
</body>

Функция calc()

Функция calc() позволяет делать математические действия.

Пример:

.something {
	width: calc(50% - 5em);
}

Взаимодействие со страницей

Для взаимодействия со страницей нужно уметь получать элемент со страницы в виде объекта, а так же создавать и добавлять новые элементы на страницу.

Получить элемент

Элемент <body> находится в document.body

document.getElementById("id") - получить элемент можно по id. Он должен быть уникальным у всех элементов, иначе результат будет непредсказуем.

document.querySelectorAll("селектор") - получить все элементы (массивом) по CSS селектору.

document.querySelector("селектор") - получить первый подходящий элемент по CSS селектору.

Получить элемент через другой

el.firstChild - первый дочерний элемент

el.lastChild - последний дочерний элемент

el.parentNode - родительский элемент

Создать элемент

const el = document.createElement("тег");

Добавить элемент

Добавить элемент внутрь данного:

el.appendChild(элемент); // В конец
el.insertBefore(элемент, элемент2); // Перед элемент2

Удалить элемент из HTML

el.removeChild(элемент); // удалить дочерний элемент

Элемент как объект

В javascript HTML элементы представлены в виде классов. Изменив значения полей объекта, вы поменяете и сам HTML элемент.

Свойства HTML элементов:

Содержимое

el.innerText - текст внутри элемента.

el.innerHTML - HTML внутри элемента, строка, содержащая HTML теги.

Стили

el.style - объект, содержащий все стили элемента.

Для каждого CSS свойства в style есть поле с его значением.

В именах из нескольких слов тире убираются, а следующая буква делается заглавной:

CSS свойство background-color в объекте style поле backgroundColor.

Значения в style не пустые в случае, если стили указаны в атрибуте style или через javascript.

Классы

el.classList - объект, содержащий все классы элемента, итерируемый.

el.classList.add("class") - добавить класс.

el.classList.remove("class") - удалить класс.

el.classList.toggle("class") - если есть - удалить, если нет - добавить класс.

el.classList.contains("class") - проверить наличие класса, возвращает true или false.

Атрибуты

Атрибуты элементов располагаются в соответствующих полях, например:

Атрибут href у ссылок: el.href,

Атрибут type у <input>: el.type.

События

Интерактивность!

Событие – это сигнал от браузера о том, что что-то произошло.

На каждое событие можно подписаться и ваша функция будет вызываться каждый раз, когда оно случается. Также в качестве параметра в вашу функцую передадутся подробности события.

Когда на элементе происходит событие, обработчики сначала срабатывают на нём, потом на его родителе, затем выше и так далее, вверх по цепочке предков.

Для определения, на каком элементе произошло событие, у него есть свойство target, в нём хранится элемент, на котором оно произошло.

Обработчики события

Обработчик события можно добавить к HTML элементу:

el.addEventListener("событие", ваша_функция);
// Можно и удалить:
el.removeEventListener("событие", ваша_функция);

Обработчик события, добавленный к объекту window - самый глобальный.

Так обработчик не удалится:

el.addEventListener("событие", (e) => doSmth(e));
el.removeEventListener("событие", (e) => doSmth(e));

так как (e) => doSmth(e) - это создание новой, уже другой функции. А для удаления обработчика необходимо указывать ту же функцию.

События

У событий, связанных с мышью, есть свойства, содержащие её координаты:

У событий, связанных с клавиатурой, есть свойства, содержащие нажатую клавишу:

Глава code и key любой клавиши.

Пример использования событий

<p id="display-move">Курсор: X: -- Y: --</p>
<p id="display-click">Нажатие: X: -- Y: --</p>

Курсор: X: -- Y: --

Нажатие: X: -- Y: --

const display_move = document.getElementById("pg15-display-move");
const display_click = document.getElementById("pg15-display-click");

window.addEventListener("mousemove", e => {
	display_move.innerText = `Курсор: X: ${e.pageY} Y: ${e.pageY}`;
});
window.addEventListener("click", e => {
	display_click.innerText = `Нажатие: X: ${e.pageY} Y: ${e.pageY}`;
});
		

Больше CSS свойств

visibility

Значения: visible или hidden.

При visibility: hidden элемент продолжает занимать место на странице.

visibility: hidden <-- hidden

visibility: visible

opacity

Значения от 0 до 1.

opacity: 1
opacity: 0.7
opacity: 0.4
opacity: 0.1

z-index

Расположение элемента по "высоте":

z-index: 1
z-index: 2
z-index: 1

cursor

Курсор при наведении на элемент. Виды (наведите курсор для просмотра):

Все виды курсоров на этом сайте.

Тег input

Подробнее о его возможностях и как им можно пользоваться.

Виды input

Для указания вида поля ввода у него есть атрибут type.

У input можно указать дополнительные атрибуты для настройки поля ввода.

У любого типа input есть атрибут value, содержащий значение поля.

<input type="text" maxlength="число" placeholder="Подсказка">
<input type="number" min="число" max="число" step="число" placeholder="Подсказка">
<input type="range" min="число" max="число" step="число">
<input type="date" min="дата в формате ГГГГ-ММ-ДД" max="дата">
<input type="color">
<input type="checkbox">
<input type="checkbox" checked>
<input type="radio" name="input-radio">
<input type="radio" name="input-radio" checked>

Для input типа radio необходимо указать атрибут name, чтобы всегда был выбран только один.

Любому input можно добавить атрибут disabled для блокировки взаимодействия с ним:

<input type="text">
<input type="text" disabled>

Javascript

Получив input элемент в виде объекта, вы можете получить/изменить его значение:

События

У input есть два полезных события:

input - происходит каждый раз при изменении значения пользователем.

changed - происходит, когда пользователь завершил ввод (нажал вне поля ввода, закрыл меню выбора цвета/даты).

CSS анимации

CSS анимации поддерживаются не всеми браузерами, см. таблицу совместимости.

Для анимации необходимо настроить два CSS свойства:

Длительность анимации указывается в секундах: 5s или милисекундах: 500ms

Не все свойства можно анимировать.

Пример анимации:

.anim-rect {
	transition-property: background-color;
	transition-duration: 1s;
	background-color: blue;
}
.anim-rect:hover {
	background-color: red;
}
Наведите курсор
Без анимации
.anim-button {
	transition-property: color, background-color;
	transition-duration: 500ms;
	background-color: lightblue;
	color: black;
}
.anim-button:active {
	background-color: blue;
	color: lime;
}

Сложные анимации

Можно делать анимации по ключевым кадрам.

Создание ключевых кадров:

@keyframes название-анимации {
	0% { /* Начало анимации */
		/* значения свойств на данном этапе анимации */
	}
	50% { } /* Можно добавить любое количество промежуточных этапов */
	25%, 75% { }
	100% { } /* Конец анимации */
}

Добавление анимации:

animation: название-анимации продолжительность кол-во-повторений направление-анимации;
/* Или: */
animation-name: название-анимации;
animation-duration: продолжительность-анимации;
animation-iteration-count: кол-во-повторений-анимации;
animation-direction: направление-анимации;

Количество повторений анимации можно указать числом или infinite - бесконечно.

Направление анимации можно указать в alternate - анимация, дойдя до конца, проигрывается в обратном направлении.

Количество повторений и направление анимации указывать не обязательно.

Пример:

@keyframes cool-animation {
	0% {
		background-color: cyan;
		width: 100px;
	}
	50% {
		background-color: lime;
	}
	100% {
		background-color: yellow;
		width: 100%;
	}
}
.anim-div {
	animation: cool-animation 2s infinite alternate;
	height: 100px;
}

Все про анимацию можно узнать на этом сайте.

Учебник по анимации на этом сайте.

Тег canvas

Канва - это место, где вы можете рисовать.

Атрибутами width и height можно указать размер холста в пикселях. Размер канвы, указанный стилями, не изменяет размер холста, изображение будет расстягиваться под размер канвы.

Размер холста можно изменить и через javascript:

const canvas = document.getElementById("canvas");
canvas.width = 300;
canvas.height = 300;

Для рисования необходимо получить контекст канвы:

const ctx = canvas.getContext("2d");

Теперь можно рисовать:

ctx.fillRect(x, y, width, height); // Закрасить прямоугольник
ctx.strokeRect(x, y, width, height); // Рамка прямоугольника
ctx.clearRect(x, y, width, height); // Очистить прямоугольник

ctx.fillText("текст", x, y); // Нарисовать текст
ctx.strokeText("текст", x, y); // Нарисовать рамку текста

// Рисование путей:
ctx.beginPath(); // Начать путь

ctx.moveTo(x, y); // Передвинуть карандаш
ctx.lineTo(x, y); // Провести линию от позиции карандаша к x, y
ctx.arc(x, y, radius, startAngle, endAngle); // дуга с центром в x, y
ctx.arcTo(x1, y1, x2, y2, radius); // сложная дуга
;
ctx.stroke(); // Закончить путь и нарисовать его
// или
ctx.fill(); // Закончить путь и заполнить его

Изменение стилей:

ctx.fillStyle = "цвет"; // Цвет заливки
ctx.strokeStyle = "цвет"; // Цвет линий
ctx.lineWidth = width; // Толщина линий
ctx.font = "10px шрифт"; // Размер и шрифт текста

Начальный и конечный угол дуги указывается в радианах. 360° == 2 * Math.PI.

Из градусов в радианы: x / 180 * Math.PI

Из радиан в градусы: x / Math.PI * 180

Пример

<canvas id="canvas"></canvas>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

canvas.height = 300;
canvas.width = 300;

ctx.font = "120px Arial";
ctx.fillStyle = "blue";
ctx.strokeStyle = "lime";
ctx.lineWidth = 5;

ctx.fillRect(10, 10, 100, 80);
ctx.strokeRect(20, 20, 100, 80);
ctx.clearRect(90, 30, 50, 50);

ctx.fillText("Текст", 0, 200);
ctx.strokeText("Текст", 0, 240);

ctx.beginPath();
ctx.moveTo(30, 30);
ctx.lineTo(40, 60);
ctx.lineTo(60, 40);
ctx.lineTo(80, 70);
ctx.stroke();

ctx.beginPath();
ctx.arc(155, 40, 30, 0, Math.PI * 2);
ctx.arc(230, 40, 30, Math.PI, Math.PI * 2);
ctx.fill();
ctx.beginPath();
ctx.arc(240, 80, 30, Math.PI / 2, Math.PI * 1.8);
ctx.fill();

canvas анимации

Для создания анимаций или игр на канве необходимо обновлять канву несколько раз в секунду. Для этого существует функция requestAnimationFrame().

В качестве параметра она принимает функцию, которую необходимо вызвать. Этой функции она передаст прошедшее время первым параметром.

Пример использования:

mainLoop(0);
function mainLoop(time) {
	// Любые действия

	requestAnimationFrame(mainLoop);
}

Например, анимация квадрата:

<canvas id="canvas"></canvas>
const width = 300;
const height = 100;
const rectSize = 50;
const rectSpeed = 5;
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

canvas.height = height;
canvas.width = width;
ctx.fillStyle = "blue";

const rectY = (height - rectSize) / 300;
let rectX = 0;
let rectDirection = 1;

mainLoop();
function mainLoop() {
	const nextX = rectX + rectSpeed * rectDirection;
	if (nextX < 0 || nextX > width - rectSize)
	{
		rectDirection *= -1;
	}
	rectX = nextX;

	ctx.clearRect(0, 0, width, height);
	ctx.fillRect(rectX, rectY, rectSize, rectSize);

	requestAnimationFrame(mainLoop);
}

Функция range()

Моя реализация функции range() из python.

Работает так же:

function* range(start_stop, stop = undefined, step = 1)
{
	const start = stop == undefined ? 0 : start_stop;
	stop = stop == undefined ? start_stop : stop;
	const sign = Math.sign(step);
	stop *= sign
	for (let i = start; i * sign < stop; i += step)
	{
		yield i;
	}
}

Использование:

for (const i of range(10)) {
	console.log(i);
}
// Или:
for (let i of range(10)) {
	console.log(i);
}

code и key любой клавиши

Нажмите любую клавишу.

Красивые кнопки

Стандартные кнопки выглядят неплохо, но не всегда.

В стилях ниже, для настройки цвета кнопок есть переменные --color и --back-color.

Добавим же стили:

.cool-button {
	--color: white;
	--back-color: #0d6efd;
	transition: background-color box-shadow;
	transition-duration: 200ms;
	background-color: var(--back-color);
	color: var(--color);
	padding: 0.4em 0.6em;
	border-radius: 0.25em;
	border: none;
	outline: none;
}
.cool-button:hover {
	box-shadow: 0px 0px 0px 0.1em var(--back-color);
}
.cool-button:active {
	box-shadow: inset 0px 0px 0px 0.1em var(--back-color);
}
		

Другой вариант:

.cool-button2 {
	--color: #0d6efd;
	--back-color: white;
	transition: background-color color;
	transition-duration: 150ms;
	background-color: var(--back-color);
	color: var(--color);
	padding: 0.4em 0.6em;
	border-radius: 0.25em;
	border: 0.15em solid var(--color);
	outline: none;
}
.cool-button2:hover {
	background-color: var(--color);
	color: var(--back-color);
}
.cool-button2:active {
	transition-duration: 0ms;
	background-color: var(--back-color);
	color: var(--color);
}

Ещё один вариант:

.cool-button3 {
	--color: white;
	--back-color: #0d6efd;
	transition: background-color box-shadow;
	transition-duration: 200ms;
	background-color: var(--back-color);
	color: var(--color);
	padding: 0.4em 0.6em;
	border-radius: 0.25em;
	border: none;
	outline: none;
}
.cool-button3:hover {
	box-shadow: 0px 0.6em 0.7em -0.2em var(--back-color);
}
.cool-button3:active {
	transform: translateY(0.2em);
	box-shadow: 0px 0.4em 0.3em -0.1em var(--back-color);
}

И ещё один вариант:

.cool-button4 {
	--color: white;
	--back-color: #0d6efd;
	transition: background-color;
	transition-duration: 100ms;
	background-color: var(--back-color);
	color: var(--color);
	padding: 0.4em 0.6em;
	border-radius: 0.25em;
	text-decoration-skip-ink: none;
	border: none;
	outline: none;
}
.cool-button4:hover {
	text-decoration: underline;
}
.cool-button4:active {
	text-decoration: none;
}

3D куб

1
2
3
4
5
6

HTML куба:

<div class="rect3d"> <!-- контейнер -->
	<div> <!-- куб -->
		<!-- стороны куба -->
		<div>1</div>
		<div>2</div>
		<div>3</div>
		<div>4</div>
		<div>5</div>
		<div>6</div>
	</div>
</div>
		

Стили:

.rect3d { /* Контейнер */
	height: 80px;
	padding: 25px;
	text-align: center;
}
.rect3d div { /* Куб */
	--size--: 40px;
	height: calc(var(--size--) * 2);
	width: calc(var(--size--) * 2);
	transform-style: preserve-3d;
	animation: rect3d-anim 3s linear infinite;
	display: inline-block;
}
/* Стороны: */
.rect3d div div:nth-child(1) {
	background-color: rgba(90, 90, 90, 0.7);
	transform: translateZ(var(--size--));
}
.rect3d div div:nth-child(2) {
	background-color: rgba(0, 210, 0, 0.7);
	transform: rotateY(180deg) translateZ(var(--size--));
}
.rect3d div div:nth-child(3) {
	background-color: rgba(210, 0, 0, 0.7);
	transform: rotateY(90deg) translateZ(var(--size--));
}
.rect3d div div:nth-child(4) {
	background-color: rgba(0, 0, 210, 0.7);
	transform: rotateY(-90deg) translateZ(var(--size--));
}
.rect3d div div:nth-child(5) {
	background-color: rgba(210, 210, 0, 0.7);
	transform: rotateX(90deg) translateZ(var(--size--));
}
.rect3d div div:nth-child(6) {
	background-color: rgba(210, 0, 210, 0.7);
	transform: rotateX(-90deg) translateZ(var(--size--));
}
/* Анимация вращения: */
@keyframes rect3d-anim {
	from {
		transform: rotate3d(1, 1, 1, 0deg);
	}
	to {
		transform: rotate3d(-0.5, 0.5, 0.8, 360deg);
	}
}