Employ CSS flexbox and/or JavaScript for creating a customizable webpage

I am in the process of developing a basic IDE for an educational programming language that has similarities to Karel the Dog. One major issue I am encountering is creating the foundation HTML page.

The IDE consists of 4 main areas:

  • Toolbox (contains buttons like open, save as, run etc.)
  • Field (canvas where the executor can move and perform actions)
  • Code (uses CodeMirror editor for writing executor's commands)
  • Console (location for displaying messages such as compilation errors or runtime debug output)

I have outlined my requirements for each area in my code, so I will highlight what is currently not functioning properly:

  1. The page should occupy 100% of the screen height.
  2. I am struggling to make CodeMirror fill the entire available height within its parent container. Additionally, I want scrollbars to appear when the content exceeds the height of the parent element.
  3. Similar to CodeMirror, I am facing issues with the canvas element only on the vertical axis.
  4. I am looking for a way to create a separator between the code and field areas that can be used to adjust horizontal space distribution between these two sections.

One more challenge arises if addressing item number 4 requires JavaScript implementation. In this case, I prefer to utilize the WinJS 3.0 library instead of adding jQuery or other heavy frameworks solely for resizing functionality.

If anyone can offer guidance or assistance, it would be greatly appreciated.

I have uploaded my code to jsfiddle.net and included it here:

var ce = CodeMirror(document.getElementById('b-codemirror'), {
  value: "\n\n\nIt is CodeMirror element. [PARAMS ALL] " +
    "width: 100% of parent element, height: always 100% of" +
    " parent element + both scrollbars if needed\n\n\n",
  lineNumbers: true
});
var cc = document.getElementById("canvas").getContext("2d");
cc.font = "16px Helvetica";
cc.fillText("It is canvas. Can be resized from", 10, 30);
cc.fillText("JS. If it is larger than parent element,", 10, 60);
cc.fillText("corresponding scrollbar should appear.", 10, 90);
@import url("http://codemirror.net/lib/codemirror.css");

/* overriding default codemirror.css */
.CodeMirror {
  font-family: monospace;
  height: 100%;
}
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
.b-section {
  margin: 2px;
  padding: 4px;
  border-radius: 4px;
}
#b-fieldcode {
  min-height: 640px;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-flow: row;
  flex-flow: row;
}
#b-toolbox {
  background: #ffeebb;
}
#b-console {
  height: 100px;
  background: #ffeebb;
}
#b-field {
  background: #ccccff;
  overflow: auto;
  -webkit-flex: 1 1 40%;
  flex: 1 1 40%;
  -webkit-order: 1;
  order: 1;
}
#b-code {
  background: #dddd88;
  -webkit-flex: 1 1 60%;
  flex: 1 1 60%;
  -webkit-order: 2;
  order: 2;
}

@media all and (max-width: 1024px) {
  #b-fieldcode, #page {
    -webkit-flex-flow: column;
    flex-flow: column;
    flex-direction: column;
  }
  #b-code, #b-field {
    -webkit-order: 0;
    order: 0;
  }
  #b-field, #b-code {
    height: 500px;
  }
}
<script type="text/javascript" src="http://codemirror.net/lib/codemirror.js"></script>
<div id="b-toolbox" class="b-section">
  Here comes the space for buttons.
  [PARAMS ALL] width: 100% of screen, height: sized to content
</div>
<div id="b-fieldcode">
  <div id="b-field" class="b-section">
    Here comes canvas wrapper.<br />
    [PARAMS landscape] width: flex 40% of screen, height:
    100% of screen minus b-toolbox and b-console.
    <br />[PARAMS portrait] width: 100% of
    screen, height: fixed 400px.<br />
    <canvas width="300" height="300" id="canvas"
            style="background-color: green" />
  </div>
  <div id="b-code" class="b-section">
    Here comes CodeEditor wrapper.<br />
    [PARAMS landscape] width: flex 60% of screen, height:
    100% of screen minus b-toolbox and b-console.<br />
    [PARAMS portrait] width: 100% of
    screen, height: fixed 500px.
    <div id="b-codemirror"></div>
  </div>
