How to make div fill the rest of viewport with keeping of aspect ratio (CSS or jQuery)?

时间:2015-10-06 08:55:07

标签: jquery css

I have a simple UI-like layout built with flexbox. It contains two bars with fixed sizes and a preview window, which should be fully responsive.

My preview window in Haml looks something like that:

.preview
  .page

But the issue is... when I style it with:

.page {
  width: 100vmin;
  padding-bottom: 56.25vmin; //16:9 56.25
}

It doesn't fill the rest of the viewport.

If I do something like this:

.page {
  width: 100%;
  padding-bottom: 56.25%; //16:9 56.25
}

It fills the whole available space, but with some viewport resolutions the .page might go outside of .preview and cover some space of my bars. Anyway, the padding-bottom aspect ratio solution is possibly not applicable for me because, in the funture, I will need to read coordineates from .page div, so I assume it should have real measurements, not built with paddings. That's why my question is: "How to make fully responsive div, which adapts to viewport size changing and keeps its aspect ratio without padding-bottom tricks (jQuery is allowed)?" Moreover, when .preview div has in a way bigger width than height, .page should take heiht as a standart to prevent overflow (like YouTube player does, for example).

HTML:

<div class='editor'>
  <div class='actions-bar'>
    <a class='actions' href='#'>Каждый</a>
    <a class='actions' href='#'>Охотник</a>
    <a class='actions' href='#'>Желает</a>
    <a class='actions' href='#'>Знать</a>
    <a class='actions' href='#'>Где</a>
    <a class='actions' href='#'>Сидит</a>
    <a class='actions' href='#'>Фазан</a>
  </div>
  <div class='tool-bar'>
    <div class='tools'>
      <div class='tool'></div>
      <div class='tool'></div>
      <div class='tool'></div>
      <div class='tool'></div>
      <div class='tool'></div>
      <div class='tool'></div>
    </div>
  </div>
  <div class='preview'>
    <div class='page'></div>
  </div>
</div>

CSS:

.editor {
  position: fixed;
  height: 100%;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -webkit-user-select: none;
}
.editor .actions-bar {
  height: 50px;
  min-width: 500px;
  width: 100%;
  background-color: #E3142C;
  display: flex;
  align-content: center;
  align-items: center;
  padding: 0;
}
.editor .actions-bar .actions {
  width: 100px;
  text-align: center;
  height: 100%;
  display: flex;
  color: white;
  text-decoration: none;
  vertical-align: middle;
  align-content: center;
  align-items: center;
  justify-content: center;
}
.editor .actions-bar .actions:hover {
  background-color: #f04155;
}
.editor .tool-bar {
  height: 95%;
  top: 5%;
  min-width: 175px;
  width: 175px;
  background-color: #F76475;
}
.editor .tool-bar .tools {
  display: flex;
  flex-wrap: wrap;
}
.editor .tool-bar .tools .tool {
  height: 50px;
  width: 50px;
  margin-left: 25px;
  margin-top: 25px;
  background-color: red;
  border: 2px solid #F7F7F7;
  border-radius: 5px;
}
.editor .tool-bar .tools .tool:hover {
  transform: scale(1.1);
}
.editor .tool-bar .tools .tool:active {
  transform: scale(1.1);
  border-color: #39b8f7;
}
.editor .preview {
  height: 100%;
  top: 50px;
  width: auto;
  left: 250px;
  background-color: #d0d0d0;
  display: flex;
  flex: 1 1 auto;
  justify-content: center;
  align-items: center;
}
.editor .preview .page {
  width: 100vmin;
  padding-bottom: 56.25vmin;
  background-color: white;
}

You can see how it works there:

http://codepen.io/dukeimg/pen/yYbgGq

I'm not waiting for ready solution. I will be really thankful if at least someone will describe me the way how to realize this properly on CSS or jQuery.

Please, don't blame me about my SCSS - it's just a draft, I know DRY, I will refact this code later.

P.S.: excuse my English - I'm Russian :)

1 个答案:

答案 0 :(得分:0)

我自己的解决方案:

HTML:

<div class='editor'>
  <div class='actions-bar'>
    <a class='actions' href='#'>Каждый</a>
    <a class='actions' href='#'>Охотник</a>
    <a class='actions' href='#'>Желает</a>
    <a class='actions' href='#'>Знать</a>
    <a class='actions' href='#'>Где</a>
    <a class='actions' href='#'>Сидит</a>
    <a class='actions' href='#'></a>
  </div>
  <div class='main'>
    <div class='tool-bar'>
      <div class='tools'>
        <div class='tool' id='label'></div>
        <div class='tool' id='image'></div>
        <div class='tool' id='video'></div>
        <div class='tool' id='audio'></div>
        <div class='tool' id='social'></div>
        <div class='tool' id='note'></div>
       </div>
    </div>
    <div class='preview'>
      <div id='page'></div>
    </div>
  </div>
  <div class='status-bar'></div>
</div>

CSS:

.body {
  margin: 0;
  padding: 0;
  height: 100vh;
}

.editor {
  display: flex;
  flex-flow: column;
  min-height: 100%;
  user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -webkit-user-select: none;
}

.editor .main {
   flex: 1 1 auto;
   display: flex;
   min-height: 100%;
}

.editor .main .tool-bar {
  min-height: 100%;
  min-width: 175px;
  width: 175px;
  background-color: #F76475;
}

.editor .main .tool-bar .tools {
  display: flex;
  flex-wrap: wrap;
}

.editor .main .tool-bar .tools .tool {
  height: 50px;
  width: 50px;
  margin-left: 25px;
  margin-top: 25px;
  background-color: #f0f0f0;
  border: 2px solid red;
  border-radius: 5px;
}

.editor .main .tool-bar .tools .tool:hover {
  transform: scale(1.1);
}

.editor .main .tool-bar .tools .tool:active {
  transform: scale(1.1);
  border-color: #39b8f7;
}

.editor .main .preview {
  background-color: #d0d0d0;
  display: flex;
  flex: 1 1 auto;
  justify-content: center;
  align-items: center;
}

.editor .main .preview #page {
  width: 80%;
  background-color: white;
}

.editor .actions-bar {
  flex: 0 1 auto;
  height: 50px;
  width: 100%;
  background-color: #E3142C;
  display: flex;
  align-content: center;
  align-items: center;
  padding: 0;
}

.editor .actions-bar .actions {
  width: 100px;
  text-align: center;
  height: 100%;
  display: flex;
  color: white;
  text-decoration: none;
  vertical-align: middle;
  align-content: center;
  align-items: center;
  justify-content: center;
}

.editor .actions-bar .actions:hover {
  background-color: #f04155;
}

.editor .status-bar {
  background-color: #2E2F30;
  flex: 0 1 40px;
}

jQuery的:

function pageAdjust() {

$('#page').width('80%');
$('#page').height($('#page').width() * 0.5625);

if ($('.preview').height() <= $('#page').height()) {
    $('#page').height($('.preview').height());
    $('#page').width($('.preview').height() * 1.7778);
}

$(window).on('resize', function(){
  pageAdjust();
});


$(document).ready(function() {
  pageAdjust();
});

工作示例:

http://codepen.io/dukeimg/pen/yYzggO

- V