body {
min-height: 100vh;
display: flex;
flex-direction: column;
}
main {
flex-grow: 1;
}
let menuElem1= $('.menu--main')[0]; // выбираем ul с меню
let titleElem1 = $(menuElem1).children('li'); // собираем все вложенные в меню элементы li
// блокируем переходы по ссылкам верхнего уровня меню (если нужно обрабатывать только с вложением - надо либо классы добавить и целиться на них, либо придумывать другой механизм, убирать к примеру ссылки или еще что-нибудь)
$(titleElem1).children('a').click(function(event){
event.preventDefault();
});
// собственно функция обработки клика на заголовке. Убирает со всех элементов класс open, добавляет на кликнутый элемент класс open.
$(titleElem1).on('click', function() {
$(titleElem1).removeClass('open');
$(this).toggleClass('open');
});
let basicMaterial = new THREE.MeshBasicMaterial({color: 0x0095DD});
let cube = new THREE.Mesh(geometry, basicMaterial);
Решение прижать футер к низу окна выполнено.
Короткая страница с блоками - будет просвет между блоком и футером. Тут никуда не деться без дополнительных извращений.
Полноценная страница на три экрана - последний блок должен упираться в подвал без просвета.
Если нет какой-то паразитной верстки со стилями, добавляющими отступы и/или имеющими свои значения высоты, которые свешиваются из блоков - никаких просветов не будет.