Search code examples
javascriptcssvue.jsheightweb-component

How to make a custom Web Component "height:100%" of the page?


I wrote a Web Component using Vue.js and vue-custom-element. Now I want to make my-chat and my-whiteboard Web Components "height:100%".I'm using the component like this:

// App.vue
<template>
  <splitpanes class="default-theme">
    <pane>
      <my-chat></my-chat>
    </pane>
    <pane>
      <my-whiteboard></my-whiteboard>
    </pane>
  </splitpanes>
</template>

The only way that I know is to set the height of all parents to 100% like this:

html,
body,
splitpanes,
pane,
my-chat,
my-whiteboard {
    height: 100%;
}
//main.js

...
// Load custom element plugin
Vue.use(vueCustomElement);

// Define web components
Vue.customElement("skyroom-whiteboard", Whiteboard);
Vue.customElement("skyroom-chat", Chat);
...

And do this for the all tags inside web my-chat and my-whiteboard too!!!

The problems:

  1. This is not working for my- components.
  2. It seems to be wrong! Isn't there any right way to do this?

Solution

  • The simple way to do it is to use

    my-chat, my-whiteboard {
      min-height: 100vh;
    }
    

    However, when one of them becomes taller than 100vh, it will grow without the other one. So, most likely, ...

    display: block;
    height: 100vh;
    overflow-y: auto;
    

    ... will do a better job.

    Here's an example (you don't need any the CSS after /* let's test it */ line but I had to add it as all of them are custom elements and, by default, they have a display value of inline):

    my-chat,
    my-whiteboard {
      display: block;
      height: 100vh;
      overflow-y: auto;
    }
    
    
    /* let's check it */
    
    my-chat,
    my-whiteboard {
      box-sizing: border-box;
    }
    
    tester {
      height: 200vh;
      padding: 1rem;
    }
    splitpanes { display: flex; }
    pane:first-child { flex-basis: 75%; }
    pane:last-child { flex-grow: 1; }
    body { margin: 0; }
    /* don't use this line in your app, it will likely break stuff
     * I used it here because I don't have any content to break! */
    .default-theme * { display: block; }
    <splitpanes class="default-theme">
      <pane>
        <my-chat>
          <tester>my-chat</tester>
        </my-chat>
      </pane>
      <pane>
        <my-whiteboard>
          <tester>my-whiteboard</tester>
        </my-whiteboard>
      </pane>
    </splitpanes>

    Important note: If any of your components gets parsed by Vue into actual <div> elements, you'll need to change the selectors accordingly (but you did say they're custom elements, so I'm guessing they're used as-is).