Responsive page not responding in the way I would like

Hi,

Please find codepen below - I think I have successfully cut and pasted in the relevant code and trimmed out as much irrelevant code as possible - the problem remains in the codepen.

The problem I am trying to fix is that when the viewport width exceeds about 1200px a gap appears between the bottom of the text (ie after “to suit your needs”) and the bottom of the pale yellow box of .

What I want to happen is for the to finish under this text and for the two images to fill the right hand column height. Ideally this would be filled by the images each taking half the height and being centred and the right and left sides being cropped. I only want this ehaviour to occur above the 992px breakpoint.

I hope I have explained this OK. Any help/comments gratefully received. Thank you.

Did you mean something like this:

<meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <link rel="icon" href="favicon.ico" type="image/x-icon"/>
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Chelsea+Market&display=swap" rel="stylesheet">
    <script src="https://use.fontawesome.com/c192036237.js"></script>
    <title>
      Outdoor Learning Cardiff | Sticks And Stones Outdoor Learning | Wales
    </title>


  <?php
    //define a variable to make the current page's menu item show the current page
    $thisPage='teachers';
  ?>   
    
    <header>
      <picture>
        <source type="https://www.danieljeffery.co.uk/sheena/image/webp" srcset="images/logo.webp" />
        <img src="https://www.danieljeffery.co.uk/sheena/images/logo.jpg" alt="logo" height="100" class="logo" />
      </picture>
<?php
require 'includes/menu.php';      
?>      
    </header>
    <main class="container">
      
      <h1>
        What we have to offer for schools
      </h1>
      <section class="teachersSection">
        <article>
          <p class="teacherSubTitle">Delivery of Outdoor Learning in schools</p> 
          <p class="teachersText">If you would like to use your school grounds for learning, Sticks and Stones will come to you. We can work with one class at a time on a subject of your choice saving you the expense of coach travel. If you would prefer to visit a local woodland this can be arranged. Check out the visits available here.</p>
          
          <p class="teacherSubTitle">Forest School</p>
          <p class="teachersText">If you would like your class to attend regular sessions and learn more about nature whilst boosting their confidence and physical development then more information on Forest School can be found here.</p>

          <p class="teacherSubTitle">Staff Training</p>
          <p class="teachersText">Not sure how to make the most of learning opportunities in your school grounds or local green spaces? Sticks and Stones offers a range of training sessions for education professionals including: Muddy Marvelous, Natural Literacy, Messy Math and bespoke courses to suit your needs.</p>
        </article>

        <article class="teachersArticle">
        <picture>
            <source type="https://www.danieljeffery.co.uk/sheena/image/webp" srcset="images/teachers1.webp" />
            <img src="https://www.danieljeffery.co.uk/sheena/images/teachers1.jpg" alt="toddler sitting in a meadow, playing with flowers" class="teachersImage" />
          </picture>
          <picture>
            <source type="image/webp" srcset="https://www.danieljeffery.co.uk/sheena/images/teachers2.webp" />
            <img src="https://www.danieljeffery.co.uk/sheena/images/teachers2.jpg" alt="child sitting under a structure constructed with branches" class="teachersImage"  />
          </picture>  
        </article> 
      </section>  
      
    </main>
    <div>
    </div>
<?php
require 'includes/footer.php';      
?>
 /* Override browser defaults */
* {
      padding: 0px;
      border: 0px;
      margin: 0px;
      box-sizing: border-box;
  }

article h1{
  font-size: 2rem;
}

img,source{
  display:block;
}

 /* Define 'variables' to be used for colours*/
:root{
  --headlineColor: #ca6;
  --textColor: #094;
  --backgroundColor: #ffe;
  --otherColor: #ce6;
  --otherColor2: #fa5;
}

html {
  height: 100%;
}

body {
  background-image: url("https://www.danieljeffery.co.uk/sheena/images/background.jpg");
  background-size: 100% 100vw;
  display: grid;
  grid-template-columns: auto;
  grid-template-rows: auto auto 1fr auto;
  justify-items: center;
  align-items: center;
  gap: 20px;
  min-height: 100%;
}

h1, h2, h3, h4, h5, h6 {
  font-family: 'Chelsea Market', cursive;
  color: var(--headlineColor);
  padding: 5px;
  Margin: 5px;
}

p,address, span, ul, li, dl, dt, dd{
  font-family: 'Chelsea Market', cursive;
  color: var(--textColor);
  font-size: 1.2rem;
  padding: 5px;
  Margin: 5px;
}

dt {
  color: var(--headlineColor);
  margin: 0 0 0 30px;
}

li{
  padding: 0;
  margin: 0 0 0 60px;
}

header {
  margin: 3px;
  display: flex;
  flex-direction: row;
  width: 70%;  
  align-items: flex-start;
  gap: 5px;
  }

a:link, a:visited {
  color: var(--headlineColor);
  text-decoration: none;
}

