Flexbox: Two even columns - big image (with aspect-ratio) and content - html

I need to create an information section that includes an image and content next to it.
It should look like this:
I have already written a little bit of code, but it does not seem to be the best solution: everything works fine, but code is not graceful.
Please, have a look:
/* Simple reset */
img {
display: block;
max-width: 100%;
}
body {
background-color: black;
}
.information {
display: flex;
gap: clamp(5rem, 10vw, 8rem);
}
.information > * {
width: 50%; /* Using the 'width' property. */
}
.information-content {
align-self: center;
color: white;
}
.information-image {
align-self: flex-start;
object-fit: cover;
aspect-ratio: 1 / 1.10;
border-radius: 5px;
}
<section>
<div class="container">
<div class="information">
<img
class="information-image"
alt="Products for companies & Startups"
src="https://s3-alpha-sig.figma.com/img/6630/3672/40959a0086f9fbb8418c0829b277dd93?Expires=1670198400&Signature=gpQ5NqRXp9omRHkjCl718I9WPLqfx4xPKp1CQSMKbEnRCU7izmQIXkcn6zI6Z17p8Q7Li-wBAXb3P2Jg9qEuJauFeKqErbl4jgW950K35-LeX394hN7fJ7UEPmkgGSqB-drY1QdU7NZVV4QKTrZ0QBuw47xVBPOOfJMQO8NPOpZkx43UbbkS1yGgnxN5tELyriz9e8pH6pXO8AnJx7zvGz4mm3InyHOySUcb3ibVPa9XKJ8fyxPnkBeVoYFvwpiVddEs7uVNqCkCRuN2dJIIQg78FB-6TYX13nQ~NxvhG2059ks2q52a9p0N-DSmSYE-Yt-jedbJ1fEt3cZVnIfzUw__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA"
/>
<div class="information-content">
<h2>
My main goal is to keep my customers satisfied.
</h2>
<p>
Even with skills that are primarily mental, such as
computer programming or speaking a foreign language.
</p>
<p>
Even with skills that are primarily mental, such as
computer programming or speaking a foreign language.
</p>
</div>
</div>
</div>
</section>
My concern is the width property set on each child of my flex parent. As far as I know, using width inside flexbox is not the best idea? However, when I try to use the flex-basis property, everything breaks.
Note: I cannot use display: grid because the image can be after the content - with grid I will have to change the order and the code will become more complicated.

Related

HTML/CSS justifying text in separate blocks

