@codeispoetry posted a new topic, subject "A simple text slider". It read:

   Hello there,
    
    slidesimple1323×109 382 KB
    
      
    The above was build using an owl carousel slider, but now I believe that conceiving 3rd party library is too taxing on the overall code. The simple JS can deliver such a thing.
    
    Please help me to get the mathematical logic clear I want to give an honest attempt to make one without seeing any example; that will be the first principal approach.
    
    15 items are there(Hypothetically, for example): At JS level what will happen that adjacent text boxes will be replaced till the end of the queue based on which arrow is triggered.

After which, @m3g4p0p added

    Hi @codeispoetry, one approach would be as follows:
    
      * Have a container with relative positioning and hidden overflow
      * Inside the container is the actual slider with absolute positioning, and a CSS transform transition as desired
      * Remember the index of the leftmost visible slide (starting with zero)
      * When clicking left or right: 
        * Increment or decrement that index
        * Add the widths of the elements up to the current index, and apply a CSS transform to the slider translating it accordingly along the x axis
    
    
    
    HTH `:-)`

Then @codeispoetry said

    image1305×702 66.7 KB
    [code] 
        <!DOCTYPE html>
        <html lang="en">
        <head>
        	<meta charset="UTF-8">
        	<meta name="viewport" content="width=device-width, initial-scale=1.0">
        	<title>Document</title>
        </head>
        <body>
        	<!DOCTYPE html>
        <html lang="en">
        <head>
        	<meta charset="UTF-8">
        	<meta name="viewport" content="width=device-width, initial-scale=1.0">
        	<title>Document</title>
        	<link rel="stylesheet" href="style.css">
        </head>
        <body>
        	<div class="wrapper">
        		<div class="container">
        			<div class="slider">
        				<div class="slide">01</div>
        				<div class="slide">02</div>
        				<div class="slide">03</div>
        				<div class="slide">04</div>
        				<div class="slide">05</div>
        				<div class="slide">06</div>
        				<div class="slide">07</div>
        				<div class="slide">08</div>
        				<div class="slide">09</div>
        				<div class="slide">10</div>
        			</div>
        		</div>
        		<div class="arrow">
        			<div class="left"><</div>
        			<div class="right">></div>
        		</div>
        	</div>
        </body>
        </html>
        
    [/code]
    
    CSS:
    [code] 
        @import url('https://fonts.googleapis.com/css?family=PT+Sans');
        @import url('https://fonts.googleapis.com/css?family=Lato:100,100i,300,300i,400,400i,700,700i,900,900i');
        html,
        body {
          margin  :0;
          padding :0;
          font-family: 'Lato', sans-serif;
          background-color: #F7F7F7;
        }
        * {
          box-sizing: border-box;
        }
        h1, h2, h3, h4, h5, h6, ul, span, p {margin: 0; padding: 0;}
        p {
        	font-size: 1.2rem;
          line-height: 1.551;
        }
        h1{
        	font-size: 5rem;
        	font-weight: normal;
        	color: #4A4949;
        }
        h3 {
          font-size: 3rem;
          font-weight: normal;
          color: #4A4949;
        }
        h4 {
          font-size: 2.6rem;
          font-weight: normal;
          color: #4A4949;
        }
        h6 {
          font-size: 1.5rem;
        }
        
        
        ul {
          list-style-type: none;
        }
        
        
        .wrapper {
          display: flex;
          max-width: 1200px;
          margin: auto;
        }
        .container {
          position: relative;
          
        }
        .slider {
          display: flex;
          justify-content: space-between;
          border:1px solid #000000;
          position: absolute;
          overflow: hidden;
        }
        .slide {
          width: 30%;
          min-width: 30%;
          padding: 10px 20px;
          border:2px solid #DCDCDC;
          margin:20px;
        }
        .arrow {
          margin: auto;
          margin-top: 150px;
        }
        .right, .left {
          padding: 5px 10px;
          border: 2px solid #DCDCDC;
          margin: 10px;
          font-size: 1.2rem;
          font-weight: bold;
          color: #000000;
        }
        
    [/code]
    
    Hi there everyone,  
    I am unable to position the slider `div` in the middle.

So @codeispoetry replied

    m3g4p0p:
    
    >   * Remember the index of the leftmost visible slide (starting with zero)
    > 
    
    [code] 
        const slide = document.getElementsByClassName("slide");
        
    [/code]
    
    The syntax is not completely visible, but I think we have to access:
    
    `slide[i]`
    
    based on the left and right arrow clicked `i` should increase or decrease.
    
    The remaining will be taken care of by CSS because based on media query and screen resolution it is the css, which will decide how many items to show.
    
    JS task will be to change the first element in the JS array/nodes.
    
    Furthermore, not yet tested on live, but this is what I can visualize:
    [code] 
        	const leftSlide = document.querySelector(".left");
        	const rightSlide = document.querySelector(".right");
        
        	leftSlide.addEventListener("click", IncreaseZero);
        	function IncreaseZero() {
        		for (var i = 0; i < slide.length; i++) {
        			i = i;
        		        slide[0] = slide[i] ;
        		}
        	}
        
        	rightSlide.addEventListener("click", DecreaseZero);
        	function DecreaseZero() {
        		for (var i = 0; i < slide.length; i++) {
        			i = i;
           		       slide[0] = slide[i] ;
        		}
        	}
        
    [/code]

