1

G'day.

I am working on a responsive website. This is what I am trying to make the header section look like on desktop and mobile respectively: Page header mockup The contents of id="header" are supposed to take up as much space as they need to but no more than a 100% of the page's width. I am having trouble coming up with a structure that could be turned responsive and creating the grid in general. Is there a similar grid somewhere I could take a look at? or should I simply go with a table instead of trying to come up with a "CSS-only" solution?

I would be very grateful for a solution that'd work with my current structure. Please let me know if there is anything I need to mention to make this question understandable (if it isn't) and thank you in advance for any help you provide.

I have looked through a number of tutorials and stackoverflow questions where similar layouts have been pursued and I have tried a number of approaches using position and CSS tables, but so far I have not been successful.

Here's my HTML:

<!DOCTYPE html>
<html>
<head lang="en-au">
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
    <div id="container" class="dtable">
        <div id="header" class="dtrow">
            <div class="dtable">
                <div class="dtrow">
                    <div class="dtcell" id="logo"></div>
                    <div class="dtcell">
                        <div class="dtable">
                            <div class="dtcptn">
                                <span class="cblock" id="menu">
                                    <a href="#">Link #0</a>
                                    <a href="#">Link #1</a>
                                    <a href="#">Link #2</a>
                                    <a href="#">Link #3</a>
                                    <a href="#">Link #4</a>
                                    <a href="#">Link #5</a>
                                    <a href="#">Link #6</a>
                                    <a href="#">Link #7</a>
                                </span>
                            </div>
                            <div class="dtrow">
                                <div class="dtcell">
                                    <span class="cblock">Phone</span>
                                </div>
                                <div class="dtcell">
                                    <span class="cblock">Social</span>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div id="content" class="dtrow">

        </div>
        <div id="footer" class="dtrow">
            <span class="cblock">&copy; The three musketeers, 2017. Say hello to the UFO.</span>
        </div>
    </div>
</body>
</html>

Here's my CSS:

@charset "utf-8";

* { box-sizing: border-box; }