Taking any page from any book or article that is justified and trying to make an exact online replica (same look and feel with HTML/CSS), that is including justifying the text with the exact line break and setting the outer wrapper with a width that match the min/max-width of the text itself - is this at all possible?
The HTML could be something like this:
...
<div class="page-wrapper">
<span class="line">The Republic of Plato is the longest of his works with the exception of the Laws,</span>
<span class="line">and is certainly the greatest of them. There are nearer approaches to modern</span>
<span class="line">metaphysics in the Philebus and in the Sophist; the Politicus or Statesman is</span>
<span class="line">more ideal; the form and institutions of the State are more clearly drawn out</span>
</div>
...
Note 1:
This CSS-trick isen't scalable as it relies on the rendering engine, and either the fix with (in example below set as 500px) will break either A) too early and add unwanted breaklines, B) too late and add large word-spacing or C) a case-by-case assessment that's of no good either as it's maybe perfect on the desktop but falls short on either A) or B) on mobile, vice versa.
.page-wrapper {
text-align: justify;
width: 500px;
}
.line:after {
content: "";
display: inline-block;
width: 100%;
}
Note 2:
I would prefer a pure HTML/CSS solution, if this is not possible, let's get JS on the table...
You could just use <p> paragraph with <br> break tags where necessary.
CSS wouldn't be complicated either
p {
text-align: justify;
}
Although I'm not necesarilly sure
What you're asking for
Why it has to be an exact replica of the source, since web is fairly dynamic.
C) a case-by-case assessment that's of no good either as it's maybe perfect on the desktop but falls short on either A) or B) on mobile, vice versa.
Seeing as you are also having problems with different sizes, #media queries might help quite a bit.
#media only screen and (max-width: 600px) {
// DO SOMETHING HERE IF SCREEN IS SMALLER THAN 600px
}
You could also have 2 different divs and hide one where necessary, and show the other.
div.mobile {
display: block;
}
div.desktop {
display: none;
}
#media only screen and (max-width: 600px) {
div.desktop {
display: block;
}
div.mobile{
display: none;
}
}
The quick and dirty way:
Work out you maximum character length. Use a monospaced font. Set your wrapper width using the ch unit and your max character count, eg 82ch. Next set a container with a max width of 100vw and overflow:auto so that the content is scrollable.
.page-container {
max-width:100vw;
overflow:auto;
}
.page-wrapper {
text-align: justify;
width: 82ch;
background-color:#EEE;
font-family:courier;
font-size:15px;
}
.line:after {
content: "";
display: inline-block;
width: 100%;
}
<div class="page-container">
<p class="page-wrapper">
<span class="line">The Republic of Plato is the longest of his works with the exception of the Laws,</span>
<span class="line">and is certainly the greatest of them. There are nearer approaches to modern</span>
<span class="line">metaphysics in the Philebus and in the Sophist; the Politicus or Statesman is</span>
<span class="line">more ideal; the form and institutions of the State are more clearly drawn out</span>
</p>
</div>
Slightly fancier:
Same as the above but set some media break points to adjust the font size. I'll leave it to you to work out font-sizes and break points.
.page-container {
max-width: 100vw;
overflow: auto;
}
.page-wrapper {
text-align: justify;
width: 82ch;
background-color: #EEE;
font-family: courier;
font-size: 15px;
}
.line:after {
content: "";
display: inline-block;
width: 100%;
}
#media screen and (max-width:768px) {
.page-wrapper {
background-color: #EFE;
font-size: 12px;
}
}
#media screen and (max-width:575px) {
.page-wrapper {
background-color: #FEE;
font-size: 11px;
}
}
<div class="page-container">
<p class="page-wrapper">
<span class="line">The Republic of Plato is the longest of his works with the exception of the Laws,</span>
<span class="line">and is certainly the greatest of them. There are nearer approaches to modern</span>
<span class="line">metaphysics in the Philebus and in the Sophist; the Politicus or Statesman is</span>
<span class="line">more ideal; the form and institutions of the State are more clearly drawn out</span>
</p>
</div>
What javascript can add
You could use javascript to calculate the max number of characters per line and update the with in ch based on the result.
Why not calculate font size based on width I hear someone ask? Well the problem with that is font size is based on character height, so basing it of width is... problematic.

How can I get this input element to fill all remaining space on the page without being pushed to the next line?