a:hover {
  color: var(--textColor); 
}

.logo{
border: solid 1px var(--headlineColor);
}

.container {
  min-height: 100%;
  width: 90%;
  background-color: var(--backgroundColor);
  border-radius: 4px;
}

.teachersSection{
  display:grid;
  grid-template-rows: auto auto auto;
  grid-template-columns: auto;
  padding: 0 20px 20px 20px;
  gap: 20px;
}
 
.teacherSubTitle{
  color: var(--otherColor);
  padding: 0px;
  margin: 0 20px 0 20px;
}

.teachersText{
  padding: 0 20px 10px 20px;
  margin: 0px;
}

.teachersImage{
  height: 50%;
  width: 100%;
  object-fit: cover;
  margin: 20px 0;
}

.teachersArticle{
  overflow: hidden;
}

/* *** Desktop *** */
@media screen and (min-width: 992px){
  
.teachersSection{
  grid-template-columns: 30vw auto;       
  grid-template-rows: 1fr;
  gap: 20px;
} 

.teachersImage{ 
  padding: 0 0px 0 0;
  object-fit: cover; 
}   
}

/* *** Tablet and desktop *** */
@media screen and (min-width: 600px) {

  p, th, td, input, select, pre, span, ul, li, dl, dt,dd{
    font-size: 1rem;
  }
    
  .container {
    width: 70%;
  }    
      
header {
  align-items: flex-end;
  }
}


@media screen and (min-width: 992px){
  
  .teachersSection{position:relative;}
  .teachersArticle{position:relative;}
  .teachersArticle img{position:absolute;}
  main.container{min-height:0;}
    .teachersArticle img{
      position:absolute;
top:0;
      left:0;
      width:100%;
      height:46%;
      object-fit:cover;
  }
  .teachersArticle picture + picture img{
    top:52%;
  }
  
}

Specifically:

@media screen and (min-width: 992px) {
  .teachersSection {
    position: relative;
  }
  .teachersArticle {
    position: relative;
  }
  .teachersArticle img {
    position: absolute;
  }
  main.container {
    min-height: 0;
  }
  .teachersArticle img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 46%;
    object-fit: cover;
  }
  .teachersArticle picture + picture img {
    top: 52%;
  }
}

Yes, I mean exactly like that. Thank you so much. I have such a lot to learn. I will now go and look at what you did. I see some arithmetics in there - I didn’t know one could do that. Thank you again.

Doh! I now see that the “+” sign is adjacent sibling, not arithmetic.

1 Like

Not specific to your particular problem, but since you brought it up… you CAN do arithmetic in CSS, like this for example:

#box {width:calc(100% - 2px)}

You could look up the calc() function to see lots of ways to use it.

1 Like

Interesting. Thank you for that. CSS is so complicated!

OK - my brain is not big enough. I see that the above declaration block positions the second image below the first. And I think

    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 46%;
    object-fit: cover;
  }

positions the first image?

But I don’t understand how the relative and absolute positions work in this context (I have looked up what they mean).

If I can explain the whole logic it may be easier to understand but there are a few concepts that we need to work with and around.

Firstly you want the height of the text content to dictate the height of the two images so they match the total height of the text. Although with css (grid/flexbox) we can equalise both columns, the tallest column will always dictate the height of the other column. Therefore when we want an image to only occupy 50% height of the text we can’t simply set the image to 50% height because the browser won’t be able to work out what height that is as that column’s own height will be based on its own content (i.e. its images). It’s a circular reference that CSS can’t resolve (although you may find that the odd browser will attempt to do this). e.g. my height is twice the height of something that is half my height; and the height of the smaller something is half the height of my height!

In order to solve this conundrum I remove the image from the flow with absolute positioning. This means that the height of the right column is solely dependent on the height of the text in the left column as grid makes the equal column automatically.

An absolute element is removed from the flow and placed in relation to its nearest ancestor that has a position defined (other than static). If none exists it is placed in relation to :root (effectively the body element). In order to make the image start in the right column we apply position:relative to the right column (which does not alter its position or appearance) and now the image can be placed absolutely using the right column as its point of reference.

An absolute element always knows the top, right, left and bottom of a relative parent (unlike static elements) and we can use that knowledge to make our image 50% of the height of that area. It is then just a matter of placing the first image at top:0 and then the second image at top:50% and setting the image height to 50%. Note that I used 46% image height and top:52% just to make space between the images but if you wanted no space then they would all be at the 50% value.

To recap an absolute element is placed in relation to its nearest positioned ancestor. Note that absolute elements are removed from the flow and do not affect the height of the parent at all. If the parent has no height then there will be nothing to show. However in our case, and as is the case with grid or flexbox or table cells, you can have columns that equalise automatically to the tallest content even if some items have no content (as would be the case with absolutely placed children).

Hope that explains it :slight_smile:

3 Likes

Wow! Thank you so much for your time and expertise.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.