CSS: Scale font-size to fit parent block element height - html

Almost every question and answer I have found talks about the viewport size; this isn't really my issues.
Take this Pen... https://codepen.io/njt1982/pen/pZjZNM
I have a very basic Bootstrap 4 grid like this:
<div class="container mt-4">
<div class="row">
<div class="col border"><div class="tile"><span>A</span></div></div>
<div class="col border"><div class="tile"><span>B</span></div></div>
...
...
</div>
<div class="row">
<div class="col border"><div class="tile"><span>A</span></div></div>
<div class="col border"><div class="tile"><span>B</span></div></div>
...
...
</div>
...
...
</div>
And some CSS to make these into squares (using the padding-top: 100% trick):
.col {
padding: 0;
}
.col:not(:last-child) {
border-right: none !important;
}
.row:not(:last-child) .col {
border-bottom: none !important;
}
.tile {
padding: 100% 0 0;
font-size: 5vw;
}
.tile span {
position: absolute;
left: 0;
top: 50%;
line-height: 0;
width: 100%;
text-align: center;
}
The problem here is that 5vw makes the font just the right size on my 2560px wide viewport, but by the time I have reached the lower breakpoint, it not longer fills the cells. I'd like to avoid tonnes of media queries to "tune" it.
Is there any CSS-only way of saying "font-size = container_height"?
font-size: 100% seems to just set the font to the base size (not the parent size, like you'd expect height: 100% to do). Some goes for the likes of em's...
I've tried vh and that works fine until the viewport height changes (so same problem as vw).
I read something about vb (about the parent block), but that doesn't seem to work? I believe it is still only theoretical.
I am aware of JS-options which could calculate the height of a parent and set it... But I feel like this is something CSS should be able to do and I'm missing a piece of a puzzle.
Could the answer lie in transforms?! or calc()?
UPDATE: Possible answer using SVGs? https://stackoverflow.com/a/51333267/224707

One possible solution I have found is using SVG's...
https://codepen.io/njt1982/pen/EpVeYw
Each column becomes this:
<div class="col border">
<div class="tile">
<svg viewBox="0 0 20 20">
<text x="50%" y="14" text-anchor="middle">A</text>
</svg>
</div>
</div>
Then we drop all notion of font-size and do this:
.tile svg {
position: absolute;
left: 0;
top: 0;
line-height: 0;
width: 100%;
height: 100%;
fill: #333;
}
Seems to scale pretty well - I have not, however, browser tested it...

Here you go:
https://codepen.io/sphism/pen/LBGmRm
Flexbox solution, scales with browser, works in both portrait and landscape, fonts scale, nice clean html, no svg's.
EDIT: added the size-* classes so you can easily change the grid size just by adding the class, eg .grid.size-4 would be a 4x4 grid.
html:
<div class="container">
<div class="grid size-7">
<div class="tile">A</div>
<div class="tile">B</div>
<div class="tile">C</div>
<div class="tile">D</div>
<div class="tile">E</div>
<div class="tile">F</div>
<div class="tile">G</div>
<div class="tile">H</div>
<div class="tile">A</div>
<div class="tile">B</div>
<div class="tile">C</div>
<div class="tile">D</div>
<div class="tile">E</div>
<div class="tile">F</div>
<div class="tile">G</div>
<div class="tile">H</div>
<div class="tile">A</div>
<div class="tile">B</div>
<div class="tile">C</div>
<div class="tile">D</div>
<div class="tile">E</div>
<div class="tile">F</div>
<div class="tile">G</div>
<div class="tile">H</div>
<div class="tile">A</div>
<div class="tile">B</div>
<div class="tile">C</div>
<div class="tile">D</div>
<div class="tile">E</div>
<div class="tile">F</div>
<div class="tile">G</div>
<div class="tile">H</div>
<div class="tile">A</div>
<div class="tile">B</div>
<div class="tile">C</div>
<div class="tile">D</div>
<div class="tile">E</div>
<div class="tile">F</div>
<div class="tile">G</div>
<div class="tile">H</div>
<div class="tile">A</div>
<div class="tile">B</div>
<div class="tile">C</div>
<div class="tile">D</div>
<div class="tile">E</div>
<div class="tile">F</div>
<div class="tile">G</div>
<div class="tile">H</div>
<div class="tile">A</div>
<div class="tile">B</div>
<div class="tile">C</div>
<div class="tile">D</div>
<div class="tile">E</div>
<div class="tile">F</div>
<div class="tile">G</div>
<div class="tile">H</div>
<div class="tile">A</div>
<div class="tile">B</div>
<div class="tile">C</div>
<div class="tile">D</div>
<div class="tile">E</div>
<div class="tile">F</div>
<div class="tile">G</div>
<div class="tile">H</div>
</div>
</div>
scss:
// 100 would have no space around it
// $gridSize: 90vw; // Works in portrait.
// $gridSize: 90vh; // Works in Landscape.
$gridSize: 90vMin; // Works in both.
.container {
// Full size of page
height: 100vh;
width: 100vw;
// Center the grid x and y
display: flex;
align-items: center;
justify-content: center;
}
.grid {
// Grid will center in container if you want a bit of space around it.
height: $gridSize;
width: $gridSize;
// This is how we make the grid
display: flex;
flex: 0 0 auto;
flex-wrap: wrap;
}
// Styles for all tiles
.tile {
display: block;
border: 1px solid gray;
text-align: center;
box-sizing: border-box;
}
// Number of rows and columns.
// $size: 8;
#for $size from 1 through 8 {
// eg 100/8
$tileSize: $gridSize / $size;
// Half th esize of the tile, or whatever you want.
$fontSize: $tileSize * 0.5;
.size-#{$size} {
.tile {
// Constrain the tiles to exact size we want.
width: $tileSize;
min-width: $tileSize;
max-width: $tileSize;
height: $tileSize;
min-height: $tileSize;
max-height: $tileSize;
flex-basis: $tileSize;
// Set fonts to same line height as tile, center them and set font size.
line-height: $tileSize;
font-size: $fontSize;
}
// Just hide extra divs so it renders properly.
$maxTiles: $size * $size + 1;
.tile:nth-child(n + #{$maxTiles}) {
display: none !important;
}
}
}