I'm attempting to recreate Zork, and so I have a large chunk of text that always ends with ">" on a new line, to mark where the input area is, as seen here:
https://i.imgur.com/NYwSfB4.png
The issue is that I'd like that input area to take up the remaining space on the page. Everything I have tried so far either pushes it to the next line, or works but is pretty janky in terms of implementation. To get it to work I had to break the text into two sections, the majority of the text, and the indicator. This can be seen here:
<div id="game-text">
West of House<br/>
You are standing in an open field west of a white house,
with a boarded front door.<br/>
There is a small mailbox here.<br/>
<br/>
</div>
<span id="indicator">
>
</span>
<span id="input-span"><input id="user-input"/></span>
#indicator{
display: table-cell;
}
#input-span {
display: table-cell;
width: 100%;
}
#user-input{
width: 100%;
}
This works, but ideally i'd like to remove the indicator span entirely and have the '>' symbol placed within the game-text div itself, which I imagine from my experimenting will require me to switch the div to a span anyways. Any help to smooth this out would be greatly appreciated.
EDIT: This is what i'd like the html to end up looking like, if possible:
<span id="game-text">
Big wall of text<br/>
<br/>
>
</span>
<span id="input-span"><input id="user-input"/></span>
No need to use another span around the > to get the desired look. You can use display:flex; and add flex-grow:1; to the input to make it fill the row.
body {
color: #fff;
background: #000;
}
.user-input-container {
display: flex;
justify-content: start;
}
#user-input {
margin-left: 5px;
flex-grow: 1;
}
<div id="game-text">
West of House<br/> You are standing in an open field west of a white house, with a boarded front door.<br/> There is a small mailbox here.<br/>
<br/>
</div>
<div class="user-input-container">><input id="user-input" /></div>
You can use Flex properties:
HTML
<div class="flexContainer">
<span>
>
</span>
<input id="user-input"/>
</div>
CSS
.flexContainer{
display: flex;
flex-direction: row;
input{
width: 100%
}
}
If the idea is to use the table-layout, then you need a parent acting like a table and only set the first span as a cell, This should not be your answer :
p[id] {
display: table;
width: 100%;
padding: 0 1em;
box-sizing: border-box;
}
#indicator {
display: table-cell;
width: 0;/* first funny thing about table-layout */
}
#input-span {
display: block;/* nop , i'll be a block, not a cell, so i use the whole space left !! */
}
#user-input {
width: 100%;/* let's use the width of my parent */
}
<p id> <!-- i'll be a table or tbody, tr -->
<span id="indicator"> > </span><!-- i'll be a cell -->
<span id="input-span"> <!-- i'll be a block -->
<input id="user-input"/> <!-- i'll be resized to 100% width -->
</span>
</p>
But today, flex or grid are better option and much more easy to understand and set in action ;) that's what i'd go for. In any case, you'll need to wrap those elements together.

How to keep two columns the same height with image?

