2

I built an interactive bar chart as part of a job application. They since came back to me with overall positive feedback and an invite to a final stage interview. However, I would really like to try and address the feedback they gave me on my submitted code.

Codepen Link

<body>
  <div class="container">
    <h1>CSS Project</h1>
    <h2>Choose your level of risk</h2>
    <p id="description">Read the definitions and choose the risk level that best suits you.</p>
    <h3>Potential Return</h3>
    <div id="graph-wrapper">
      <div id="left-float">
        <p>Low Risk</p>
        <p>Lower potential return</p>
      </div>
      <div id="right-float">
        <p>High Risk</p>
        <p>Higher potential return</p>
      </div>
      <input type="checkbox" style="display: none" id="defensive-checkbox">
      <label id="defensive-label" for="defensive-checkbox">Defensive</label>
      <input type="checkbox" style="display: none" id="cautious-checkbox">
      <label id="cautious-label" for="cautious-checkbox">Cautious</label>
      <input type="checkbox" style="display: none" id="balanced-checkbox">
      <label id="balanced-label" for="balanced-checkbox">Balanced</label>
      <input type="checkbox" style="display: none" id="growth-checkbox">
      <label id="growth-label" for="growth-checkbox">Captial Growth</label>
      <input type="checkbox" style="display: none" id="aggressive-checkbox">
      <label id="aggressive-label" for="aggressive-checkbox">Aggressive</label>
      <div id="defensive-bar" class="bar"></div>
      <div id="cautious-bar" class="bar"></div>
      <div id="balanced-bar" class="bar"></div>
      <div id="growth-bar" class="bar"></div>
      <div id="aggressive-bar" class="bar"></div>
      <div id="defensive-info" class="info">
        <h4>Defensive</h4>
        <p>The Defensive investor may be very sensitive to short-term losses. A Defensive investor's potential aversion to short-term losses could compel them to sell their investment and hold a zero risk investment instead if losses occur.</p>
        <p>Defensive investors would possibly accept lower long-term return in exchange for smaller and less frequent changes in portfolio value. Analysing the risk-return choices available, a Defensive investor is usually willing to accept a lower return
          in order to assure the safety of his or her investment.</p>
      </div>
      <div id="cautious-info" class="info">
        <h4>Cautious</h4>
        <p>The Cautious investor may be sensitive to short-term losses. A Cautious investor's potential aversion to losses could compel them to shift into a more stable investment if significant short-term losses occur.</p>
        <p>Analysing the risk-return choices available, a Cautious investor is usually willing to accept somewhat lower returns in order to assure greater safety of his or her investment.</p>
      </div>
      <div id="balanced-info" class="info">
        <h4>Balanced</h4>
        <p>The Balanced investor may be somewhat concerned with short-term losses and may shift to a more stable option in the event of significant losses. The safeties of investment and return are typically of equal importance to the Balanced investor.</p>
      </div>
      <div id="growth-info" class="info">
        <h4>Captial Growth</h4>
        <p>The Captial Growth investor may be willing to accept high risk and chance of loss in order to achieve higher returns on his or her investment. Significant losses over an extended period may prompt the Captal Growth Investor to shift to a less
          risky investment.</p>
      </div>
      <div id="aggressive-info" class="info">
        <h4>Aggressive</h4>
        <p>The Aggressive investor usually aims to maxmise long-term expected returns rather than minimise possible short-term losses. An Aggressive investor values high returns relatively more and can tolerate both large and frequent fluctuations through
          time in portfolio value in exchange for a higher return over the long term.</p>
      </div>
    </div>
  </div>
</body>

Here is the CSS:

$purple: #7f3f98;
$dark-purple: #1D1060;
$light-purple: #a576b1;
$green: #7cc14c;
$white: #ffffff;
$black: #000000;
$alt-purple: #592a6b;

body {
    background-color: $purple;
    color: $white;
    font-family: 'Open Sans', sans-serif;
    box-sizing: content-box;
    width: 100%;
    h1 {
        margin: 1em;
        text-align: center;
    }
    h2, h3 {
        margin-bottom: 1em;
    }
    #description {
        margin-bottom: 2em;
    }
}

body {
  animation: pulse 5s infinite;
}

@keyframes pulse {
  0% {
    background-color: $purple;
  }
  50% {
    background-color: $alt-purple;
  }
  100% {
    background-color: $purple;
  }
}

