2

Okay..... So here is a list of things to know:

First, I am using fabric.js (I didn't include it in the tags because it's not the central focus of the problem), which means that when I create a new instance of a fabric.js canvas, it creates 2 canvas elements (.lower-canvas) and (.upper-canvas), which by interacting with it, I've come to find out that they are absolutely positioned, so long story short (with a huge run on) I can't change the fact there are 2 canvases and I can't change to a different library.

Second, I am using bootstrap to keep the UI looking slick. Right now it's structure looks like

<div class="row">
    <div class="col" id="canvas_container">
        <canvas id="canvas">
        </canvas>
    </div>
</div>
<div class="row">
    <div class="col">
        <br>
    </div>
</div>
<div class="row">
    <div class="col">
        ---some buttons---
    </div>
</div>

So when the page is generated, it changes from the previous code block to

<div class="row">
    <div class="col" id="canvas_container">
        <div class="canvas-container">
            <canvas id="canvas" class="lower-canvas">
            </canvas>
            <canvas class="upper-canvas">
            </canvas>
        </div>
    </div>
</div>
<div class="row">
    <div class="col">
        <br>
    </div>
</div>
<div class="row">
    <div class="col">
        ---some buttons---
    </div>
</div>

which changes the previous canvas to 2 different canvases with different classes but keeps the id of the initial canvas on one of the canvases, and creates a div with class "canvas-container" to encapsulate both canvases.

Third, the canvases will have dynamic sizes. The user will select which size canvas they want to use to interact with the fabric canvas.

Fourth, I have looked at various links on stackoverflow to try, and some have come really close, but still no cigar. The one I am thinking of specifically is here if you'd like to check it out.

Fifth, there shouldn't be any additional css affecting any of the elements apart from bootstrap - with the exception of the canvas elements to affect their size (measured currently in % but may change to vw or vh).

---The Problem Statement---

Just to restate the problem, I am trying to center both canvases that have absolute positions. I think this might be best accomplished if I can center just the .canvas-container, since both canvases are encapsulated in it and since they have absolute positioning. Any thoughts on this?

Let me know if there is anything else I can do to clear up anything I may not have touched on.

Thank you in advance.

--edit--

Just to give a little more context, the light blue boxes will always be the canvas element that needs to be centered.

Here is an update regarding one of the proposed solutions from @SoluableNonagon (it is the post that has a parent and 3 children that are vertically, horizontally, and "both" aligned), so you can see what is going on... for reference, the gray bar at the bottom is horizontally aligned.

Proposed solution

The green box is the #canvas_container element which shares the class col.

The light blue box is made up of both canvases.

Moving the css "up" on level to where the child becomes the parent and the new parent's contents becomes the child results in this

Potential solution change 1

@Gagandeep Sangh 's solution without making proper changes to affect the one specific element.

Gagandeep Sangh's solution 1

After making the changes to affect the 1 element, the result is like so

Gagandeep Sangh's solution 2

Shmack
  • 1,933
  • 2
  • 18
  • 23
  • Does this answer your question? [How to horizontally center a
    ](https://stackoverflow.com/questions/114543/how-to-horizontally-center-a-div)
    – SoluableNonagon Jun 18 '20 at 04:07
  • @SoluableNonagon thanks for the quick response, let me test and get back with you in about 10 to 15 minutes. – Shmack Jun 18 '20 at 04:08
  • @SoluableNonagon, Unfortuneately, no. It didn't solve the problem. I really think it amounts to having the element being position: absolute;. I tried the top 2 answers – Shmack Jun 18 '20 at 04:15
  • Can you provide a working snippet? much easier to help then. Also, stackblitz and codesandbox would do nicely – SoluableNonagon Jun 18 '20 at 04:22
  • Regarding that link, you need to find answers which also have position absolute. – SoluableNonagon Jun 18 '20 at 04:24
  • @SoluableNonagon, that link should be to a question that focuses around an absolute positioned element, unless I've put the wrong link. I will check in a minute. It's pretty late, so I likely overlooked that. – Shmack Jun 18 '20 at 04:32

2 Answers2

1

Generally, when an element is position: absolute the parent is position: relative. Then, the absolute element is left: 50%; transform: translateX(-50%); for horizontal centering. For vertical centering top: 50%; transform: translateY(-50%);

.parent {
  position: relative;
  height: 200px; // needs height/width cause 'absolute' child takes no space
  width: 200px;
  border: 1px solid red;
}

.child-1 {
  position: absolute;
  height: 50px;
  width: 50px;
  border: 1px solid blue;
  
  left: 50%;
  transform: translateX(-50%);
}

.child-2 {
  position: absolute;
  height: 50px;
  width: 50px;
  border: 1px solid orange;
  
  top: 50%;
  transform: translateY(-50%);
}

.child-3 {
  position: absolute;
  height: 50px;
  width: 50px;
  border: 1px solid green;
  
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
<div class='parent'>
  <div class='child-1'>horizontal</div>
  <div class='child-2'>vertical</div>
  <div class='child-3'>both</div>
<div>
SoluableNonagon
  • 11,541
  • 11
  • 53
  • 98
  • @ShanerM13 glad you were able to figure out a solution – SoluableNonagon Jun 18 '20 at 16:28
  • This post truly answers the question, though it isn't quite what I was going for. It does horizontally align the element inside of the box, but the parent needed to be shifted over, which I was able to do. Keep your eyes peeled, I am going to open another thread about resizing an element with javascript given that it has the !important property on it. – Shmack Jun 18 '20 at 16:57
1

The <div class="canvas-container"> can be centered respective to its parent <div class="col"> using position:absolute; and setting the col div to position:relative; but here comes a new issue that after setting the <div class="canvas-container"> as absolute it will flow out of its parent div and the height of parent div will collapse as it doesn't have any other content in it, than you need to add some height to that div also, so basically you can try this

.col{
    min-height:500px;
    position:relative;
}
.canvas-container{
    position:absolute;
    top:50%;
    left:50%;
    transform:translate(-50%,-50%);
}

Hope it works.

Gagandeep Singh
  • 975
  • 6
  • 11
  • It was a good try at it, but unfortuneately didn't work either. It might help to mention that I'm fairly certain that ".col"s are flex boxes, because that's how bootstrap operates with their "grid" system. – Shmack Jun 18 '20 at 04:37
  • In BS4 `row` is set as a flex container and not `col`, and what issue are you facing with above code ? – Gagandeep Singh Jun 18 '20 at 04:40
  • So it's positioned more bottom right of the center of the page. I also need to be careful with altering the css of the .col, because it will affect the other elements on the page. Nice to know regarding that nuance between col and row. Row is a "flex container" and col is "flex item". – Shmack Jun 18 '20 at 04:45
  • Give me a minute and I will post a pic. – Shmack Jun 18 '20 at 04:59
  • have you tried changing `col` to `col-12`, is it possible to make a jsfiddle/codepen to replicate the issue ? – Gagandeep Singh Jun 18 '20 at 05:27
  • I got it figured out. I was able to center the green box by setting it to a flex box and keeping its position relative, then setting the inside contents width and height to 100% with the same centering that you all were suggesting. I could probably just use the height and width, and not have to use the centering... I will look at that tomorrow, and award the answer. Thanks for the help. I now have a different problem, which I will share on this thread later. – Shmack Jun 18 '20 at 06:11