# P5 Layout Questions

**URL:** <https://discourse.processing.org/t/p5-layout-questions/30453>\
**Category:** Libraries\
**Created:** [June 2, 2021, 7:45pm UTC](https://discourse.processing.org/t/p5-layout-questions/30453 "2021-06-02T19:45:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![karenmani](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/karenmani/32/13359_2.png) [@karenmani](https://discourse.processing.org/u/karenmani)\
**Post date:** [June 2, 2021, 7:45pm UTC](https://discourse.processing.org/t/p5-layout-questions/30453/1 "2021-06-02T19:45:17Z")

</div>

Hi,

I’m working with a p5 video player and I’m not too familiar with CSS. I have a layout that’s consistent on Chrome and Firefox, but for some reason, it gets messed up in Safari and does not line up the way my button and video are set. Additionally, the slider gets placed elsewhere. I tried creating a slider in html and using `document.getElementById.value` to use the slider for panning, but that doesn’t work so I stuck to creating it in p5.js itself. Can someone help me figure that out? Pasting my code below.

```auto
//SKETCH.JS:
let cnv;
let video_file;
let button;
let playButton = document.getElementById("play-button");
let playing = false;
let panValue;// = document.getElementById("sliderRange").value;
let theresa_audio; //left voice
let stan_audio; //right voice
let leftVal, rightVal;
let audioSlider;

function preload() {
  soundFormats('ogg', 'mp3');
  theresa_audio = loadSound('theresa_vocal_solo.mp3'); 
  stan_audio = loadSound('stan_vocal_solo.mp3'); 
}

function centerCanvas() {
  let x = (windowWidth - width) / 2;
  let y = (windowHeight - height) / 2;
  cnv.position(x, y);
}

function setup() {
  cnv = createCanvas(800, 480);
  centerCanvas();
  // specify multiple formats for different browsers
  video_file = createVideo(['assets/theresa_stan_480p_with_instrumental.mp4', 'assets/theresa_stan_480p_with_instrumental.webm']);
  video_file.hide(); // by default video shows up in separate dom
  // element. hide it and draw it to the canvas
  // instead

  playButton.addEventListener('click', togglePlay);

  audioSlider = createSlider(-1, 1, 0, 0.1);
  audioSlider.style('width', '150px');
  audioSlider.position(720, 655, 'relative');
}

function windowResized() {
  centerCanvas();
}

function draw() {
  background(150);
  image(video_file, 0, 0); // draw the video frame to canvas

  panValue = audioSlider.value();
  panAudio();
}

function togglePlay() {
  if(playing) {
    video_file.pause();
    theresa_audio.pause();
    stan_audio.pause();
    playButton.innerText = "Start Video";

    playing = false;
  } else {
    video_file.loop();
    theresa_audio.loop();
    stan_audio.loop();
    playButton.innerText = "Stop Video";

    playing = true;
  }
}

function panAudio() {
  theresa_audio.pan(-1);
  stan_audio.pan(1);

  if (panValue < 0) {
    //sets volume to gradually increase left voice and decrease right voice
    leftVal = panValue * (-1);
    rightVal = 1 - leftVal;

    theresa_audio.setVolume(leftVal);
    stan_audio.setVolume(rightVal);

  } else if (panValue > 0) {
    //sets volume to gradually increase right voice and decrease left voice
    rightVal = panValue;
    leftVal = 1 - rightVal;

    theresa_audio.setVolume(leftVal);
    stan_audio.setVolume(rightVal);

  } else if (panValue == 0) {
    //middle of slider sets max volume for both voices
    //no panning
    theresa_audio.setVolume(1);
    stan_audio.setVolume(1);

  }
}

```

```auto
//INDEX.HTML:
<!DOCTYPE html>
<html>
  <head>
    <title>P5</title>
    <script src="ml5.min.js" type="text/javascript"></script>
    <script src="p5.min.js"></script>
    <script src="p5.dom.min.js"></script>
    <script src="p5.sound.min.js"></script>
   
    <link 
      rel="stylesheet" 
      type="text/css" 
      href="style.css" />
    <link 
      rel="preconnect" 
      href="https://fonts.gstatic.com" >
    <link 
      href="https://fonts.googleapis.com/css2?family=Nunito+Sans&display=swap" 
      rel="stylesheet" >
    <link 
      rel="stylesheet" 
      href="style.css" />

    <meta charset="utf-8" />
  </head>

  <body>
    <header id="masthead">
      <h1>P5</h1>
    </header>

    <main id="video">
      <div id="p5_loading">Loading P5.js...</div>
    </main>

    <footer id="bottom-toolbar">
        <div id="audio-controls">
          <button id="play-button">Start Video</button>
        </div>

        <!--
         <div id="slider" class="slidecontainer">
          <input type="range" min="-1" max="1" value="0" class="slider" id="sliderRange" step="0.2">
        </div>
        -->
       
      </div>
    </footer>

    <script src="sketch.js"></script>
  </body>
</html>

```

```auto
//STYLE.CSS
html,
body {
	font-family: 'Nunito Sans', sans-serif;
	color: #444444;
	background-color:#e1f3f8;
	height: 100%;
	width: 100%;
	margin: 0;
	padding: 0;
}

body {
	display: flex;
	flex-direction: column;
	/* align-items: stretch; */
	height: 100%;
	width: 100%;
}

/* Masthead */
#masthead {
	text-align: center;
	background-color:#e1f3f8;
}

/* Web cam */
#video {
	flex: 1;
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: transparent;
}

/* Bottom toolbar */
#bottom-toolbar {
	display: flex;
	align-items: center;
	height: 120px;
	background-color:#e1f3f8;
	padding: 10px;
}

#audio-controls {
	flex: 1;
	text-align: center;
}

button {
	background-color:white;
	color: #444444;
	padding: 8px;
	border: 1px solid #444444;
	border-radius: 8px;
	position: relative;
	left: -75px;
}

```

---

<div class="post-metadata">

**Author:** ![KumuPaul](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kumupaul/32/13072_2.png) [@KumuPaul](https://discourse.processing.org/u/KumuPaul)\
**Post date:** [June 2, 2021, 9:32pm UTC](https://discourse.processing.org/t/p5-layout-questions/30453/2 "2021-06-02T21:32:40Z")

</div>

If you are going to define elements in HTML and then access them from javascript you need to ensure that the document is finished loading before you attempt to access them. I think it is sufficient to move any uses of `document.getElementById` to the `setup()` function (this assumes the setup is only called after `document` raises the `onreadystatechange` event and has a `readyState` value of `'complete'`).

I was able to make your sketch work by adding the following line to your setup function:

```auto
	playButton = document.getElementById("play-button");

```

---

<div class="post-metadata">

**Author:** ![KumuPaul](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kumupaul/32/13072_2.png) [@KumuPaul](https://discourse.processing.org/u/KumuPaul)\
**Post date:** [June 2, 2021, 9:41pm UTC](https://discourse.processing.org/t/p5-layout-questions/30453/3 "2021-06-02T21:41:37Z")

</div>

Actually I misunderstood the issue you were encountering because when I copied your code to somewhere I could test it I inadvertently moved your `<script />` tag into the `<head>` which introduced an issue that wouldn’t occur with the `<script />` tag at the end of the body.

The actual issue with the slider created using `createSlider` is the use of `'relative'` positioning. In CSS, `relative` positioning causes the element to be offset from where in would normally be placed based on block or inline layout. The large y value for the position of you slider (`655`) is causing it to display off the bottom of the page (if you scroll down a lot you will see it). The precise layout solution for your slider will depend on exactly where you want it to be positioned.

---

<div class="post-metadata">

**Author:** ![KumuPaul](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kumupaul/32/13072_2.png) [@KumuPaul](https://discourse.processing.org/u/KumuPaul)\
**Post date:** [June 2, 2021, 9:56pm UTC](https://discourse.processing.org/t/p5-layout-questions/30453/4 "2021-06-02T21:56:55Z")

</div>

One thing you might want to try is making your slider created with `createSlider` a child of the `audio-controls` div by calling `audioSlider.parent('audio-controls');`. However, be aware, there seems to be something special about the canvas element that makes it appear above other elements in the stacking order. So you might want to set the `z-index` of `audio-controls` to 1 (alternately setting element positions to `'relative'` does seem to magically pop them above canvas in the stacking order). CSS is bonkers sometimes 🤪.

---

<div class="post-metadata">

**Author:** ![karenmani](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/karenmani/32/13359_2.png) [@karenmani](https://discourse.processing.org/u/karenmani)\
**Post date:** [June 3, 2021, 1:12pm UTC](https://discourse.processing.org/t/p5-layout-questions/30453/5 "2021-06-03T13:12:04Z")

</div>

Got it. Tried adding those two lines of code but didn’t seem to make a difference. What layout solution would I have to set rather than `relative` in order to keep the slider lined up to the right of the `start` button?

---

<div class="post-metadata">

**Author:** ![KumuPaul](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kumupaul/32/13072_2.png) [@KumuPaul](https://discourse.processing.org/u/KumuPaul)\
**Post date:** [June 3, 2021, 7:30pm UTC](https://discourse.processing.org/t/p5-layout-questions/30453/6 "2021-06-03T19:30:36Z")

</div>

Here’s an example (If you click play I apologize for the terrible choice of audio files, they’re just what I had lying around).

> **[Discourse Question P5 Layout Question - OpenProcessing](https://openprocessing.org/sketch/1211587/pc/5B7bZdJF)**

Basically all I did was add

```auto
	audioSlider.parent('audio-controls');

```

And remove

```auto
	// audioSlider.position(720, 655, 'relative');

```

I also commented the relative positioning of button:

```auto
button {
	background-color: white;
	color: #444444;
	padding: 8px;
	border: 1px solid #444444;
	border-radius: 8px;
	/*
	position: relative;
	left: -75px; */
}

```

Because this is generally not a great way to adjust positioning. If you want to create space between the button and slider you should use margin.

And lastly I set the `z-index` for bottom-toolbar and eliminated the background so that it would show above the canvas:

```auto
#bottom-toolbar {
	display: flex;
	align-items: center;
	height: 120px;
	padding: 10px;
	z-index: 1;
}

```
