1

I'm trying to create a text changing animation in which four words cycle through a fixed underlined space. I've gotten the text changing piece done using a simple js script, but I'm having trouble positioning the underline. I've tried using hr to no avail and I've gotten close using an inline svg, however I can't figure out how to position the SVG so that it's underneath the text. I've tried adjusting the position in CSS using the SVG id and I've also tried adjusting the position of the SVG directly in the svg code.

var text = ["Repurposed", "Remnant  ", "Scrap", "Upcycled  "];
var counter = 0;
var elem = $("#greeting");
setInterval(change, 3000);
function change() {
    elem.fadeOut(function(){
        elem.html(text[counter]);
        counter++;
        if(counter >= text.length) { counter = 0; }
        elem.fadeIn();
    });
}
#layer_1 {
    display: block;
    padding-bottom: 20%;
    padding-top: 0;
    text-align: right;
    margin-left: 40%;
    margin-top: 0;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
    <div class="col-6">
        <div class="text-change" id='greeting'>Upcycled</div>
        <div class="liner">
    <svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400.52 4.84"><defs><style>.cls-1{fill:none;stroke:#fff;stroke-miterlimit:10;stroke-width:3px; padding-left: 25%;}</style></defs><line class="cls-1" y1="2.84" x2="200.51" y2="2"/></svg>
</div>
    </div>
    <div class="col-6">
        <div class="text-change-right">Materials</div>
    </div>
</div>
Waltermelon
  • 11
  • 1
  • 3
  • 1
    Does giving that element the style `text-decoration: underline;` not work for you? – Pointy May 31 '21 at 17:37
  • No because I'd like the underline to remain fixed while the text changes. – Waltermelon May 31 '21 at 17:42
  • Define *"remain fixed"* in more specific terms. Would padding the string length with extra spaces help? Not clear in demo what svg is doing either – charlietfl May 31 '21 at 17:43
  • Hmm yeah maybe padding the string length would help. By remain fixed I mean I simply want a solid line on which the text changes so that it has a fill in the blank type of effect. – Waltermelon May 31 '21 at 17:48
  • 1
    You could put the text in a `
    ` styled as `display: inline-block`, give it a fixed witdh, center the text (if you want), and then give the `
    ` a bottom border.
    – Pointy May 31 '21 at 18:02
  • Thanks for the suggestion, this worked. – Waltermelon May 31 '21 at 19:36

2 Answers2

1

Probably not what you are after... but when I see jQuery, I try to write something without

var titles = ["Repurposed", "Remnant", "Scrap", "Upcycled"];
var div = document.querySelector(".greeting div:first-child");
setInterval(change, 200);

function change() {
  titles.unshift(div.innerHTML = titles.pop());// pop last title, insert at front
}
.greeting {
  width: 50vw;
  font:30px Arial;
}

.greeting div {
  background: pink;
  text-align: center;
}

.greeting div:first-child {
  border-bottom: 1px solid green;
}
<div class="greeting">
  <div>Upcycled</div>
  <div>Materials</div>
</div>
Danny '365CSI' Engelman
  • 16,526
  • 2
  • 32
  • 49
  • Thanks for writing this out, it wasn't exactly what I was looking for, but it was helpful to see it done a different way. – Waltermelon May 31 '21 at 19:35
0

Here's a method using real underlines.

The underline is extended by using the ::after pseudo-element to add non-breaking whitespace after the text. To make the underline look fixed-width, we turn off text wrapping, and ensure any extra spaces are hidden using overflow: hidden.

You just need to make sure you include enough \0000a0 (non-breaking space) characters to ensure the text overflows the column. If that seems a bit ugly, you could perhaps try stretching the spaces horizontally instead using one of the techniques in this question.

var text = ["Repurposed", "Remnant  ", "Scrap", "Upcycled  "];
var counter = 0;
var elem = $("#greeting");
setInterval(change, 3000);
function change() {
    elem.fadeOut(function(){
        elem.html(text[counter]);
        counter++;
        if(counter >= text.length) { counter = 0; }
        elem.fadeIn();
    });
}
body {
  font-size: 36px;
}

.row {
  display: flex;
}
.col-6 {
  width: 300px;
}


.text-change-container {
  overflow: hidden;
}

.text-change {
  display: inline;
  text-decoration: underline;
  white-space: nowrap;
}

.text-change::after {
  display: inline;
  content: '\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0\0000a0';
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
    <div class="col-6 text-change-container">
        <div class="text-change" id='greeting'>Upcycled</div>
    </div>
    <div class="col-6">
        <div class="text-change-right">Materials</div>
    </div>
</div>
Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181