Hello everyone and thanks for the help in advance. Full disclosure, I am a back end developer (C#, SQL Server, etc.) and should not be allowed to develop UI. However, my wife is asking me to do so for her practice, so here I am. Please refer to https://kidsmedicalcare.com:43443/. I am trying to do some basic toggling between a full screen and mobile. I employed some basic media queries that do not seem to be working. Any feedback would be appreciated.
You seem to have mostly media queries for large screen so the small screen code is everything outside those rules.
Your header seems to be obeying the rules you gave it and the text and layout is reduced on screens less than 768px so that seems to be working.
You may need to be more explicit and let us tackle one problem at a time
I do notice some silly mistakes though as you have this:
abpseal {
width: 200px;
}
pcmhseal {
width: 200px;
}
There are no html called pcmhseal or abpseal but you do have classes.
e.g.
.abpseal {
width: 200px;
}
.pcmhseal {
width: 200px;
}
Fix those errors first and then point us to a problem area that you are working on
Also stop adding inline styles as they will win out over your media queries.
e.g.
<div id="divwelcome" name"divwelcome"="" style="font-size: 7em; color: teal; font-weight: 900; float: right; padding-right: .5em; text-align: center; -webkit-text-stroke-width: 2px;
-webkit-text-stroke-color: black;">
<span style="font-size: 1.5em;">Welcome</span><br>
To Your
Child's<br>
Medical Home
<!--
<span style="font-size: 7em; color: teal; font-weight: 900; float: right; padding-right: .5em; text-align: center; -webkit-text-stroke-width: 2px;
-webkit-text-stroke-color: black;">
Welcome<br />
To Your
Child's<br />
Medical Home
</span>
-->
<div id="divcallnow" name="divcallnow" style="background-color: darkorange; color: white; padding: .2em; border-radius: 10px;">
Call (239) 591-8481
</div>
</div>
You can’t change those inline styles from your media query unless you append every single one using !important which is a big no no and should be avoided at all costs
.. and fix typos like this:
name"divwelcome"=""
As I mentioned above if you don’t remove the inline styles then your media queries will need to us !important like this which is not best practice:
@media only screen and (max-width: 768px) {
#splash{
height:auto!important;
text-align:center;
min-height:40vh;
}
#divwelcome{
float:none!important;
font-size:3rem!important;
padding-right:0!important;
}
#divcallnow{
font-size:2em;
}
#divpcmh{
display:block!important;
}
.abpseal,.pcmhseal{
max-width:100%;
height:auto;
display:block;
margin:auto;
}
}
If you added that media query at the end of all your css then the small screen would look like this image:
First of all, thank you for all of your help and patience. I removed (I think) all of the inline css, but am still not getting the same results.
It’s working but why did you remove the padding-right:0 from here?
#divwelcome{
float:none!important;
font-size:3rem!important;
padding-right:0!important;
}
And why did you add a width:40% here:
#divwelcome {
float: none !important;
font-size: 3rem !important;
padding-right: 0 !important;
width: 40%;
}
Both your changes will break the layout.
You don’t want a width there as that means there’s no room for the text and you need to remove the padding right or it will all be offset.
Those 2 changes will get it back to looking like my screenshot.
Of course there’s a lot else you could refine but you need to get it it to a basic usable state first and then you can fine-tune text sizes and whatever else needs changing.
Also remember that as you have removed the inline styles you need replace them in the css with the styling you wanted. You can also now remove the !important from the styles I gave you.
As an aside topic your hero image is much too tall as you have made it height:100vh which means that it goes well below the fold because you have the header and navigation above it. It would have been better if the hero image only went to the bottom of the viewport which could be done automatically and without forcing heights but would require a complete change of structure.
I’ll be back tomorrow as going offline now.
Once again, thank you. Unless I’m missing something, I’m not sure where the changes are that you’re referring to. I reloaded the site and and will keep debugging.
Ok. I loaded what I think are the suggested changes, but don’t seem to get the same results. Regarding the hero image, are you saying to resize the image or simply change the vh value?
Its getting closer
There’s also some right padding on #splash that needs to be removed in the small screen media query.
#splash {
height: auto!important;
text-align: center;
min-height: 40vh;
padding-right: 0;/* add this */
}
Also I would reduce the call now text even more as its much too large on small screen. Try .8em:
#divcallnow {
font-size: .8em;
}
Both those rules are in your max-width:768px media query.
Then it will roughly look like this on small screens.
It’s just a matter of tweaking things until they fit better.
I would just reduce the vh value a little as you are going too far below the viewport. (To have an automatic viewport height would require a change of structure like the demo I posted and is probably not viable for you at this stage.)
Also on large screens your hero image isn’t going edge to edge (as on my monitor) so you probably should be using background-size:cover
on #splash. The text is also very large but I guess that’s your design choice.
Being that your project appears to be vanilla HTML etc, it seems to me it is a good candidate for introducing CSS Grid and Flexbox — it’s not constricted by some wrapping theme or framework.
I have to head out but have spent 15 minutes trying to refactor your nav’s HTML. You have a comment about using nav
so I have included that
Also given the medical nature of your site, in particular I think accessibility might be an important aspect — I have started to introduce some aria attributes etc into the menus.
<header class='main-header'>
<div class='main-header-container'>
<div class='header-info'>
<img class='logo' src='/images/Kids_Logo_100.jpg' alt="Diana McLaughlin, MD Kids' Medical Care Logo" />
<div>
<h1>Diana McLaughlin, M.D.</h1>
<p class='kids'>Kids' Medical Care</p>
<address class='suite'>10661 Airport Pulling Road Suite 9, Naples, FL 34109</address>
</div>
</div>
<address class='header-contact'>
<p>Phone: (239) 591-8481</p>
<p>Fax: (239) 596-0212</p>
</address>
</div>
<div class='primary-navigation-container'>
<!-- Can add an eventListener to this button in Javascript -->
<!-- Can use aria-expanded in CSS to toggle menu -->
<button
id='primary-navigation-toggle'
aria-controls='primary-navigation'
aria-expanded='false'
>
<!-- for accessibility, this span will be hidden but readable by screen readers -->
<span class='visually-hidden'>Main Menu Toggle Button</span>
<i>☰</i>
</button>
<nav
id='primary-navigation'
class='primary-navigation'
>
<ul>
<li><a href='/'>Home</a></li>
<li><a href='../About/Bio'>About</a></li>
<li><a href='../About/Why_Choose_a_Pediatrician'>Why Choose a Pediatrician</a></li>
<li><a href='../Home/BusinessHours'>Hours</a></li>
<li><a href='../About/AfterHours'>After Hours</a></li>
<li><a href='../About/Appointments'>Appointments</a></li>
<li><a href='../About/PCPChoice'>PCP</a></li>
<li><a href='../About/MedicalHome'>Medical Home</a></li>
<li><a href='../About/EvidenceBasedCare'>Evidence Based Care</a></li>
<li><a href='../Resources/Forms'>Forms</a></li>
<li><a href='../Directions'>Directions</a></li>
</ul>
</nav>
</div>
</header>
This headers HTML can be styled with the use of flexbox and some absolute positioning for the drop down.
The JS can hook onto the button in the form of an eventListener attached to the button element.
Edit: I am currently working on a menu myself, which is why I maybe getting a bit carried away. That said with regards accessibility this might be an interesting read.
Edit2: Have added links to the above text, which might be helpful to you.
Seeing as you started I have carried on with the rest of the page and I would be looking at something like this html wise.
<div class="wrapper homepage">
<header class="main-header" role="banner">
<div class="main-header-container">
<a href="/" class="logo-link" itemprop="url">
<img class="logo" src="/images/Kids_Logo_100.jpg" alt="Diana McLaughlin, MD Kids' Medical Care Logo" />
</a>
<div class="inner-header">
<h1>Diana McLaughlin, M.D.</h1>
<p class="kids">Kids' Medical Care</p>
<p class="suite">10661 <span>Airport Pulling Road</span> <span>Suite 9</span>, Naples, <span>FL 34109</span></p>
</div>
<!-- Only one main address per page. Use address tag in the footer instead. -->
<div class="header-contact">
<p><a href="tel:+12395918481" itemprop="telephone">239-591-8481</a></p>
<p>Fax: (239) 596-0212</p>
</div>
</div>
<nav id="primary-navigation" aria-label="Primary navigation" class="primary-navigation">
<!-- Can add an eventListener to this button in JavaScript -->
<!-- Can use aria-expanded in CSS to toggle menu -->
<button id="primary-navigation-toggle" aria-controls="primary-navigation" aria-expanded="false">
<!-- For accessibility, this span will be hidden but readable by screen readers -->
<span class="visually-hidden">Main Menu Toggle Button</span>
<i>☰</i>
</button>
<ul>
<li><a href="/">Home</a></li>
<li><a href="../About/Bio">About</a></li>
<li><a href="../About/Why_Choose_a_Pediatrician">Why Choose a Pediatrician</a></li>
<li><a href="../Home/BusinessHours">Hours</a></li>
<li><a href="../About/AfterHours">After Hours</a></li>
<li><a href="../About/Appointments">Appointments</a></li>
<li><a href="../About/PCPChoice">PCP</a></li>
<li><a href="../About/MedicalHome">Medical Home</a></li>
<li><a href="../About/EvidenceBasedCare">Evidence Based Care</a></li>
<li><a href="../Resources/Forms">Forms</a></li>
<li><a href="../Directions">Directions</a></li>
</ul>
</nav>
</header>
<section id="splash" class="hero" aria-label="Homepage introduction">
<h2>
<span>Welcome</span>
<span>To your Child's</span>
<span>Medical Home</span>
</h2>
<p class="call-now" itemprop="telephone">Call: <a href="tel:+12395918481">239-591-8481</a></p>
</section>
<main>
<div class="pcmh" id="divpcmh">
<img src="/images/630f3a479fdc650f10414e09_ABP_Parent-Certified-Logo.png" alt="American Board of Pediatrics Logo" class="abpseal" />
<img src="/images/62_PCMH_CMYK.jpg" alt="Patient Centered Medical Home Logo" class="pcmhseal" />
</div>
</main>
<footer class="footer" itemscope itemtype="http://schema.org/Physician" role="contentinfo">
<p class="footer-name" itemprop="name">Diana McLaughlin, M.D., P.A. - Kids' Medical Care</p>
<p class="description" itemprop="description">Pediatrics and Adolescent Medicine</p>
<address class="postal-address" itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
<p class="street-address" itemprop="streetAddress">
<a href="https://goo.gl/maps/inyqjQKZqZPyTwJc9">10661 Airport Pulling Road, Suite 9</a>
</p>
<div>
<span itemprop="addressLocality">Naples,</span>
<span itemprop="addressRegion">FL</span>
<span itemprop="postalCode">34109</span>
</div>
<p class="tel" itemprop="telephone">
Phone: <a href="tel:+12395918481">239-591-8481</a>
</p>
</address>
</footer>
</div>
If I get a chance later this afternoon I’ll add some basic css to show my approach
I had to make a couple of changes to the html to get the structure I wanted but here is the basic thing styled with css and responsive.
The codepen is here:
The live codepen page is here for a full screen view:
I’m not expecting you to switch all your code over to this but rather in an exercise as to show how things can become responsive with only a few media queries. The html structure is more semantic, readable and accessible.
There are obviously finer details and tweaks that can be made but that can all be done within that structure. The structure is designed for the home page only but can easily be adapted for other pages if the wrapper and splash are removed.
Hope it helps anyway if only as eye candy
I had a go at the about page. Hamburger menu isn’t implemented at this point.
I’ve used flexbox (no floats in sight), I am sure Paul will be able to spot on a glaring mistakes
HTML for about page
<div class='container'>
<header class='main-header'>
<div class='main-header-container'>
<img
class='main-header-logo'
src='https://assets.codepen.io/3351103/Kids_Logo_100.jpg'
alt="Diana McLaughlin, MD Kids' Medical Care Logo"
/>
<div class='main-header-info'>
<h1 class='main-header-info__title'>
<span class='provider-name'>Diana McLaughlin, M.D.</span><br />
<span class='clinic-name'>Kids' Medical Care</span>
</h1>
<address class='main-header-info__address'>10661 Airport Pulling Road Suite 9, Naples, FL 34109</address>
</div>
<address class='main-header-contact'>
Phone: (239) 591-8481<br>
Fax: (239) 596-0212
</address>
</div>
<div class='primary-navigation-container'>
<!-- Can add an eventListener to this button in Javascript -->
<button
id='primary-navigation-toggle'
aria-controls='primary-navigation'
aria-haspopup='true'
aria-expanded='false'
>
<!-- for accessibility, this span will be hidden but readable by screen readers -->
<span class='visually-hidden'>Main Menu Toggle Button</span>
<img src='https://assets.codepen.io/3351103/hamburger.svg' alt=''>
</button>
<nav
id='primary-navigation'
class='primary-navigation'
aria-labelledby='primary-navigation-toggle'
>
<ul role='list'>
<li><a href='/'>Home</a></li>
<li><a class='active' href='../About/Bio'>About</a></li>
<li><a href='../About/Why_Choose_a_Pediatrician'>Why Choose a Pediatrician</a></li>
<li><a href='../Home/BusinessHours'>Hours</a></li>
<li><a href='../About/AfterHours'>After Hours</a></li>
<li><a href='../About/Appointments'>Appointments</a></li>
<li><a href='../About/PCPChoice'>PCP</a></li>
<li><a href='../About/MedicalHome'>Medical Home</a></li>
<li><a href='../About/EvidenceBasedCare'>Evidence Based Care</a></li>
<li><a href='../Resources/Forms'>Forms</a></li>
<li><a href='../Directions'>Directions</a></li>
</ul>
</nav>
</div>
</header>
<main>
<div class='main-container'>
<section class='section hero'>
<h2 class='hero__title'>About Diana McLaughlin, M.D.</h2>
<div class='biography-container'>
<img src='https://assets.codepen.io/3351103/Diana_Lupe.jpg' alt='Dr. McLaughlin and Lupe'/>
<div class='biography-description'>
<p>Since 1993, Diana McLaughlin, MD has been a pediatrician in Naples, Florida. She is the founder and owner of Kids' Medical Care who has provided care to literally tens of thousands of children in Naples and Southwest Florida during it history.</p>
<p>Dr. McLaughlin is board certified by the American Board of Pediatircs and Kids Medical Care is recognized by the National Center for Quality Assurance as a Patient Centered Medical Home.</p>
</div>
</div>
</section>
<section class='section'>
<h2>Experience</h2>
<ul>
<li>Founded Kids' Medical Care in 1993</li>
<li>Certified by American Board of Pediatrics </li>
<li>Mother of three daughters</li>
</ul>
</section>
<section class='section'>
<h2>Education and Training</h2>
<ul>
<li>Ambulatory Care Fellowship Miami Children's Hospital, Miami, Florida</li>
<li>Pediatrics Resident Training Levels I, II, III Miami Children's Hospital, Miami, Florida</li>
<li>Medical Doctor State University of New York Downstate Medical Center, NY</li>
<li>Bachelor of Science St. John's University New York, NY</li>
<li>Juris Doctorate - University of Miami- School of Law</li>
<li>Masters in Business Administration - Florida Gulf Coast University</li>
</ul>
</section>
</div>
</main>
<footer class='footer'>
<div>
<p>Diana McLaughlin, M.D., P.A. - Kids' Medical Care</p>
<p>Pediatrics and Adolescent Medicine</p>
<address>
<a href='https://goo.gl/maps/inyqjQKZqZPyTwJc9'>10661 Airport Pulling Road, Suite 9</a><br>
Naples, FL 34109<br>
Phone: <a href='tel:+12395918481'>239-591-8481</a>
</address>
</div>
</footer>
</div>
Looks good to me.
Update, I have added a functioning drop down menu. Same link.
A live view.
The menu is toggled opened and closed by setting the aria-expanded attribute to ‘true’ or ‘false’.
I have tried to follow some accessibility guidelines.
-
Buttons, links etc should be accessible by tabbing through them with the tab key and shift + tab key for reverse order.
-
When the hamburger button is in focus, hitting space will toggle the menu open and closed.
-
When the menu is opened you can only tab through the menu items e.g. when you reach the bottom menu item, the next item will be the top menu item. The same applies to shift tabbing in reverse.
-
Hitting the escape key when the menu is open will close the menu setting focus to the hamburger menu button.
-
When the menu is closed the menu items will not be tab focusable.
-
When switching out of mobile view all listeners are removed and elements returned to default settings.
-
When switching into mobile view the eventlisteners are added
I had dreams of achieving this is CSS only
The JS is very rough and ready and in need of a refactor. There is also the issue of the home link not being tab focusable when the menu is closed.
Note: I have used the HTML ‘inert’ attribute to remove the ability to tab child elements. This isn’t currently available in Safari, so I will need to look for an alternative. Maybe by setting tabindexes instead.
A couple of js functions I have been using
https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
You have been busy. I prefer your design
Just setting the menu to display:none will remove it from the tab order as in my example above. You can tab ok backwards and forwards and when the menu is op-en you can tab through it.
OFF-TOPIC
Apart from the escape key you could do most of that in css but would rely on the checkbox hack (although you could make a case for using popover which allows previously impossible things to be done. (or even the dialogue element)).
That was very helpful and enabled me to clean up the JS.
I think I will call this done.
Selecting the last indexed item
A small thing, but I need to be able to check whether focus is on the last menu item. It can be done like this, but having to calculate based on the length does bug me.
target === menuItems[menuItems.length-1]
In python that would be a more concise
target == menuItems[-1]
Javascript has introduced array.prototype.at which can be used in a similar fashion.
target == menuItems.at(-1)
I have opted to use that and added a basic polyfill.
Polyfill for Array.at()
// Polyfill for Array.prototype.at method
if (!Array.prototype.at) {
Object.defineProperty(Array.prototype, 'at', {
value: function(index) {
// Convert index to integer
index = Math.trunc(index) || 0;
// Handle negative indexing
if (index < 0) index += this.length;
// Return undefined if out of bounds
if (index < 0 || index >= this.length) return undefined;
return this[index];
},
writable: true,
enumerable: false,
configurable: true
});
}
I’ve also added just a few basic helper functions, which I think make the main code more readable and remove repetition
Helper functions
// Utility functions to manage the navigation menu state
function isExpanded (elem) {
return elem.ariaExpanded === 'true';
}
function notExpanded (elem) {
return elem.ariaExpanded === 'false';
}
function expandMenu (navToggleButton) {
navToggleButton.ariaExpanded = 'true';
}
function collapseMenu (navToggleButton, focusOnButton = true) {
navToggleButton.ariaExpanded = 'false';
// optionally focus the toggle button when collapsing the menu
if (focusOnButton) {
navToggleButton.focus();
}
}
Main code
// Initialize the primary navigation menu on page load
window.addEventListener('DOMContentLoaded', function() {
const primaryNavContainer = document.querySelector('.primary-navigation-container');
const primaryNav = primaryNavContainer.querySelector('#primary-navigation');
const primaryNavToggle = primaryNavContainer.querySelector('#primary-navigation-toggle');
// Collect all menu items for tabbing management
const menuItems = Array.from(primaryNav.querySelectorAll('li > a'));
// handle click events to toggle the menu
function toggleHandler () {
if (isExpanded(primaryNavToggle)) {
collapseMenu(primaryNavToggle);
} else {
expandMenu(primaryNavToggle);
}
}
// Handle key presses for accessibility
function keyPressHandler (event) {
if (notExpanded(primaryNavToggle)) return;
const { target, key, shiftKey } = event
// close menu adding focus to menu toggle button
if (key === 'Escape') {
collapseMenu(primaryNavToggle);
return;
}
// while menu is open contain tabbing within the menu items
if (key === 'Tab') {
// if shift tabbing from the first menu item, skip to the last item
if (shiftKey && target === menuItems.at(0)) {
event.preventDefault(); // prevent default tabbing behavior
menuItems.at(-1).focus(); // focus the last menu item
return;
}
// if tabbing from the last menu item, skip to the first item
if (!shiftKey && target === menuItems.at(-1)) {
event.preventDefault();
menuItems.at(0).focus(); // focus the first menu item
return;
}
}
}
// Handle closing menu in desktop view
function resizeHandler (event) {
if (event.matches) {
// If the viewport is wider than 768px, ensure the menu is closed
if (isExpanded(primaryNavToggle)) {
collapseMenu(primaryNavToggle, false);
}
}
}
function init() {
// set breakpoint for media query
const mediaQuery = window.matchMedia('(min-width: 768px)');
// Set initial state of the navigation
primaryNavToggle.ariaExpanded = 'false';
// add handlers
primaryNavToggle.addEventListener('click', toggleHandler);
primaryNavContainer.addEventListener('keydown', keyPressHandler);
mediaQuery.addEventListener('change', resizeHandler)
// Initial check on page load
resizeHandler(mediaQuery);
}
// Initialize the navigation menu
init();
});
Currently I have it setup so that if the menu is open tabbing is contained within that menu until you hit escape. It can be easily amended so that if you tab out of the menu top or bottom the menu can collapse instead.
Maybe it’s me but creating menus always turns into an involved process. An interesting learning exercise, it’s just retaining that information that is an issue.
I have updated the codepen with this new code.
So I walked away for a couple of days and miracles happened. Thank you both for the help. I need to go through these examples in detail as this is way beyond my skills set. I will be back with questions. Thank you both again.
Again, thanks for the response and all of the help. I’m trying to work through the concepts of grid vs. flex and how they were utilized in your solution. The use of flex for the logos, I assume, is to allow the images to stack within the divpcmh element. Could you please explain the use of grid in this solution as I don’t understand why you selected that.
On a separate note, I have never worked with SCSS and wonder why you selected this for the about page. Looks great, but really left me inn the dust.
Grid vs Flexbox
Nothing is fixed in stone but the general idea is that grid can be used for your main page layouts and enables you to break sections of the page down into columns.
Flexbox suits headers quite well, space-between to separate the logo from menus, and flex for the menu items themselves where you have numerous items that you want to align and have wrap around at smaller screen sizes.
I will add I don’t know these in-depth, there is always a bit of trial and error, and I have to refer to MDN or similar throughout the process.
In the about page example, I didn’t use grid for the main page. For the hero section with the image of Diana and text I opted to use flexbox. It seemed a simple solution.
I did use grid for the menu, but this was to enable me to add vertical reveal effect. I toggle between grid-template-rows: 0fr
and grid-template-rows: 1fr
with a transition transition: grid-template-rows 250ms ease-in-out
. This enables me to add a pure CSS solution, without the need for Javascript to calculate the height of the menu. Menus are always a bit tricky
BTW, Kevin Powell’s video tutorials on youtube are excellent. He has numerous videos on grid and flexbox and worth checking out. For starters