#graph-wrapper {
    width: 100%;
    position: relative;
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    grid-template-rows: 300px auto 1fr;
    grid-gap: 10px;
}

#left-float, #right-float {
    position: absolute;
    top: 150px;
    p {
        margin-bottom: 0;
    }
}
#left-float {
    left: 0.5em;
}
#right-float {
    text-align: right;
    right: 0.5em;
}


// Bar Styles
.bar {
    grid-row: 1 / 2;
    align-self: end;
    width: 100%;
    background-color: $light-purple;
    border-top: 5px solid $light-purple;
    border-radius: 5px;
}

#defensive-bar {
    grid-column: 1 / span 1; 
    height: 15px;
}

#cautious-bar {
    grid-column: 2 / span 1;
    height: 50px;
}

#balanced-bar {
    grid-column: 3 / span 1;
    height: 80px;
}

#growth-bar {
    grid-column: 4 / span 1;
    height: 140px;
}

#aggressive-bar {
    grid-column: 5 / span 1;
    height: 200px;
}


// Button Styles
label {
    grid-row: 2 / 3;
    display: inline-block;
    text-align: center;
    border: none;
    border-radius: 5px;
    padding: 0.5em;
    background-color: $dark-purple;
    color: $white;
    cursor: pointer;
    vertical-align: middle;
    -webkit-transform: perspective(1px) translateZ(0);
    transform: perspective(1px) translateZ(0);
    box-shadow: 0 0 1px transparent;
    -webkit-transition-duration: 0.3s;
    transition-duration: 0.3s;
    -webkit-transition-property: box-shadow;
    transition-property: box-shadow;
}

#defensive-checkbox:checked ~ #defensive-label {
    box-shadow: 0 10px 10px -10px rgba(0, 0, 0, 0.5);
}
#defensive-checkbox:checked ~ #defensive-bar {
    box-shadow: 0 10px 10px -10px rgba(0, 0, 0, 0.5);
}
#cautious-checkbox:checked ~ #cautious-label {
    box-shadow: 0 10px 10px -10px rgba(0, 0, 0, 0.5);
}
#cautious-checkbox:checked ~ #cautious-bar {
    box-shadow: 0 10px 10px -10px rgba(0, 0, 0, 0.5);
}
#balanced-checkbox:checked ~ #balanced-label {
    box-shadow: 0 10px 10px -10px rgba(0, 0, 0, 0.5);
}
#balanced-checkbox:checked ~ #balanced-bar {
    box-shadow: 0 10px 10px -10px rgba(0, 0, 0, 0.5);
}
#growth-checkbox:checked ~ #growth-label {
    box-shadow: 0 10px 10px -10px rgba(0, 0, 0, 0.5);
}
#growth-checkbox:checked ~ #growth-bar {
    box-shadow: 0 10px 10px -10px rgba(0, 0, 0, 0.5);
}
#aggressive-checkbox:checked ~ #aggressive-label {
    box-shadow: 0 10px 10px -10px rgba(0, 0, 0, 0.5);
}
#aggressive-checkbox:checked ~ #aggressive-bar {
    box-shadow: 0 10px 10px -10px rgba(0, 0, 0, 0.5);
}

#defensive-label {
    grid-column: 1 / span 1; 
}

#cautious-label {
    grid-column: 2 / span 1; 
}

#balanced-label {
    grid-column: 3 / span 1; 
}

#growth-label {
    grid-column: 4 / span 1; 
}

#aggressive-label {
    grid-column: 5 / span 1; 
}


// Information Section
.info {
    display: none;
    grid-column: 1 / span 5;
    grid-row: 3 / 4;
    background-color: $white;
    color: $black;
    position: relative;
    padding: 2em 1.5em;
    border: 4px solid $white;
    border-radius: 10px;
    margin-top: 50px;
    margin-bottom: 50px;
    box-shadow: 0 10px 10px -10px rgba(0, 0, 0, 0.5);
    h4 {
        color: $purple;
        margin-bottom: 1em;
    }
}

.info:after, .info:before {
    bottom: 100%;
    border: solid transparent;
    content: " ";
    height: 0;
    width: 0;
    position: absolute;
    pointer-events: none;
}