We have a two column layout where image is on one side with text on the other. We want the image to be the same height as the content. We are having an issue when the text column reaches a certain height, then it will not make the image go full height. Although not added, this .flex__wrapper is surrounded by an outer <div class="container"> element so that we can handle larger screens where we may want to limit the width.
How can we achieve this? Our current solution uses flexbox, but we have also tried the following solutions but none resolves the problem.
Goal:
As the right column containing the text increases in height, i want the image to also take up the same amount of height.
Solutions we tried, but they didn't work. They seem to work well with text and text, but not text and image.
Make two columns the same height (using Flexbox)
Keep columns with same height
(using Tables)
.flex__wrapper {
display: flex;
position: relative;
align-items: center;
background-color: #eee;
}
[class*=col--] {
box-sizing: border-box;
}
.col--m-s-12 {
width: 100%;
}
.col--t-s-6 {
width: 50%;
}
img {
display: block;
height: auto;
}
<div class="flex__wrapper">
<div class="col--m-s-12 col--t-s-6">
<img src="https://thumb1.shutterstock.com/display_pic_with_logo/422872/1024946740/stock-photo-large-group-of-business-people-standing-with-folded-hands-togeth-1024946740.jpg">
</div>
<div class="col--m-s-12 col--t-s-6">
<div>Distinctively engineer timely benefits before leading-edge technology. </div>
<div>Quickly brand strategic web-readiness whereas global relationships. Credibly underwhelm interdependent e-markets via plug-and-play value. Professionally maximize emerging partnerships rather than equity invested information. Objectively morph intuitive applications rather than multimedia based best practices. Competently innovate covalent infrastructures after premium relationships.
Globally conceptualize holistic sources and leveraged synergy. Distinctively maintain stand-alone content without market-driven niche markets. Completely orchestrate seamless channels after high-quality synergy. Rapidiously scale cutting-edge niche markets with reliable innovation. Intrinsicly productize multifunctional manufactured products without high standards in e-tailers.</div>
</div>
</div>
Current issue:
Additional issue:
Desired result:
You need to apply max-width:100% on your image. Now even after applying the following style your image will not take whole place in full screen(1600*900px), this is happening because your original image is of less size(450*274) and the container where your are trying to fit is 792px approx. Try using a bigger image then it will be solved.
.flex__wrapper {
display: flex;
position: relative;
background-color: #eee;
flex-wrap: wrap;
}
#media screen and (min-width: 1024px) {
.flex__wrapper {
max-width: 56%;
}
}
[class*=col--] {
box-sizing: border-box;
flex-basis: 0;
flex-grow: 1;
max-width: 100%;
}
.col--m-s-12 {
width: 100%;
}
.col--t-s-6 {
width: 50%;
}
img {
height: 100%;
width: 100%;
object-fit:cover;
}
<div class="flex__wrapper">
<div class="col--m-s-12 col--t-s-6" style="border:solid 1px;">
<img src="https://thumb1.shutterstock.com/display_pic_with_logo/422872/1024946740/stock-photo-large-group-of-business-people-standing-with-folded-hands-togeth-1024946740.jpg" class="img-fluid">
</div>
<div class="col--m-s-12 col--t-s-6">
<div>Distinctively engineer timely benefits before leading-edge technology. </div>
<div>Quickly brand strategic web-readiness whereas global relationships. Credibly underwhelm interdependent e-markets via plug-and-play value. Professionally maximize emerging partnerships rather than equity invested information. Objectively morph intuitive
applications rather than multimedia based best practices. Competently innovate covalent infrastructures after premium relationships. Globally conceptualize holistic sources and leveraged synergy. Distinctively maintain stand-alone content without
market-driven niche markets. Completely orchestrate seamless channels after high-quality synergy. Rapidiously scale cutting-edge niche markets with reliable innovation. Intrinsicly productize multifunctional manufactured products without high standards
in e-tailers.</div>
</div>
</div>
html:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test3</title>
<link rel="stylesheet" type="text/css" href="test.css">
</head>
<body>
<main class="holder">
<section class="left-div">
<h1 class="flat-invisible">test-3</h1>
<img src="https://thumb1.shutterstock.com/display_pic_with_logo/422872/1024946740/stock-photo-large-group-of-business-people-standing-with-folded-hands-togeth-1024946740.jpg" alt="stock photo large group of business people standing with folded hands together">
</section>
<aside class="right-div">
<div>Distinctively engineer timely benefits before leading-edge technology. </div>
<div>Quickly brand strategic web-readiness whereas global relationships. Credibly underwhelm interdependent e-markets via plug-and-play value. Professionally maximize emerging partnerships rather than equity invested information. Objectively morph intuitive applications rather than multimedia based best practices. Competently innovate covalent infrastructures after premium relationships.
Globally conceptualize holistic sources and leveraged synergy. Distinctively maintain stand-alone content without market-driven niche markets. Completely orchestrate seamless channels after high-quality synergy. Rapidiously scale cutting-edge niche markets with reliable innovation. Intrinsicly productize multifunctional manufactured products without high standards in e-tailers.</div>
</aside>
</main>
</body>
</html>
css:
.left-div {
float: left;
grid-area: section;
max-width: 100%;
max-height: 100%;
}
.flat-invisible {
margin: 0em;
padding: 0em;
line-height: 0em;
height: 0em;
visibility: hidden;
}
.left-div > img {
object-fit: cover;
top: 0px;
height: 100%;
max-width: 120%;
}
.right-div {
padding-top: 2em;
padding-bottom: 2em;
padding-left: 150px;
max-width: 50%;
grid-area: aside;
max-height: 100%;
}
.holder {
max-width: 90%;
background-color: #eee;
display: grid;
grid-template:
'section aside';
}

Background With Changing Elements HTML