So @codeispoetry replied

    codeispoetry:
    
    > 
    [code]
    >     const slide = document.getElementsByClassName("slide");
    >     
    [/code]
    
    Finally I refined the code, but still could not put it in synchronization with the actual HTML so that first element in slide should get modified and sliding happens→
    [code] 
        	<script>
        		const slide = document.getElementsByClassName("slide");
        		const leftSlide = document.querySelector(".left");
        		const rightSlide = document.querySelector(".right");
        
        		leftSlide.addEventListener("click", IncreaseZero);
        		function IncreaseZero() {
        			for (var i = 0; i < slide.length; i++) {				
        			  slide[0] = slide[i];
        			  i = i++;
        			}
        		}
        
        		rightSlide.addEventListener("click", DecreaseZero);
        		function DecreaseZero() {
        			for (var i = 0; i < slide.length; i++) {				
        			  slide[0] = slide[i];
        			  i = i--;
        			}
        		}
        	</script>
        
    [/code]
    
    I think we have to assign an extra class first to first element and based on node inccrement/decrement we have to change that class/toggling.
    
    image718×479 60.2 KB

@m3g4p0p replied

    codeispoetry:
    
    > so that first element in slide should get modified and sliding happens
    
    Well the idea is not to modify any `.slide` at all, but apply a transform to the `.slider` – add the widths of the slides up to the current index, and translate the slider horizontally so that the previous slides are overflowing to the left (and thus hidden).
    
    https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements
    
    https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/translate()

After which, @Archibald added

    codeispoetry:
    
    > The remaining will be taken care of by CSS because based on media query and screen resolution it is the css, which will decide how many items to show.
    
    I would use JavaScript to make this responsive: including hiding the buttons if there is nothing hidden.
    
    Anyone disagree?

So @codeispoetry replied

    Archibald:
    
    > I would use JavaScript to make this responsive: including hiding the buttons if there is nothing hidden. Anyone disagree?
    
    My intention was also to use JS. Can my code be refined?

After which, @Archibald added

    codeispoetry:
    
    > I want to give an honest attempt to make one without seeing any example
    
    codeispoetry:
    
    > Can my code be refined?
    
    If you wish I can show you code I have that works (but it's not responsive as it stands). It is an alternative approach but I'm not saying it is more refined

So @codeispoetry replied

    Archibald:
    
    > If you wish I can show you code I have that works (but it's not responsive as it stands). It is an alternative approach but I'm not saying it is more refined 
    
    Sure, Thanks!

To which @Archibald replied

    OK, here is my code that I wrote before the first reply to this thread.
    
    My terminology is somewhat different . . . .
    
      * The whole thing has class “slider”;
      * Within the slider is a “view” (red border) and an element for the buttons (“buttons”);
      * Within the view is a “container” wider than the view, with its overflow hidden;
      * Within the “container” are a number of text boxes with class “box”.
    
    
    
    I have used negative values of CSS `margin-left` to move the container instead of using CSS` transform`.
    
    Note the “-400” in the JavaScript limits the shifting of the container. That would need to be changed by calculation if there are more text boxes or the width of the “view” is changed. At present it allows no more than two text boxes (200 pixels wide) to disappear off to the left.
    
    With sliders like this there is always a question as to which way the arrows should point.
    
    Standby for comments on my code from this forum's coding puritans

After which, @rpg_digital added

    Archibald:
    
    > I have used negative values of CSS `margin-left` to move the container instead of using CSS ` transform` .
    
    Transform is more performant and utilises the GPU. I think you'll find margin-left is a more expensive operation and triggers repaints (I had a list somewhere of all the properties that trigger re-flows)
    
    You can kind of see it when you scroll, it's a bit jittery.
    
    I don't have the time right now, but here is one article on the topic  
    https://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/

So @system replied

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


{'source': 'discourse', 'url': 'https://www.sitepoint.com/community/t/a-simple-text-slider/367315', 'title': 'A simple text slider', 'views': 3387, 'has_accepted_answer': False, 'word_count': 1409, 'like_count': 10, 'reply_count': 7, 'participant_count': 4, 'posts': 13, 'tags': '', 'author': '@codeispoetry', 'participants': '@codeispoetry, @m3g4p0p, @Archibald, @rpg_digital, @system', 'image_url': ['https://aws1.discourse-cdn.com/sitepoint/optimized/3X/0/8/08297fb2d7a81682d8707bb8ac88d36075aef138_2_1024x84.gif'], 'created_at': '2021-04-27T16:20:59.603Z', 'last_posted_at': '2021-07-28T17:31:56.339Z'}