.info:after {
    border-color: rgba(255, 255, 255, 0);
    border-bottom-color: $white;
    border-width: 30px;
    margin-left: -30px;
}
.info:before {
    border-color: rgba(255, 255, 255, 0);
    border-bottom-color: $white;
    border-width: 36px;
    margin-left: -36px;
}

#defensive-info:after, #defensive-info:before {
    left: 10%;
}

#cautious-info:after, #cautious-info:before {
    left: 30%;
}

#balanced-info:after, #balanced-info:before {
    left: 50%;
}

#growth-info:after, #growth-info:before {
    left: 70%;
}

#aggressive-info:after, #aggressive-info:before {
    left: 90%;
}


// Defensive Active
#defensive-checkbox:checked ~ #defensive-info {
    display: block;
}
#defensive-checkbox:checked ~ #cautious-info,
#defensive-checkbox:checked ~ #balanced-info,
#defensive-checkbox:checked ~ #growth-info,
#defensive-checkbox:checked ~ #aggressive-info {
    display: none;
}
#defensive-checkbox:checked ~ #defensive-label {
    background-color: $green;
}
#defensive-checkbox:checked ~ div#defensive-bar.bar {
    border-color: $white;
}


// Cautious Active
#cautious-checkbox:checked ~ #cautious-info {
    display: block;
}
#cautious-checkbox:checked ~ #defensive-info,
#cautious-checkbox:checked ~ #balanced-info,
#cautious-checkbox:checked ~ #growth-info,
#cautious-checkbox:checked ~ #aggressive-info {
    display: none;
}
#cautious-checkbox:checked ~ #cautious-label {
    background-color: $green;
}
#cautious-checkbox:checked ~ div#defensive-bar.bar,
#cautious-checkbox:checked ~ div#cautious-bar.bar {
    border-color: $white;
}


// Balanced Active
#balanced-checkbox:checked ~ #balanced-info {
    display: block;
}
#balanced-checkbox:checked ~ #defensive-info,
#balanced-checkbox:checked ~ #cautious-info,
#balanced-checkbox:checked ~ #growth-info,
#balanced-checkbox:checked ~ #aggressive-info {
    display: none;
}
#balanced-checkbox:checked ~ #balanced-label {
    background-color: $green;
}
#balanced-checkbox:checked ~ div#defensive-bar.bar,
#balanced-checkbox:checked ~ div#cautious-bar.bar,
#balanced-checkbox:checked ~ div#balanced-bar.bar {
    border-color: $white;
}


// Growth Active
#growth-checkbox:checked ~ #growth-info {
    display: block;
}
#growth-checkbox:checked ~ #defensive-info,  
#growth-checkbox:checked ~ #cautious-info, 
#growth-checkbox:checked ~ #balanced-info,
#growth-checkbox:checked ~ #aggressive-info{
    display: none;
}
#growth-checkbox:checked ~ #growth-label {
    background-color: $green;
}
#growth-checkbox:checked ~ div#defensive-bar.bar,
#growth-checkbox:checked ~ div#cautious-bar.bar,
#growth-checkbox:checked ~ div#balanced-bar.bar,
#growth-checkbox:checked ~ div#growth-bar.bar {
    border-color: $white;
}


// Aggressive Active
#aggressive-checkbox:checked ~ #aggressive-info {
    display: block;
}
#aggressive-checkbox:checked ~ #defensive-info,
#aggressive-checkbox:checked ~ #cautious-info,
#aggressive-checkbox:checked ~ #balanced-info,  
#aggressive-checkbox:checked ~ #growth-info {
    display: none;
}
#aggressive-checkbox:checked ~ #aggressive-label {
    background-color: $green;
}
#aggressive-checkbox:checked ~ div#defensive-bar.bar,
#aggressive-checkbox:checked ~ div#cautious-bar.bar,
#aggressive-checkbox:checked ~ div#balanced-bar.bar,
#aggressive-checkbox:checked ~ div#growth-bar.bar,
#aggressive-checkbox:checked ~ div#aggressive-bar.bar {
    border-color: $white;
}

Basically they mentioned a couple of points:

  1. The site is broken in Internet Explorer, browser testing is an essential part of the front end development process.

  2. The button active state functionality is inconsistent.

The first point is kinda expected as it was built with CSS Grid which isn't supported by IE. So I was going to look at creating some images to display instead in IE.