Sorry if the title makes no sense, I didn't know how to call this issue, lol.
So... I have this android app which shows a parking lot, with the parking layout as the background and some cars showing "inside" each parking when needed. This is easy to build using different layouts for each parking and changing the image sources from empty to a car, etc.
The thing is... I need to replicate this on a web page, And I have no idea how could I build a background and change images on top of it. I suppose I could make a bunch of divs for each parking, changing the img sources when needed and use the parking lot layout as the background for the whole thing, however I don't know if this would be the best practice, and the whole idea doesn't really sound responsive to me.
Any ideas?
I don't expect/need it to change in real time like you can do with Android, but I do need to replicate the idea of changing images programatically on top of a background.
Thanks!
The only real way to overlay images with CSS is by having a relatively displayed container with it's inner image elements absolutely positioned.
Using this idea, it'd be possible to absolutely position the car images on top of your image parking spots.
That being said, why don't you create a more abstract representation of this parking lot?
.flex-container {
display: flex;
justify-content: center;
background-color: DodgerBlue;
}
.flex-container > div {
width: 100px;
margin: 10px;
text-align: center;
line-height: 75px;
font-size: 30px;
}
.available {
background-color: green;
}
.unavailable {
background-color: red;
}
<!DOCTYPE html>
<html>
<body>
<h1>Parking spot availability</h1>
<p>Green indicates an available spot. Red indicates an unavailable spot.</p>
<div class="flex-container">
<div class="available">1</div>
<div class="unavailable">2</div>
<div class="available">3</div>
</div>
</body>
</html>
For something like this, I would recommend using jQuery. Register event handlers for each of your images and adjust the src property accordingly. I have provided an example below for review:
$('.car').on('click', function () {
$(this).prop('src', 'https://placeholdit.co//i/300x150?text=A%20Completely%20New%20Image!&bg=111111');
});
.playground {
background-color: #ccc;
width: 500px;
height: 500px;
}
.car {
margin: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="playground">
<img src="https://placeholdit.co//i/200x150?text=The%20Original%20Image" class="car" />
</div>

How permanently align div of a stacked element

I need to move all div inside of container up to a div above it
<div class="gb-box-holder">
<!-- GUIDE BOX -->
<div class="gb-box gb-box-1">
<div class="gb-header">
<span class="gb-decor-top"></span>
<div class="gb-logo">
<img class="gb-img" src="http://www.scim.si/wp-content/uploads/2015/01/apply.jpg" alt="">
<div class="gb-logo-cover"></div>
</div>
<h3>Lorem ipsum dolor</h3>
<!-- <span class="gb-decor-top"></span> -->
</div>
<div class="gb-container">
<span class="gb-decor-container"></span>
<p>
Lorem
</p>
<a class="gb-btn-guide" href="#"> Reed more</a>
</div>
</div>
<!-- GUIDE BOX -->
</div>
BOXES SECTION END -->
#gd-section .gb-box-holder {
display: flex;
display: -webkit-flex;
flex-wrap: wrap;
-webkit-flex-wrap: wrap;
justify-content: top;
-webkit-justify-content: top;
}
#gd-section .gb-box-holder .gb-box {
display: block;
width: 246px;
background-color: #303030;
margin: 5px;
float: left;
}
.gb-box class of each div
ps. Sorry for my spalling, English not my mother language
There are multiple ways You can approach this. The wrap that flex creates is only horizontal and not vertical - therefore, you won't be able to stack an item upwards. So it must be done in a column-wise manner. You just have to invert things in order for it to work like You want it to.
Here is a way to do this using Flex.
Another way of doing this is using HTML Columns which is your quickest option here but it will not be responsive in all browsers, therefore you will need to use prefixes and manual adjustments.
div {
-webkit-columns: 100px 3; /* Chrome, Safari, Opera */
-moz-columns: 100px 3; /* Firefox */
columns: 100px 3;
}
You can find a good tutorial on this here.
The other more fool-proof way is to use a plugin called CSS Masonry which uses JavaSript to align your items in a certain way. The only con here is that it will add a bit of js bulk to your code and it will be a bit time consuming. But it will be responsive and perfectly aligned.
If you decide to go along the CSS column path, this CodePen will do you good as well.
You can not achieve this with flexbox but you might want to try using css columns although they are meant to be used for text.
.gb-box-holder {
columns: 200px 3;
}
http://codepen.io/ingvi/pen/EgAZwz/