Related

How can I make this layout align like it should?

I'm trying to learn and practice flexbox by creating my own layouts. I'm not entirely sure why bottom row's col-1-of-2 won't align with the right col-1-of-2 in second row. Same with col-1-of-4.
Is grid-box better for this because you have more control of the column gap? I tried making the parent margin 5px and the children padding 5px and it was close but still not 100% aligned. I'm assuming we have to take the screen size into consideration as well?
.row {
display: flex;
}
.col {
display: flex;
flex-grow: 1;
border: 1px solid purple;
margin: 1rem;
}
.col-1-of-1 {
width: 100%;
justify-content: center;
background: lightblue;
}
.col-1-of-2 {
width: 50%;
justify-content: center;
background: orange;
}
.col-1-of-3 {
width: 33%;
justify-content: center;
background: lightgreen;
}
.col-1-of-4 {
width: 25%;
justify-content: center;
background: lightcoral;
}
<div class="row">
<div class="col col-1-of-1">
<p>col-1-of-1</p>
</div>
</div>
<div class="row">
<div class="col col-1-of-2">
<p>col-1-of-2</p>
</div>
<div class="col col-1-of-2">
<p>col-1-of-2</p>
</div>
</div>
<div class="row">
<div class="col col-1-of-4">
<p>col-1-of-4</p>
</div>
<div class="col col-1-of-4">
<p>col-1-of-4</p>
</div>
<div class="col col-1-of-4">
<p>col-1-of-4</p>
</div>
<div class="col col-1-of-4">
<p>col-1-of-4</p>
</div>
</div>
<div class="row">
<div class="col col-1-of-3">
<p>col-1-of-3</p>
</div>
<div class="col col-1-of-3">
<p>col-1-of-3</p>
</div>
<div class="col col-1-of-3">
<p>col-1-of-3</p>
</div>
</div>
<div class="row">
<div class="col col-1-of-4">
<p>col-1-of-4</p>
</div>
<div class="col col-1-of-4">
<p>col-1-of-4</p>
</div>
<div class="col col-1-of-2">
<p>col-1-of-2</p>
</div>
</div>
Is grid-box better for this because you have more control of the column gap?
You're getting close to understanding the nature of the problem in this statement. The problem is that you're taking a layout engine that was built with the goal of allowing elements to grow and shrink their size and space between them in order to get an organic fit, and expecting it to behave like a rigid, grid-like system.
Specifically, the issue arises when you add the margin to .col elements. For any given row, you are trying to fit the contents into 100% width, but the contents widths add up to 100% plus whatever margin exists for the number of elements you've included.
For instance-- the top row will be 100% plus 2rem (margin on either side). The next row is two elements of 50% width, which adds to 100%, plus the 4rem tacked on for the 1rem margins on either sides of the two elements.
flex takes care of this for you-- it massages the sizes and gaps in order to make everything fit nice and cleanly in that 100% width space. However, things get sticky when you start mixing the .col-1-of-<num> types and expecting them to line up nicely-- flex is doing its work to make sure they fit, which is coming at the cost of having them align.
That said, what you want is possible with flex. The solution below simply uses a calc() to make sure that the margins are considered when setting the width of the element-- instead of .col-1-of-1 being 100%, it is calc(100% - 2em), .col-1-of-2 becomes calc(50% - 2em), and so on.
There may be other ways to approach this using flex that would also work, possibly by playing around with the flex property, or the justify-content property; or you could check out grid. Good luck!
.row {
display: flex;
}
.col {
display: flex;
flex-grow: 1;
border: 1px solid purple;
margin: 1rem;
}
.col-1-of-1 {
width: calc(100% - 2rem);
justify-content: center;
background: lightblue;
}
.col-1-of-2 {
width: calc(50% - 2rem);
justify-content: center;
background: orange;
}
.col-1-of-3 {
width: calc(33% - 2rem);
justify-content: center;
background: lightgreen;
}
.col-1-of-4 {
width: calc(25% - 2rem);
justify-content: center;
background: lightcoral;
}
<div class="row">
<div class="col col-1-of-1">
<p>col-1-of-1</p>
</div>
</div>
<div class="row">
<div class="col col-1-of-2">
<p>col-1-of-2</p>
</div>
<div class="col col-1-of-2">
<p>col-1-of-2</p>
</div>
</div>
<div class="row">
<div class="col col-1-of-4">
<p>col-1-of-4</p>
</div>
<div class="col col-1-of-4">
<p>col-1-of-4</p>
</div>
<div class="col col-1-of-4">
<p>col-1-of-4</p>
</div>
<div class="col col-1-of-4">
<p>col-1-of-4</p>
</div>
</div>
<div class="row">
<div class="col col-1-of-3">
<p>col-1-of-3</p>
</div>
<div class="col col-1-of-3">
<p>col-1-of-3</p>
</div>
<div class="col col-1-of-3">
<p>col-1-of-3</p>
</div>
</div>
<div class="row">
<div class="col col-1-of-4">
<p>col-1-of-4</p>
</div>
<div class="col col-1-of-4">
<p>col-1-of-4</p>
</div>
<div class="col col-1-of-2">
<p>col-1-of-2</p>
</div>
</div>