</div>
<div id="b-console" class="b-section">
  Here comes output console.
  [PARAMS ALL] width: 100% of screen, height: fixed 120px.
</div>

Answer №1

To begin, it is important to differentiate between styles for portrait and landscape orientations. Creating styles for the portrait part is relatively straightforward, so we will focus on the landscape portion.

For the landscape layout, you'll need a fluid height header (containing buttons) and a fixed height footer (such as a console). This scenario perfectly fits the usage of CSS flexbox - allowing spare space to be allocated to the main content area. By setting

display: flex; flex-direction: column;
on the <body> element and flex: 1; on the main section (#fieldcode in your code snippet), you achieve this desired layout.

The #field should occupy 40% of the width within #fieldcode, while #code takes up the remaining 60%. To accomplish this, apply

display: flex; flex-direction: row;
to #fieldcode, and assign flex: 4; to #field and flex: 6; to #code, ensuring that the spare space distribution follows a 4:6 ratio. It's crucial to note the change in the flex-direction value from the previous step, indicating whether the separation occurs horizontally or vertically.

html, body {
  margin: 0;
  padding: 0;
}
#toolbox {
  background: #feb;
}
#field {
  background: #ccf;
  overflow: auto;
}
#code {
  background: #dd8;
  overflow: auto;
}
#codemirror {
  min-width: 100%;
  min-height: 100%;
}
#console {
  background: #feb;
  height: 120px;
}

@media screen and (orientation: portrait) {
  #field {
    height: 400px;
  }
  #code {
    height: 500px;
  }
}

@media screen and (orientation: landscape) {
  html, body {
    height: 100%;
  }
  body {
    display: flex;
    flex-direction: column;
  }
  #fieldcode {
    flex: 1;
    display: flex;
    flex-direction: row;
  }
  #field {
    flex: 4;
  }
  #code {
    flex: 6;
  }
}
<div id="toolbox">buttons here</div>

<div id="fieldcode">
  <div id="field">
    <canvas></canvas>
  </div>

  <div id="code">
    <div id="codemirror"></div>
  </div>
</div>

<div id="console">console here</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Create a form in a PHP file containing a pair of buttons for selecting a specific action

Consider the following HTML code snippet: <body onload="showcontent()"> <!-- onload attribute is optional --> <div id="content"><img src="loading.gif"></div> <!-- exclude img tag if not using onload --> < ...

Updating an Object in vue.js Upon Click Event to Add a New Value

I currently have a code snippet that looks like the following: arr = [ { val1: a, val2: b }, { val1: a, val2: b }, { val1: a, val2: b } ] <div v-for="single in arr"> <button v-on:click="addSome"></button> </div> When I c ...

The information displayed in my Google snippet does not match the content of the intended URL

It may seem a bit confusing, so to clarify, here is an example: When you click the +1 button on this page, the snippet will display the text and URL from that specific page. However, in my case, the snippet displays text from the homepage URL instea ...

Customize the keyboard on your iPod by replacing the default one with a

Looking to customize the iPOD keyboard to only display numbers, similar to a telephone keypad: https://i.stack.imgur.com/X0L3y.png The current iPOD default keyboard looks like this: https://i.stack.imgur.com/VykjU.png ...

Utilize AngularJS to loop through a list with ng-repeat

Seeking guidance as an Angular newbie. The ng-repeat in question is formatted as: ng-repeat="f in drillDownList['D' + d.merchMetrics.DEPT_NBR + 'CG' + d.merchMetrics.CATG_GRP_NBR + 'C' + d.merchMetrics.DEPT_CATG_NBR] M ...

Optimize Material-UI input fields to occupy the entire toolbar