The second however I am a little stuck on. What I think they are looking for is to have previous buttons highlighted when clicking on subsequent ones. For instance if I click on button 4, buttons 1, 2, 3 and 4 will appear green. Then if I were to click on button 2, it would only highlight buttons 1 and 2. The issue I am running into is that there does not seem to be a way to select previous siblings with CSS.

I am at a stage where I am thinking whether I should maybe look at different ways of building this that might address their points.

1 Answers1

2

Previous siblings or parent selectors are not a thing in CSS.

I agree that the behaviour is inconsistent, but all you need to do to fix it is use radio buttons instead of check boxes and hack away to position the buttons before the affected elements on the HTML flow, then use label tags to operate them from below on the visual output, and use the ~ general sibling combinator to affect the correct elements.

I've just made a pen to showcase a basic example of what you need, the whole trick is on the bottom lines

#rb1:checked ~ #div1{
  background:lime;
}

#rb2:checked ~ #div1, #rb2:checked ~ #div2 {
  background:lime;
}

section{
  display:flex;
}

div{
  background-color:grey;
  margin:1rem;
  width:100px; height:100px;
}

label{
  background-color:lightgrey;
  margin:1rem;
  width:100px;
  text-align:center;
  box-sizing:border-box;
  padding:1rem;
  cursor:pointer;
}

#rb1, #rb2, #rb3, #rb4, #rb5{
  display:none;
}

#rb1:checked ~ #div1{
  background:lime;
}

#rb2:checked ~ #div1, #rb2:checked ~ #div2 {
  background:lime;
}

#rb3:checked ~ #div1, #rb3:checked ~ #div2, #rb3:checked ~ #div3 {
  background:lime;
}

#rb4:checked ~ #div1, #rb4:checked ~ #div2, #rb4:checked ~ #div3, #rb4:checked ~ #div4{
  background:lime;
}

#rb5:checked ~ #div1, #rb5:checked ~ #div2, #rb5:checked ~ #div3, #rb5:checked ~ #div4, #rb5:checked ~ #div5{
  background:lime;
}
<section>
  <input type="radio" name="rb" id="rb1">
  <input type="radio" name="rb" id="rb2">
  <input type="radio" name="rb" id="rb3">
  <input type="radio" name="rb" id="rb4">
  <input type="radio" name="rb" id="rb5">
  <div id="div1"> </div>
  <div id="div2"> </div>
  <div id="div3"> </div>
  <div id="div4"> </div>
  <div id="div5"> </div>
</section>

<section>
  <label id="lb1" for="rb1">First</label>
  <label for="rb2">Second</label>
  <label for="rb3">Third</label>
  <label for="rb4">Fourth</label>
  <label for="rb5">Fifth</label>
</section>

Of course, refactoring the code as SASS for loops will make the code much DRYer, and obviously "best practices" are not there at all.. just wanted to give you a quick guide. Might refactor the code later as I think it's a good trick to have in my showcase :)

As for the "1.The site is broken in Internet Explorer, browser testing is an essential part of the front end development process", they are totally right, but another essential part of front end development is telling the developer about the desired browser support scope.

Facundo Corradini
  • 3,825
  • 9
  • 24
  • Thanks for the help, this looks great. I will work it in and update the pen :) –  Jan 07 '18 at 16:19
  • @SuperEpicMan glad to help. Let us know of further progress :) – Facundo Corradini Jan 07 '18 at 16:26
  • Radio buttons worked really well, at first I wasn't able to unselect them, but I hadn't realised I needed to give them the same name. I have updated the pen, but I might see about refactoring my SASS since its huge. I might also see what I can do about IE, thinking of just putting some images in to display when in IE. Thanks for your help :) –  Jan 07 '18 at 17:00
  • wow that was fast! For IE you can think of a fallback for your grid. Maybe use your grid declarations in a @supports query, and set a fallback to inline-block, floats or even display:table-cell above the cascade flow to serve for progressive enhancement. The ~ selector is supported from IE7, so shouldn't be a problem. But again, it would be good to know the desired browser support scope. It's not the same thing trying to make it work for IE11, than IE8... than damn IE6. – Facundo Corradini Jan 07 '18 at 17:14
  • 1
    I have updated the pen to include some support for older browsers, can't test it properly since I don't have a windows machine, but loading it on an Edge simulator seems to look much better now. I might leave it for now and see what it looks like at work, but thanks for your suggestions, I might see about incorporating them in tomorrow. –  Jan 07 '18 at 17:55