Align vertically boxes with different height in Flexbox in a row

I am using Flexbox and I am trying to create something like this:
I want the three "parent" boxes to be vertically aligned within the row. Each box have different height.
In the snippet (Codepen is better in this case as there was a character limit in Stack) I am trying to replicate the first box as a start, the boxes float to the top. They are not vertically aligned:
.box, .box-first, .box-large, .box-nested, .box-row {
position: relative;
box-sizing: border-box;
min-height: 1rem;
margin-bottom: 0;
background: #007FFF;
border: 1px solid #FFF;
border-radius: 2px;
overflow: hidden;
text-align: center;
color: #fff;
}
.box-nested {
background: #036;
border-color: #007FFF;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/flexboxgrid/6.3.1/flexboxgrid.css" rel="stylesheet"/>
<div class="row"> <div class="col-xs-12"> <div class="box box-container"> <div class="row"> <div class="col-xs-12"> <div class="box-first box-container"> <div class="row"> <div class="col-xs-2"> <div class="box-nested"> <img style="width:30px; height:auto;" src="https://cdn0.iconfinder.com/data/icons/simplicity/512/dollar-256.png"/> </div></div><div class="col-xs-5"> <div class="box-nested"> <div class="col-xs-12"> <div class="box-nested">111 222</div><div class="box-nested">105,306</div></div></div></div><div class="col-xs-5"> <div class="box-nested"> <div class="col-xs-12"> <div class="box-nested"> <div class="col-xs-12"> <div class="box-nested">111</div><div class="box-nested">222</div></div></div><div class="box-nested"> <div class="col-xs-12"> <div class="box-nested">105,306</div></div></div></div></div></div></div></div></div></div></div></div></div>
When I tried adding the for the display: flex; align-items: center; in the CSS it messes up with the nested divs:
I am not that familiar with Flexbox and I have seen many different versions online that don't help.

Horizontal scrolling in SVG

JSFiddle
body {
background-color: #111111;
color: #ffffff;
/*max-width: 100%;*/
overflow-x: hidden;
}
.row {
max-width: 100rem;
}
.svgrow {
min-width: 70rem;
}
.svgrow svg {
overflow-x: auto;
}
I want to have this svg horizontal scrollable on small screens, without the body being horizontal scrollable. In addition to that I want only relative units to be used.
I already tried to put the overflow property in different positions, but I can't get it to work.
I use the foundation framework.
In order for the scrolling to happen, you have to give the container a fixed width. The contents (the SVG) needs to have a width that is greater than the container element. Usually that means giving it a specific width, because otherwise it will just resize to its container.
.svgrow {
max-width: 100vw;
overflow-x: auto;
}
.svgrow svg {
min-width: 70rem;
}
/* My CSS */
body {
overflow-x: hidden;
}
.row {
max-width: 100rem;
}
.svgrow {
max-width: 100vw;
overflow-x: auto;
}
.svgrow svg {
min-width: 70rem;
}
svg {
margin-bottom: 2.5em;
}
.off-canvas-toolbar {
position: fixed;
height: 100%;
width: 8%;
}
<div class="container">
<div class="off-canvas position-left" id="sidebar" data-off-canvas>
</div>
<div class="off-canvas-content" data-off-canvas-content>
<div class="off-canvas-toolbar">
<div class="custom-menu-icon" data-toggle="sidebar">
<i class="fa fa-bars">Icon</i>
</div>
</div>
<div class="row svgrow">
<div class="small-12 columns">
<h1>Title</h1>
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2000 1000">
<polygon points="0,1000 60,0 2000,0 2000,1000" fill="#fdedbc"></polygon>
<polygon points="70,1000 970,0 1800,1000" fill="#7c5b18"></polygon>
</svg>
</div>
</div>
<div class="row">
<div id="searchResult" class="small-12 columns" style="">
<h2 class="center">Search Results</h2>
<div class="small-12 medium-6 large-4 columns">
<div class="searchResult">
<div class="caption">
Test <span class="creator">by User</span>
</div>
</div>
</div>
<div class="small-12 medium-6 large-4 columns">
<div class="searchResult">
<div class="caption">
Test <span class="creator">by User</span>
</div>
</div>
</div>
<div class="small-12 medium-6 large-4 columns">
<div class="searchResult">
<div class="caption">
Test <span class="creator">by User</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

Two small align images beside a large image

I'm struggling on how I will code to create a two vertical images and is it possible to lessen the height of the larger image without lessen the width? because I need to fit it on col-md-8 any thoughts about this?
this is the image I need to make.
Click here
HTML and CSS code:
.img-big{ height: 100%;width: 100%; }
<div class="row col-md-8">
<img class="row img-big img-responsive" src="/assets/icons/people-crowd-child-kid-large.jpg"></div>
</div
the above code is what I've used to make the bigger image beside image 2 and 3. the dimension of the large image is 900x767
You can use the flexbox property to achieve what you want and set the image as background.
body, html {
margin: 0;
padding: 0;
color: white;
}
.container {
height: 767px;
display: flex;
}
.left {
background-image: url('http://i.imgur.com/AzeiaRY.jpg');
background-size: cover;
flex: 1;
}
.right {
display: flex;
flex-direction: column;
flex: 0 0 50%;
}
.one {
background-image: url('http://i.imgur.com/AzeiaRY.jpg');
background-size: cover;
flex: 50%;
}
.two {
background-image: url('http://i.imgur.com/AzeiaRY.jpg');
background-size: cover;
flex: 50%;
}
<div class="container">
<div class="left">Left image</div>
<div class="right">
<div class="one">First image</div>
<div class="two">Second image</div>
</div>
</div>
In Bootstrap 5, you can use d-grid gap-x. For example:
HTML
.content {
background-color: transparent;}
.content .left, .content .right {
float: left;}
.full-width-band-hd {
margin-top: -35px;}
.txt-yellow {
color: var(--bs-yellow);}
<section class="container-lg">
<div class="content row">
<h2 class="txt-yellow full-width-band-hd">Head</h2>
<!-- Left Side -->
<h6 class="text-yellow">H6 head</h6>
<h3 class="text-yellow">H3 head</h3>
</div>
<!-- style in content row will become a class later-->
<div class="content row" style="height: 642px;">
<div class="col-md-4 left d-grid gap-3">
<div class="">
<img src="image1" width="100%" height="auto" alt="fp1">
</div>
<div class="">
<img src="image2" width="100%" height="auto" alt="fp2">
</div>
</div>
<!-- End of Left Side -->
<div class="col-md-8 left">
<div class="">
<img src="image3" width="100%" height="auto" alt="fp3">
</div>
</div>
<!-- End of col-md-8 -->
</div><!-- content row -->
</section>
You should format your code like below:
<div class="row">
<div class="col-md-8">
<img class="img-big img-responsive" src="https://en.apkshki.com/storage/5/icon_5dcfce7f86906_5_w256.png"></div>
</div>
<div class="col-md-4">
<img src="https://en.apkshki.com/storage/5/icon_5dcfce7f86906_5_w256.png"></div>
<img src="https://en.apkshki.com/storage/5/icon_5dcfce7f86906_5_w256.png"></div>
</div>
</div>
As you can see the two images at the bottom in col-md-4 if you spread the width 100% the next image will drop below.
You shouldnt really have a class with both a row and a col-md in the class name. (See http://getbootstrap.com/css/)
With regards to reducing the height and not the width are you not able to crop the image down on Paint or Photoshop and upload the image with the correct height?

trying to center a div for mobile device/ zurb foundation

So, I'm trying to get this to display properly on mobile phone for the class 'circle-right right' div. Right now, instead of being centered, the circle-right class is displaying too far to the right instead of center. On desktop it displays correctly.
<div class="path-container">
<div class="row">
<div class="large-12 columns ">
</div>
</div>
<div class="row path-item">
<div class="large-7 push-5 columns">
<div id="img1" class="circle circle-left "></div>
</div>
<div class="large-5 pull-7 columns path-text left">
<h3 id="pstop1">Get in touch!</h3>
<a class="pathlinks" href="#" data-reveal-id="myModal">Get in touch>></a>
</div>
</div>
<div class="row path-item">
<div class="large-7 columns">
<div id="img2" class="circle circle-right right"></div>
</div>
<div class="large-5 columns path-text right">
<h3 id="pstop2">Give us feedback!</h3>
<p class="shadow">We're not happy unless your satisfied. During the process, we'll be in touch to make sure we're on the right track.</p>
Get in touch>>
</div>
This is most of the default css that comes with the foundation path template. Tried using media query to select the class and adjust the position, but it wont work. Here's a link to the template http://patterntap.com/code/responsive-timeline
css:
.path-container .path-item .circle.circle-right {
right: 100px;
}
.path-container {
text-align: center;
}
.path-container .circle {
top: 0;
right: 0;
left: 0;
float: none;
margin-bottom: 30px !important;
margin-top: 60px;
margin-left: auto;
margin-right: auto;
}