⚽ Champions League updates from the 8pm BST kick-off⚽ Live scores | Read Football Daily | And you can mail Niall
Close dialogue1/1Next imagePrevious imageToggle captionSkip to key eventsPrint subscriptionsSearch jobs Sign indocument.addEventListener('DOMContentLoaded', function () {
/** The checkbox input element used to toggle the navigation menu. */
const navInputCheckbox = document.getElementById('header-nav-input-checkbox');
/** The veggie burger button element used to open/close the menu. */
const veggieBurger = document.getElementById('header-veggie-burger');
/** List of menu items that should be selectable when the menu is open. */
const expandedMenuClickableTags = document.querySelectorAll(
'.selectableMenuItem',
);
/** The root element of the expanded menu. */
const expandedMenu = document.getElementById('header-expanded-menu-root');
/** The label for the first column in the menu, assumed to be "News".*/
const firstColLabel = document.getElementById('News-button');
/** The link element in the second list item under news links. */
const firstColLink = document.querySelector(
'#newsLinks > li:nth-of-type(2) > a',
);
/**
* Focuses on the first navigation element depending on whether the first column label is visible.
*
* If the first column label is not visible, the function focuses on the first link element.
* Otherwise, it focuses on the first column label.
*/
const focusOnFirstNavElement = () => {
if (window.getComputedStyle(firstColLabel).display === 'none') {
firstColLink.focus();
} else {
firstColLabel.focus();
}
};
/**
* Updates ARIA attributes and tabindex values based on whether the menu is open or closed.
*/
const updateAttributesForMenu = (isOpen) => {
firstColLabel.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
veggieBurger.setAttribute(
'data-link-name',
isOpen
? 'header : veggie-burger : hide'
: 'header : veggie-burger : show',
);
expandedMenuClickableTags.forEach((tag) => {
tag.setAttribute('tabindex', isOpen ? '0' : '-1');
});
};
/** Toggles the navigation menu by simulating a click on the checkbox. */
const toggleMainMenu = () => {
if (navInputCheckbox) {
navInputCheckbox.click();
}
};
/**
* Handles keydown events to toggle the menu when the Enter or Space key is pressed.
*/
const keydownToggleMainMenu = (e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
toggleMainMenu();
}
};
/**
* Handles click events to manage the state of the navigation menu.
*
* - Toggles the menu open/close state when the menu button (veggieBurger) is clicked.
*/
const handleMenuClick = (e) => {
const menuButtonClicked = navInputCheckbox === e.target;
const clickInsideMenu = expandedMenu.contains(e.target);
const menuIsOpen = navInputCheckbox.checked
if (menuButtonClicked && !menuIsOpen) {
document.body.classList.toggle('nav-is-open')
firstColLabel.setAttribute('aria-expanded', 'false')
veggieBurger.setAttribute('data-link-name','header : veggie-burger : show')
expandedMenuClickableTags.forEach(function($selectableElement){
$selectableElement.setAttribute('tabindex','-1')
})
} else if (menuButtonClicked && menuIsOpen) {
document.body.classList.toggle('nav-is-open')
firstColLabel.setAttribute('aria-expanded', 'true')
veggieBurger.setAttribute('data-link-name','header : veggie-burger : hide')
expandedMenuClickableTags.forEach(function($selectableElement){
$selectableElement.setAttribute('tabindex','0')
})
focusOnFirstNavElement()
}
};
/** Adds event listeners to manage the navigation menu. */
if (navInputCheckbox) {
navInputCheckbox.addEventListener('click', handleMenuClick);
veggieBurger.addEventListener('keydown', keydownToggleMainMenu);
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && navInputCheckbox.checked) {
toggleMainMenu();
veggieBurger.focus();
}
});
/**
* Handles mouse down events to manage the state of the navigation menu.
*
* - Closes the menu if the click occurs outside both the menu button and the expanded menu.
*/
document.addEventListener('mousedown', function(e){
if(navInputCheckbox.checked && !expandedMenu.contains(e.target) && !veggieBurger.contains(e.target)){
toggleMainMenu()
}
});
}
});UKUK editionUS editionAustralia editionEurope editionInternational editionThe Guardian - Back to homeThe GuardianNewsOpinionSportCultureLifestyleShow moreHide expanded menudocument.addEventListener('DOMContentLoaded', function(){
var columnInput = document.getElementById('News-button');
if (!columnInput) return; // Sticky nav replaces the nav so element no longer exists for users in test.
columnInput.addEventListener('keydown', function(e){
// keyCode: 13 => Enter key | keyCode: 32 => Space key
if (e.keyCode === 13 || e.keyCode === 32) {
e.preventDefault()
document.getElementById('News-checkbox-input').click();
}
})
})NewsView all NewsUK newsUS politicsWorld newsClimate crisisMiddle EastUkraineFootballNewslettersBusinessEnvironmentUK politicsScienceTechGlobal developmentObituariesdocument.addEventListener('DOMContentLoaded', function(){
var columnInput = document.getElementById('Opinion-button');
if (!columnInput) return; // Sticky nav replaces the nav so element no longer exists for users in test.
columnInput.addEventListener('keydown', function(e){
// keyCode: 13 => Enter key | keyCode: 32 => Space key
if (e.keyCode === 13 || e.keyCode === 32) {
e.preventDefault()
document.getElementById('Opinion-checkbox-input').click();
}
})
})OpinionView all OpinionThe Guardian viewColumnistsCartoonsOpinion videosLettersdocument.addEventListener('DOMContentLoaded', function(){
var columnInput = document.getElementById('Sport-button');
if (!columnInput) return; // Sticky nav replaces the nav so element no longer exists for users in test.
columnInput.addEventListener('keydown', function(e){
// keyCode: 13 => Enter key | keyCode: 32 => Space key
if (e.keyCode === 13 || e.keyCode === 32) {
e.preventDefault()
document.getElementById('Sport-checkbox-input').click();
}
})
})SportView all SportFootballCricketRugby unionTennisCyclingF1GolfBoxingRugby leagueRacingUS sportsdocument.addEventListener('DOMContentLoaded', function(){
var columnInput = document.getElementById('Culture-button');
if (!columnInput) return; // Sticky nav replaces the nav so element no longer exists for users in test.
columnInput.addEventListener('keydown', function(e){
// keyCode: 13 => Enter key | keyCode: 32 => Space key
if (e.keyCode === 13 || e.keyCode === 32) {
e.preventDefault()
document.getElementById('Culture-checkbox-input').click();
}
})
})CultureView all CultureFilmMusicTV & radioBooksArt & designStageGamesClassicaldocument.addEventListener('DOMContentLoaded', function(){
var columnInput = document.getElementById('Lifestyle-button');
if (!columnInput) return; // Sticky nav replaces the nav so element no longer exists for users in test.
columnInput.addEventListener('keydown', function(e){
// keyCode: 13 => Enter key | keyCode: 32 => Space key
if (e.keyCode === 13 || e.keyCode === 32) {
e.preventDefault()
document.getElementById('Lifestyle-checkbox-input').click();
}
})
})LifestyleView all LifestyleThe FilterFashionFoodRecipesTravelHealth & fitnessWomenMenLove & sexBeautyHome & gardenMoneyCarsSearch input google-search SearchSupport usPrint subscriptionsSearch jobsHire with Guardian JobsHolidaysLive eventsAbout UsDigital ArchiveGuardian Print ShopPatronsGuardian LicensingThe Guardian appVideoPodcastsPicturesNewslettersToday's paperInside the GuardianGuardian WeeklyCrosswordsWordiplyCorrectionsTipsSearch input google-search SearchSearch jobsHire with Guardian JobsHolidaysLive eventsAbout UsDigital ArchiveGuardian Print ShopPatronsGuardian LicensingFootballLive scoresTablesFixturesResultsCompetitionsClubsChampions LeagueChampions LeaguePorto v Manchester City: Champions League – live⚽ Champions League updates from the 8pm BST kick-off
⚽ Live scores | Read Football Daily | And you can mail Niall
Key events35m agoTeam news1h agoPreamble Erling Haaland is in the house. Photograph: Diogo Cardoso/UEFA/Getty ImagesView image in fullscreenErling Haaland is in the house. Photograph: Diogo Cardoso/UEFA/Getty ImagesNiall McVeighTue 8 Sep 2026 19.39 BSTFirst published on Tue 8 Sep 2026 18.30 BSTShareKey events35m agoTeam news1h agoPreamblenow19.39 BSTFT: Club Brugge 2-3 Aston Villa They were pushed all the way, but Villa begin their campaign with a very useful three points. Rob Smyth has the latest …
Read moreShare3m ago19.37 BSTHead to head: Porto have played Manchester City four times in Europe, and are yet to beat them. In the 2020-21 Champions League, City won 3-1 at home and drew 0-0 away in the group stage – before going on to lose the final to Chelsea in this very stadium.
The two sides also met in the 2011-12 Europa League knockouts, with City winning 6-1 on aggregate, before getting bundled out by Sporting in the next round.
12m ago19.28 BSTOver in Bruges, Aston Villa are holding on to a 3-2 lead with 10 minutes to go. Follow that one with Rob Smyth …