I'm having trouble getting the material-ui app bar example to work as I want. I've created a CodeSandbox example based on the Material-UI website. My Goal: My goal is to make the search field expand fully to the right side of the app bar, regar ...

Enhance Your Charts: Learn how to dynamically adjust zoom levels between two timestamps with just a simple form submission

I have a Zingchart Area Graph that displays events on a timeline with time on the X-Axis. I want to be able to automatically zoom into a specific timeframe on the graph based on user input from a form. For example, if a user selects a start time of 8 AM an ...

How can you efficiently transfer the expression utilized in v-for from the template to the component code?

How can I extract the expression within the template that is contained in :class? <div v-for="(user, index) in users" :key="index" :class="{'bg-yellow-lighter': infoWindowMarker && infoWindowMarker.position.lat === user.posit ...

The animation in Material UI does not smoothly transition with the webkit scrollbar

I've been experimenting with CSS animations in Material UI's sx property to achieve a webkit scrollbar that eases in and out. However, instead of the desired effect, the scrollbar appears and disappears instantly. Whether I define the keyframes ...

The integration of a side panel with a chrome extension is experiencing issues

I am working on a chrome extension with the following functionalities - Extract URL path from a specific webpage. (The webpage's URL remains constant) Open this URL in a new tab. It can be either http:// or https://. Embed an iframe containing a sim ...

Tips for evaluating an array of objects in JavaScript

Welcome to the world of coding! Here's a scenario with an array: [ { "question1": "Apple", "question2": 5, "question3": "Item 1" }, { "question1": ...

Having trouble with the button's functionality in Internet Explorer?

Recently, I encountered an issue with a "dropdown button" that I created using only CSS and HTML. Surprisingly, it works flawlessly in Chrome and FireFox, but seems to have some glitches when tested on Internet Explorer (IE). The "New Invoice" button fails ...

Is CSS Transition smoothly easing in, but not out?

On the image gallery of this website , I have applied transitions to the images, where they ease in (fade in), but revert back to their original state instantly when the mouse moves off the image. Is there a way to make the transition reverse when the mo ...

Unable to set $_POST value when using $.ajax post request

I am a beginner in the world of PHP and JavaScript, and I have encountered an issue where I need to make changes to values in an XML document that has been read in. Specifically, I have an HTML Select element that was dynamically generated by PHP code. fu ...

Implementing AJAX in Rails for the new/create action can greatly enhance the user

I have a timeline with event sections on it that allow you to create, view, update, and delete events directly on the timeline page. Currently, the functionality for deleting an event is working smoothly as the delete section refreshes along with the timel ...

Why is it that the default theme of Material UI lacks any stylization at all?

After experimenting with both Carbon Design for React (@carbon/react) and Material UI (@mui/material) in conjunction with Next.js, I encountered styling issues with the components. While they functioned correctly to some extent, there were noticeable discr ...

What is the purpose of using a single pipe character within a Vue.js template handlebar expression?

Here is a sample code snippet: <div> {{ name | capitalize }} </div> I have searched through the documentation for vuejs and handlebars, but couldn't find any relevant information. ...

Problem with Layering in Javascript Canvas Game using Kinetic JS

Currently, I am attempting to replicate the game found at and delving into html5 canvas and kineticJS for my study. Here is the link to my fiddle: http://jsfiddle.net/2WRwY/7/ The issues I am facing are as follows: The tail part of the player in the f ...

Refreshing AJAX content with a dynamically adjusting time interval

I am facing a scenario where I have a webpage featuring a countdown alongside some dynamic data refreshed via AJAX. To optimize server load, I found a clever solution by adjusting the AJAX refresh interval based on the time remaining in the countdown, foll ...

Selenium - How to pass a file path to a dynamically generated input element that is not visible in the DOM

Check out this example of HTML code: This is how you create a visible button and display the selected file: <button id="visible-btn">visible button</button> <p>selected file is: <span id="selected-file"></spa ...