skip to Main Content

I have a timeline. The name written on each input should be deleted from the top and written flat below when the input becomes active. It is not in the correct position at the moment. I need to fix this location. I also tried to do this by adding data-info but I guess this is not the right approach. Is it possible to provide this operation from the text written in span ?
I have added the codes and photos. I will be glad if you help.

body {
  font-family: 'Open Sans', sans-serif !important;
}

.timetable-container {
  margin: auto;
  position: relative;
  height: 100vh;
  width: 56.25vh;
  font-size: 0.5208vh;
  display: flex;
  flex-direction: column;
}

.flex-parent {
  margin-top: 2em;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
}

.input-flex-container {
  display: flex;
  justify-content: space-around;
  align-items: center;
  width: 100%;
  height: 30em;
  position: relative;
  z-index: 0;
}

.input-line {
  width: 3.5em;
  height: 3.5em;
  background-color: #7dad4c;
  position: relative;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.5em;
}

.input-line h2 {
  color: white;
  font-weight: bolder;
  display: inline-block;
}

.input {
  width: 1.3em;
  height: 1.3em;
  position: relative;
  border-radius: 50%;
  border: 2.5px solid #7dad4c; 
  background-color: white;
}

.input::before,
.input::after {
  content: '';
  display: block;
  position: absolute;
  z-index: -1;
  top: 50%;
  transform: translateY(-50%);
  background-color: #7dad4c;
  width: 10em;
  height: 0.7em; 
  max-width: 50px;
}

.input-line::after {
  content: '';
  display: block;
  position: absolute;
  z-index: -1;
  top: 50%;
  transform: translateY(-50%);
  background-color: #7dad4c;
  width: 2em;
  height: 0.2em;
  max-width: 50px;
}

.input::before {
  left: calc(-4vw + 12.5px);
}

.input::after {
  right: calc(-4vw + 12.5px);
}

.input-line::after {
  right: calc(-4vw + 12.5px);
}

.input.active {
  background-color: #7dad4c;
  width: 1.5em;
  height: 1.5em;
}

.input span {
  width: 1px;
  height: 1px;
  position: absolute;
  top: -300%;
  left: 30%;
  /* transform: translate(-50%, -50%); */
  /* visibility: hidden; */
  display: inline-block;
  transform: rotate(-45deg);
  font-size: 2em;
}

.input span::after,
.input span::before {
  position: absolute;
  left: 50%;
}

.input span::after {
  content: attr(data-info); 
  color: #7dad4c;
  font-weight: bold;
  transform: translateX(-50%);
  font-size: 1.8em;
  transform: rotate(45deg);
}

.input span::before {
  top: -65px;
  width: 70px;
  transform: translateX(-5px) rotateZ(-45deg);
  font-size: 1.8em;
  text-indent: -10px;
}
 <div class="timetable-container">
    <div class="section-timeline" style="height: 15%">
      <div class="flex-parent">
        <div class="input-flex-container">
          <div class="input-line">
            <h2>U1</h2>
          </div>
          <div class="input">
            <span>Uhlandstr.</span>
          </div>
          <div class="input">
            <span>Kurfurstendamm</span>
          </div>
          <div class="input active">
            <span data-info="Wittenbergplatz">Wittenbergplatz</span>
          </div>
          <div class="input">
            <span >Nollendorfplatz</span>
          </div>
        </div>
      </div>
    </div>
   </div>

Current:
enter image description here

must be:
enter image description here

2

Answers


  1. i would suggest you just make them in the same div and then have them seperate elements. i hope this helped

    Login or Signup to reply.
  2. The "must be" image shows that a marker only ever has one label:

    We can apply different styles to <span> depending on whether its "input" has the active class, to change its position and its text’s style. Example:

    /*Ignore; for toggling behaviour*/
    document.querySelector("input").addEventListener("input", evt => {
      document.querySelector(".input").classList.toggle("active", evt.target.checked);
    });
    .input span {
      position: absolute;
      display: inline-block;
    }
    
    .input:not(.active) span {
      bottom: 100%;
      left: 30%;
      transform-origin: top left;
      transform: rotate(-45deg);
    }
    .input.active span {
      top: 150%;
      left: 50%;
      transform: translateX(-50%);
      color: #7dad4c;
      font-weight: bold;
    }
    
    /*Ignore; representing your code*/
    body {font-family:sans-serif}
    
    .input {
      position: relative;
      border: .2rem solid #7dad4c;
      border-radius: 50%;
      width: 1rem;
      height: 1rem;
      background-color: white;
    }
    
    .input::before, .input::after {
      content: "";
      position: absolute;
      top: 50%;
      right: 100%;
      width: 2rem;
      height: .2rem;
      display: inline-block;
      transform: translateY(-50%);
      background-color: #7dad4c;
    }
    .input::after {left:100%}
    
    .input.active {
      width: 1.2rem;
      height: 1.2rem;
      background-color: #7dad4c;
    }
    
    /*Ignore; presentational*/
    #wrapper {
      height: 10rem;
      display: grid;
      place-items: center;
    }
    <label><input type=checkbox> Has class <code>active</code>?</label>
    <div id="wrapper">
    
      <div class="input">
        <span>Wittenbergplatz</span>
      </div>
      
    </div>

    The lower label is actual content on the timeline; it should be in your HTML (or rather: in the DOM), and not be made with some CSS tricks.

    So, if you want both labels on top and below, you should use distinct elements. You could position the extra element below the current marker with CSS Grid. Example:

    .input-wrapper {
      margin-top: 6rem;
      margin-left: 2rem;
      width: fit-content;
      display: grid;
      align-items: center;
      grid-auto-flow: column;
      gap: 0 4rem;
    }
    
    .input {grid-row:1}
    
    .highlight {
      grid-row: 2;
      position: relative;
    }
    .highlight span {
      position: absolute;
      top: .6rem;
      left: 50%;
      color: #7dad4c;
      font-weight: bold;
      white-space: nowrap;
      transform: translate(-50%);
    }
    
    /*Ignore; representing your code*/
    body {font-family:sans-serif}
    
    .input {
      position: relative;
      margin: -.2rem;
      border: .2rem solid #7dad4c;
      border-radius: 50%;
      width: .8rem;
      height: .8rem;
    }
    .input.active {
      width: 1.2rem;
      height: 1.2rem;
      background-color: #7dad4c;
    }
    
    .input::before, .input::after {
      content: "";
      position: absolute;
      top: 50%;
      right: 100%;
      width: 2rem;
      height: .2rem;
      background-color: #7dad4c;
      transform: translateY(-50%);
    }
    .input::before {left:100%}
    
    .input span {
      position: absolute;
      bottom: 150%;
      left: 100%;
      white-space: nowrap;
      transform-origin: bottom left;
      transform: rotate(-45deg);
    }
    <div class="input-wrapper">
      <div class="input">
        <span>Some station</span>
      </div>
      <div class="input active">
        <span aria-current=location>Another station</span>
      </div>
      <div class="input">
        <span>A third station</span>
      </div>
      
      <!--
        The active input's index (for grid-column)
        and content can be found via JS.
      -->
      <div class="highlight" style="grid-column:2">
        <span aria-hidden=true>Another station</span>
      </div>
    </div>

    The attr() CSS function only works on attributes; you cannot "copy" an element’s content with it (or any other function) in CSS.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search