a { display: inline-block; text-decoration: none; }
a:hover { text-decoration: underline; }
body, html { font-family: Helvetica, Arial, sans-serif; font-size: 16px; height: 100%; margin: 0; padding: 0; background-color: #ffffff; }
img { border: 0; }
textarea { resize: none; }

input[type="button"], input[type="submit"] { cursor: pointer; }

.dtable { display: table; }
.dtcell { display: table-cell; }
.dtcptn { display: table-caption; }
.dtrow { display: table-row; }

span.cblock { display: inline-block; padding: 18px; border: 2px solid transparent; -webkit-box-shadow: inset 0px 0px 2px 2px rgba(200, 200, 200, 0.5); -moz-box-shadow: inset 0px 0px 2px 2px rgba(200, 200, 200, 0.5); box-shadow: inset 0px 0px 2px 2px rgba(200, 200, 200, 0.5); -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; }

#container { width: 100%; height: 100%; }
#content { height: 100%; }
#footer { text-align: center; }
#footer span { width: 100%; }
#header > div { margin: 0 auto; }
#logo { width: 100px; background-image: url('../images/logo.gif'); background-size: contain; background-repeat: no-repeat; background-clip: padding-box; }
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Pyromonk
  • 684
  • 1
  • 12
  • 27
  • 1
    So, the problem you will have is that `display:table` was designed to turn non table elements in to table 'acting' elements. And tables by their nature are not responsive. I understand why you don't want to us flextbox (seeing that you need to support IE9), however, what's your rational for not wanting to use floats? Float has been very well supported for many years. – LWilson May 29 '17 at 05:51
  • 1
    Here is a simple sample showing how you could do, switching between `display: table-cell` and `display: block` https://jsfiddle.net/28k17jha/1/ – Asons May 29 '17 at 06:18
  • @LWilson, that is a very good point, thank you. I will update my question's title. My only reason for not using floats is that I don't like them (they break the flow and sometimes require a clearfix). – Pyromonk May 29 '17 at 07:23
  • @LGSon, thank you, I love your solution! The only problem with it is the use of calc (and I realise I haven't mentioned it in my question, so it's my fault), as [that will prevent ~1.5% of users from seeing the correct layout](https://caniuse.com/#search=calc) (the ones with Android <4.4.4, not to mention people running older versions of Opera Mobile). – Pyromonk May 29 '17 at 07:26
  • Here is one without `calc()`, where I commented out the white space in the markup with a simple comment `` ... https://jsfiddle.net/28k17jha/2/ – Asons May 29 '17 at 09:07
  • Of course there is other ways than a comment to get rid of the inline block element white space: [how-to-remove-the-space-between-inline-block-elements](https://stackoverflow.com/questions/5078239/how-to-remove-the-space-between-inline-block-elements) – Asons May 29 '17 at 09:15
  • @LGSon, wow! I would have to set the logo to be the background of `id="logo"` for the desktop version and the background of the first span within `id="logo"` for mobile to make it exactly the same height as the second block, but that's a very minor setback. Your approach is very elegant and I like it *a lot*. Are there any problems with `width: auto;` that I should take into consideration? Do all browsers treat the instruction equally? – Pyromonk May 29 '17 at 09:17
  • @LGSon, I have come up with a solution using `position` and `::after`. What's the recommended way to go from there regarding answering this question? Should I present both the solution you have come up with and the one I have found or would you rather answer the question yourself? I would like to give credit where credit is due, and I am naturally very grateful to you for your help. You have approached the problem from an angle I have not considered at all. Thank you so much! – Pyromonk May 29 '17 at 09:19
  • 1
    I will of course post this as an answer if you find it useful, then, if your `position` / `pseudo` is a minor change you can either comment my answer or if it is a major change, add it as your own – Asons May 29 '17 at 09:21
  • try this: https://codepen.io/eirenaios/pen/LyoMPY?editors=1100 – Suresh Karia May 29 '17 at 09:28

2 Answers2

2

Here is a simple sample showing how you could do, switching between display: table-cell and display: block;

Note the comment <!-- --> in the markup, that get rid of the inline block element white space (here is more ways to do that: how-to-remove-the-space-between-inline-block-elements)

Fiddle demo

Stack snippet

.dtable {  display: table;  width: 100%; }
.dtcell {  display: table-cell;  padding: 10px; }
.dtcptn {  display: table-caption; }
.dtrow  {  display: table-row; }
.dtcell:first-child {
  width: 1px;
}
.dtcell:first-child span {
  display: inline-block;
  border: 1px solid;
  box-sizing: border-box;
}
.dtcell:first-child span:last-child {
  display: none;
}
.dtcell:last-child div {
  border: 1px solid;
  box-sizing: border-box;
}
.dtcell:last-child span {
  display: inline-block;
  width: 50%;
  border: 1px solid;
  box-sizing: border-box;
}
  
@media screen and (max-width: 600px) {
  .dtcell:first-child {
    width: 100%;
  }
  .dtcell:first-child span:last-child {
    display: inline-block;
  }
  .dtcell,
  .dtcell:last-child span {
    display: block;
    width: auto;
  }
  .dtcell:last-child div {
    display: none;
  }
}
<div id="container" class="dtable">
  <div id="header" class="dtrow">
    <div class="dtcell" id="logo">
      <span>logo</span>
      <span>hamburgermenu</span>
    </div>
    <div class="dtcell">
      <div>links</div>      
      <span>phone</span><!-- 
      --><span>social</span>
    </div>    
  </div>
</div>
Asons
  • 84,923
  • 12
  • 110
  • 165
  • Thank you very much once more, this is a very elegant solution that I most likely would not have thought of myself. I know about the HTML comment trick, but I am grateful to you for providing an explanation and a link to other ways of bypassing whitespace between inline/inline-block elements. I will post my own solution as soon as I get the time to, and I would appreciate it if you could tell me which one is best. Thank you! – Pyromonk May 29 '17 at 09:31
  • @Pyromonk I will comment on yours...make sure you drop me a note here below my answer so I get notified – Asons May 29 '17 at 09:32
  • I have posted my solution, but it turned out to have a downside yours didn't have. I would still like to hear your assessment to improve my CSS knowledge if I may. Thank you, good sir. – Pyromonk May 29 '17 at 11:36
  • Unfortunately, `.dtcell:first-child { width: 1px; }` screws up the footer (because it has a single cell in it). I will try to use an additional CSS table inside `id="header"` and, if that fails, run through a few other options to fix it. **Update**: that helped. Yay! Here's my final modification of your answer: https://jsfiddle.net/uw35786p/ – Pyromonk May 30 '17 at 01:40
  • I've made another update: https://jsfiddle.net/uw35786p/1/. In my current version of the website, I also have some `img` tags inside `a` tags where the word "Social" used to be. I was wondering whether there was a way to increase their size beyond font-size (16px) without using `transform`. – Pyromonk May 30 '17 at 04:08
  • @Pyromonk It might be, though as it is a completely different issue, post a new question with the requirements needed. – Asons May 30 '17 at 07:08
  • Question posted. – Pyromonk May 30 '17 at 08:35
  • @Pyromonk Posted an answer at your new question – Asons May 30 '17 at 09:02
1

Well, here is my answer using positioning and pseudo-elements.

@charset "utf-8";

* { box-sizing: border-box; }

a { display: inline-block; text-decoration: none; }
a:hover { text-decoration: underline; }
body, html { font-family: Helvetica, Arial, sans-serif; font-size: 16px; height: 100%; margin: 0; padding: 0; background-color: #ffffff; }
img { border: 0; }
textarea { resize: none; }

input[type="button"], input[type="submit"] { cursor: pointer; }

.dtable { display: table; }
.dtrow { display: table-row; }

span.cblock { display: inline-block; padding: 18px; border: 2px solid transparent; -webkit-box-shadow: inset 0px 0px 2px 2px rgba(200, 200, 200, 0.5); -moz-box-shadow: inset 0px 0px 2px 2px rgba(200, 200, 200, 0.5); box-shadow: inset 0px 0px 2px 2px rgba(200, 200, 200, 0.5); -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; }

#container { width: 100%; height: 100%; }
#contact, #social { width: 50%; }
#content { height: 100%; }
#footer { text-align: center; }
#footer span { width: 100%; }
#header { position: relative; text-align: center; }
#header > div { margin: 0 auto; }
#header > div div { display: inline-block; }
#header > div div:last-child { margin-left: 100px; }
#logo { width: 100px; position: absolute; top: 0; bottom: 0; background-image: url('logo.png'); background-size: contain; background-repeat: no-repeat; background-clip: padding-box; }
#menu { width: 100%; }
#menu::after { content: '\000A'; white-space: pre; }
#social { text-align: right; }

@media screen and (max-width: 768px) {

#contact, #social { width: 100%; }

/*  added these 2 rules  */
#social { text-align: center; }
#header > div div:last-child { margin-left: 0; }

}
<!DOCTYPE html>
<html>
<head lang="en-au">
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
    <div id="container" class="dtable">
        <div id="header" class="dtrow">
   <div>
    <div id="logo">&nbsp;</div><!--
    --><div>
     <span class="cblock" id="menu">
      <a href="#">Link #0</a>
      <a href="#">Link #1</a>
      <a href="#">Link #2</a>
      <a href="#">Link #3</a>
      <a href="#">Link #4</a>
      <a href="#">Link #5</a>
      <a href="#">Link #6</a>
      <a href="#">Link #7</a>
     </span><!--
     --><span class="cblock" id="contact">Phone</span><!--
     --><span class="cblock" id="social">Social</span>
    </div>
   </div>
        </div>
        <div id="content" class="dtrow">

        </div>
        <div id="footer" class="dtrow">
            <span class="cblock">&copy; The three musketeers, 2017. Say hello to the UFO.</span>
        </div>
    </div>
</body>
</html>

It's not as good as LGSon's, because on smaller screen sizes it leaves a margin between the left side of the screen and id="contact" and id="social", which I am not sure how to fix. It could be useful in certain scenarios, however.

Asons
  • 84,923
  • 12
  • 110
  • 165
Pyromonk
  • 684
  • 1
  • 12
  • 27
  • Will have a look later today...let you know – Asons May 29 '17 at 15:54
  • 1
    I updated your answer and added 2 rules in your media query, `#social { text-align: center; }` and `#header > div div:last-child { margin-left: 0; }`. The first center the text in _Social_ and the second remove the left margin. ... Still, I would go with the solution I posted, as it is cleaner and more easy to follow and maintain. – Asons May 29 '17 at 19:49
  • @LGSon, thank you! I will go with your solution and let you know if I encounter any problems on the way. – Pyromonk May 30 '17 at 00:08