I am creating an Etch-A-Sketch project as part of The Odin Project's foundations course. I have created a 16x16 grid, and the amount of cells in the grid will change depending on the user's input to a prompt.
My problem is that the amount of cells in the columns will change, but not the amount of cells in the rows. This results in the etch-a-sketch pad being made up of rectangles rather than evenly placed squares.
For example: If the user enters "32", there will be 32 cells in each column. But still only 16 columns. I need the grid to be 32x32 instead of 32x16.
const container = document.querySelector("#container");
const buttonSize = document.querySelector("#gridsize");
const buttonRainbow = document.querySelector("#gridsize");
let cell = document.querySelectorAll('.cell');
let cellAmount = 16;
window.onload = createGrid(cellAmount);
cell.onmouseover = mouseOver();
// creates a 16x16 grid
function createGrid(e){
for (let i = 0; i < e*e; i++){
const div = document.createElement("div");
div.classList.add("cell");
container.appendChild(div);
}
}
// changes cell colors to black on mouseover
function mouseOver(){
let cell = document.querySelectorAll('.cell');
cell.forEach((cell) => {
cell.addEventListener('mouseover', function(){
cell.style.background = "black";
})
})
}
// resizes the grid and resets sketch
buttonSize.addEventListener('click', () => {
for (i = 0; i < cell.length; i++){
cell[i].style.removeProperty("black")
}
let userAmount = prompt("Select your pixel size (Default: 16)");
if (userAmount == ""){
userAmount == 16;
}
while (parseInt(userAmount) < 4 || parseInt(userAmount) > 100){
userAmount = prompt("Sorry, please enter a number between 4 and 100.");
}
cellAmount = parseInt(userAmount);
while (container.hasChildNodes()){
container.removeChild(container.firstChild);
}
createGrid(cellAmount);
mouseOver();
});
#container {
margin-top: 25px;
display: inline-grid;
grid-template-columns: repeat(16, 1fr);
grid-template-rows: auto;
border: 7.5px solid black;
border-radius: 10px;
height: 575px;
width: 575px;
box-sizing: border-box;
}
.cell {
border: 1px solid black;
box-sizing: border-box;
}
#title {
display: flex;
background-color: crimson;
justify-content: center;
width: 270px;
height: 72px;
margin-left: 815px;
margin-top: 50px;
border-style: solid aqua;
border-radius: 35px;
font-size: small;
}
#buttons {
display: flex;
justify-content: center;
gap: 75px;
margin-top: 40px;
}
#gridsize {
background: black;
color: white;
border: none;
width: 100px;
height: 30px;
font-size: large;
border-radius: 20px;
font-weight: bold;
}
#rainbow {
background: black;
color: white;
border: none;
width: 100px;
font-size: large;
font-weight: bold;
border-radius: 20px;
}
#tipmessage {
text-align: center;
margin-top: 40px;
}
html {
background-color: snow;
text-align: center;
font-family: Arial, Helvetica, sans-serif;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Etch-A-Sketch.</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="title">
<h1>Etch-A-Sketch. 🖍</h1>
</div>
<div id="buttons">
<button id="gridsize">Size</button>
<button id="rainbow">Rainbow</button>
</div>
<div id="container"></div>
<div id="tipmessage">
<h3><em>'We don't make mistakes, just happy little accidents' - Bob Ross</em></h3>
</div>
</body>
<script src="script.js" defer></script>
</html>
I have tried changing the CSS grid properties for #container however this has not solved the problem. I have inspected my JS but can't seem to figure out if the problem is coming from the JS, or the CSS.
For example, I tried changing my CSS Grid's columns and rows to "auto" but this completely ruined the grid.
The problem is coming from the CSS. This part:
#container{
...
grid-template-columns: repeat(16, 1fr);
...
}
Because the grid-template-columns amount is hard-coded into the style-sheet it will not change with the new grid size received from the user. If the amount of columns is set to, say 33 and then you edit grid-template-columns via browser tools to match 33 then the divs created will appear as squares.
As it is written there must be 16 columns in the grid and no more or less.
So when you call the function that creates the grid you have to edit the grid-template-columns attribute of #container so that the grid-template-columns of the container is updated along with the amount of cells in the grid.
function createGrid(e){
container.style.gridTemplateColumns = `repeat(${e},1fr)` // This will make the divs square
for (let i = 0; i < e*e; i++){
const div = document.createElement("div");
div.classList.add("cell");
container.appendChild(div);
}
}
This question already has an answer here:
css ::before attr() and unicode
(1 answer)
Closed 8 months ago.
I'm trying to change a Font Awesome icon on action using JS.
I'm implementing the icon through pseudo element ::before.
Assigning the icon through CSS using content:'\f0c2' displays the icon fine, but if I transfer the string through a dataset - content: attr(data-content), it just renders the string on the page.
How can I get it to work? Is there a better way to do it?
Here's a JSFiddle with all relevant code I've used.
const element = document.querySelector('.data');
const btn = document.querySelector('.btn');
const changeIcon = () => {
element.dataset.content = '\\f185';
}
btn.addEventListener('click', changeIcon);
.container {
display: grid;
place-items: center;
margin-top: 6rem;
font-family: sans-serif;
color: lightblue;
gap: 1rem;
}
.btn {
padding: 1em 2em;
background-color: lightblue;
color: white;
border-radius: 10px;
}
.btn:hover {
background-color: white;
color: lightblue;
border: 1px solid lightblue;
}
.icon-before::before {
display: inline-block;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
font: var(--fa-font-solid);
margin-right: 0.2em;
}
.string::before {
content: '\f0c2';
}
.data::before {
content: attr(data-content);
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<div class='container'>
<h2 class='element string icon-before'>
Added through string
</h2>
<h2 class=' element data icon-before' data-content="\f0c2">
Added through dataset
</h2>
<a class='btn'>Press Me</a>
</div>
const changeIcon = () => {
element.dataset.content = String.fromCharCode(0xf0c2);
}
im new to javascript so if my code isn't the best i apologise in advance! Im trying to display the tags when a certain name is clicked with the click event (eventListener), but I have no idea how! I tried writing the code how I want it, but now im stuck. I want the tags to be displayed in the aside 1 if the name is clicked. Any help is appreciated!
window.addEventListener('load', init);
const cardsContainer = document.querySelector("#cards")
const birdNames = ["Koolmees", "Specht", "kerkuil"]
const birdImages = ["https://www.natuurpunt.be/sites/default/files/styles/content-wide/public/koolmees_fr_van_bauwel.jpg?itok=arfFjeTb&c=312068de040ea85bb4eb43164e28b3b2", "https://www.buitenleven.nl/wp-content/uploads/2019/10/grote-bonte-specht.jpg", "https://www.vogelhuisjes.nl/media/wysiwyg/vogels-in-de-tuin/vogels-in-nederland/xkerkuil.jpg.pagespeed.ic.8a2v4rM0Z3.jpg"]
const birds = [
{ name: "Koolmees", image: "https://www.natuurpunt.be/sites/default/files/styles/content-wide/public/koolmees_fr_van_bauwel.jpg?itok=arfFjeTb&c=312068de040ea85bb4eb43164e28b3b2", tag:"rotterdam, koolmees, kleine vogel" },
{ name: "specht", image: "https://www.buitenleven.nl/wp-content/uploads/2019/10/grote-bonte-specht.jpg" },
{ name: "kerkuil", image: "https://www.vogelhuisjes.nl/media/wysiwyg/vogels-in-de-tuin/vogels-in-nederland/xkerkuil.jpg.pagespeed.ic.8a2v4rM0Z3.jpg" }
]
const Birdtags = ["rotterdam, koolmees, kleine vogel", "specht, nijmegen, kleine vogel", "uil, eindhoven, grote vogel, roofvogel"]
let Field;
let target;
function init()
{
//Click handler for every card
Field = document.getElementById('field');
Field.addEventListener('click', playingFieldClickHandler);
//starting
addCard();
//Listen to input of chosen name by user
let playForm = document.getElementById('form');
playForm.addEventListener('submit', formSubmitHandler);
}
function addCard(birdImage, birdName){
const cardDiv = document.createElement("flex-item")
cardDiv.classList.add("card")
cardsContainer.appendChild(cardDiv)
const img = document.createElement("img")
img.src = birdImage
cardDiv.appendChild(img)
const nameDiv = document.createElement("div")
nameDiv.innerText = birdName
cardDiv.appendChild(nameDiv)
}
function playingFieldClickHandler(e)
{
/** what do I put here???*/
}
function formSubmitHandler(e)
{
//Prevent default form submit
e.preventDefault();
//If the value is the right one, you won!
if (birdNames === "koolmees") {
/** display tags */
} else if (birdNames === "specht") {
/** display tags */
}
else if (birdNames === "kerkuil") {
/** display tags */
}
}
function addCards(){
for(let i = 0; i<birdNames.length; i++){
addCard(birdImages[i], birdNames[i])
}
}
addCards()
flex-container {
/* We first create a flex layout context */
display: flex;
/* Then we define the flow direction
and if we allow the items to wrap
* Remember this is the same as:
* flex-direction: row;
* flex-wrap: wrap;
*/
flex-flow: row wrap;
/* Then we define how is distributed the remaining space */
justify-content: space-around;
padding: 0;
margin: 0;
list-style: none;
}
flex-item {
background: #ABEBC6;
padding: 5px;
width: 250px;
height: 200px;
margin-top: 10px;
line-height: 50px;
color: black;
font-weight: bold;
font-size: 3em;
text-align: center;
}
nav {
display: flex;
flex-flow: row wrap;
justify-content: flex-end;
list-style: none;
margin: 0;
background: #A2D9CE;
}
nav a {
text-decoration: none;
display: block;
padding: 1em;
color: white;
}
nav a:hover {
background: #1565C0;
}
wrapper {
display: flex;
flex-flow: row wrap;
font-weight: bold;
text-align: center;
}
wrapper > * {
padding: 10px;
flex: 1 100%;
}
header {
background: #DAF7A6;
}
footer {
background: #28B463;
}
main {
text-align: left;
background: #A2D9CE;
}
aside {
background: #28B463;
}
#media all and (min-width: 600px) {
.aside { flex: 1 0 0; }
}
#media all and (min-width: 800px) {
main { flex: 3 0px; }
aside { order: 1; }
main { order: 2; }
footer { order: 3; }
}
body {
width: 100%;
}
#media all and (max-width: 800px) {
nav {
justify-content: space-around;
}
}
#media all and (max-width: 600px) {
nav {
flex-flow: column wrap;
padding: 0;
}
nav a {
text-align: center;
padding: 10px;
border-top: 1px solid rgba(255, 255, 255,0.3);
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
nav li:last-of-type a {
border-bottom: none;
}
}
p1 {
font-family: "Times New Roman", Times, serif;
font-size: 40px;
}
p2 {
font-family: Arial, Helvetica, sans-serif;
}
p3 {
font-family: "Lucida Console", "Courier New", monospace;
}
img {
width: 250px;
height: 150px;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="css/style2.css">
<title>Test week 2</title>
</head>
<body>
<wrapper>
<header><p1>Vogel magazine voor vogelspotters!</p1></header>
<main>
<flex-container id="cards">
</flex-container>
</main>
<aside>Aside 1</aside>
<footer>Footer</footer>
</wrapper>
<script src="js/DOM4.js"></script>
</body>
</html>
Admittedly I modified the HTML structure a little as there were errors with the markup, possibly screwed up your CSS and changed the multiple source arrays for a single Object literal but you should be able to adapt the following to suit your needs. I made this do what I thought you were trying to do.
window.addEventListener('load', init);
const cardsContainer = document.querySelector('#cards');
const aside = document.querySelector('#wrapper aside');
/*
If you re-structure your data into a single Object literal
you will, I think, find less issues with maintaining several
arrays and ensuring they all have the same number of items etc
This sort of data structure can easily be created in the form of
JSON data from a database query!
Each sub-object ( aka - Bird ) can be extended easily to have additional
properties quite easily, especially if database driven.
If you remove, from the img src, the `scheme` you can generally get the image to download
using the same scheme as the parent page. One day ALL websites will be hosted on SSL
so this will be redundant but in the meantime this might help prevent warnings
*/
const birds={
'Koolmees':{
src:'//www.natuurpunt.be/sites/default/files/styles/content-wide/public/koolmees_fr_van_bauwel.jpg',
tags:'rotterdam, koolmees, kleine vogel'
},
'Specht':{
src:'//www.buitenleven.nl/wp-content/uploads/2019/10/grote-bonte-specht.jpg',
tags:'specht, nijmegen, kleine vogel'
},
'kerkuil':{
src:'//www.vogelhuisjes.nl/media/wysiwyg/vogels-in-de-tuin/vogels-in-nederland/xkerkuil.jpg.pagespeed.ic.8a2v4rM0Z3.jpg',
tags:'uil, eindhoven, grote vogel, roofvogel'
}
};
/*
It is unclear from the code what you hope to do with the `submithandler`
especially given that there is no form ( or was no form ) so I guessed
that you were hoping to do something similar to what this method does..
if there is no `figcaption` below the image it will add the caption and
assign the `tags` text which is assigned to the image as a dataset attribute
*/
const clickhandler=function(e){
let fig=e.target.parentNode.querySelector('figcaption');
if( fig==null ){
fig=document.createElement('figcaption');
fig.textContent=this.dataset.tags
e.target.parentNode.appendChild( fig );
}else{
e.target.parentNode.removeChild(fig)
}
aside.textContent=fig==null ? '' : this.dataset.tags;
}
function init(){
/* the first does nothing, the 2nd has errors and the 3rd is incomplete...
//Click handler for every card
document.getElementById('field').addEventListener('click', playingFieldClickHandler);
//starting
//addCard(src,name,desc);
//Listen to input of chosen name by user
document.getElementById('form').addEventListener('submit', formSubmitHandler);
*/
document.getElementById('cards').querySelectorAll('.card').forEach( card => {
card.addEventListener('click',clickhandler );
});
}
function addCard(birdImage, birdName, birdTags){// now takes 3 arguments
let item = document.createElement('flex-item');
item.classList.add('card');
item.dataset.tags=birdTags; //assign the tags as a dataset atttribute
cardsContainer.appendChild(item)
let img = document.createElement('img')
img.src = birdImage;
img.title=birdTags; // tags also assigned for the img title
item.appendChild(img)
let name = document.createElement('div')
name.innerText = birdName
item.appendChild(name)
}
/**********************************************************
Unclear how these two functions are really to be used
- unchanged
*/
function playingFieldClickHandler(e)
{
/** what do I put here???*/
}
function formSubmitHandler(e)
{
//Prevent default form submit
e.preventDefault();
//If the value is the right one, you won!
if (birdNames === "koolmees") {
/** display tags */
} else if (birdNames === "specht") {
/** display tags */
}
else if (birdNames === "kerkuil") {
/** display tags */
}
}
/*
With the new data structure a new approach to iterating through the
data is required. Using the `object.keys` method allows us to quickly
iterate through each sub-object. The `key` is the bird name.
*/
function addCards(){
Object.keys( birds ).forEach( key => {
let bird=birds[ key ];
addCard( bird.src, key, bird.tags )
})
}
addCards()
body{
width:100%;
height:100vh;
margin:0;
padding:0;
box-sizing:border-box;
}
flex-container {
/* We first create a flex layout context */
display: flex;
/* Then we define the flow direction
* and if we allow the items to wrap
* Remember this is the same as:
* flex-direction: row;
* flex-wrap: wrap;
*/
flex-flow: row wrap;
flex:10;
margin:auto;
/* Then we define how is distributed the remaining space */
justify-content: space-around;
padding: 0;
list-style: none;
}
flex-container figcaption{
font-size:1rem;
line-height:1rem;
color:white;
}
flex-item {
background: #ABEBC6;
padding: 5px;
width: 250px;
min-height: 200px;
max-height:250px;
margin-top: 10px;
line-height: 50px;
color: black;
font-weight: bold;
font-size: 3em;
text-align: center;
cursor:pointer;
}
nav {
display: flex;
flex-flow: row wrap;
justify-content: flex-end;
list-style: none;
margin: 0;
background: #A2D9CE;
}
nav a {
text-decoration: none;
display: block;
padding: 1em;
color: white;
}
nav a:hover {
background: #1565C0;
}
#wrapper {
display: flex;
flex:10;
flex-direction:column;
font-weight: bold;
text-align: center;
min-height:100vh;
margin:auto;
padding:0;
}
#wrapper > * {
padding: 10px;
flex: 1 100%;
}
header {
background: #DAF7A6;
flex:2!important;
order:1;
display:flex;
align-items:center;
justify-content:center;
}
footer {
background: #28B463;
flex:1!important;
order:3;
display:flex;
align-items:center;
justify-content:center;
}
main {
text-align: left;
background: #A2D9CE;
flex:50!important;
order:2;
}
aside {
display:flex;
align-items:center;
justify-content:center;
background: #28B463;
flex:1;
margin:auto;
max-height:2rem;
width:100%;
padding:0!important;
}
#media all and (min-width: 600px) {
.aside { flex: 1 0 0; }
}
#media all and (min-width: 800px) {
main { flex: 3 0px; }
aside { order: 1; }
main { order: 2; }
footer { order: 3; }
}
#media all and (max-width: 800px) {
nav {
justify-content: space-around;
}
}
#media all and (max-width: 600px) {
nav {
flex-flow: column wrap;
padding: 0;
}
nav a {
text-align: center;
padding: 10px;
border-top: 1px solid rgba(255, 255, 255,0.3);
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
nav li:last-of-type a {
border-bottom: none;
}
}
p1 {
font-family: "Times New Roman", Times, serif;
font-size: 40px;
}
p2 {
font-family: Arial, Helvetica, sans-serif;
}
p3 {
font-family: "Lucida Console", "Courier New", monospace;
}
img {
width: 250px;
height: 150px;
}
<div id='wrapper'><!-- There is no HTML element `wrapper` -->
<header><p1>Vogel magazine voor vogelspotters!</p1></header>
<main>
<flex-container id="cards"></flex-container><!-- unusual to assign custom elements without accompanying javascript/css -->
</main>
<aside>Aside 1</aside>
<footer>Footer</footer>
</div>
First of all I've been browsing for a while trying to avoid opening yet another "div not expanding" question, but I haven't found a solution yet.
I'm building a web reporting tool with SCOM data I get via powershell scripting. We don't have access to SCOM reporting tools, that's why I have to build a website by hand.
<!DOCTYPE html>
<html lang="en">
<head>
<title>SCOM Reporting</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href=".\style\style.css">
</head>
<body>
<div class="header">
<h1 id="header">SCOM WEB REPORTING TOOL</h1>
</div>
<div class="navbar">
Home
PROD
ABN
EDEN
</div>
<div class="div_report" id="divReport">
</div>
<script src=".\js\scripts.js"></script>
</body>
</html>
My css
/* Style the body */
body, html {
font-family: Arial, Helvetica, sans-serif;
margin: 0;
padding: 0;
overflow: hidden;
height:100%;
width: 100%;
min-height:100%;
}
/* Header/logo Title */
.header {
padding: 20px;
text-align: center;
background: DarkSeaGreen;
color: white;
}
/* Increase the font size of the heading */
.header h1 {
font-size: 60px;
}
.navbar {
overflow: hidden;
text-align: center;
background-color: DimGrey;
}
.navbar a {
float: left;
font-size: 16px;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.navbar a:hover {
background-color: #555;
}
/* Main column */
.main {
padding: 20px;
}
.div_report {
width: auto;
height: 500px;
border:1px solid #c0c0c0;
overflow: hidden;
}
And my js
function changeGuay(id){
changeHeader(id);
changeContent(id);
}
function changeHeader(id) {
if (id === "HOME") {
document.getElementById("header").innerText = "SCOM WEB REPORTING TOOL";
} else {
document.getElementById("header").innerText = id + " REPORTING";
}
}
function changeContent(id){
if (id === "HOME"){
document.getElementById("divReport").innerHTML = '<object type="text/html" data="about:blank"></object>';
} else {
document.getElementById("divReport").innerHTML = '<object type="text/html" data="'+id+'.html"></object>';
}
}
The div content changes to whatever I want as I desire but the content it shows doesn't expand at all, it remains as a small square. I'd like it to fill the rest of the empty space of the page, with the vertical scroll since the data I'm pulling from SCOM is long.
Live example here : https://codepen.io/bala421/pen/wvMqKwy
The problem is not the div, it is that you are using an <object> </object>. Select the object and apply the styles to it. I used this
object{
width: 100%;
height: 100%;
}
for basic grid layout i suggest bootstrap.
but anyway,
.div_report {
width: 100%;
}
So I like this, where it wraps but yet the boxes all align on both sides and fill the whole space.
<head>
<style>
* {
padding: 0px;
margin: 0px;
text-transform: none;
font-style: normal;
}
p {
display: flex;
flex-wrap: wrap;
width: 200px;
}
i {
flex: 1;
padding: 5px;
margin: 2px;
background: #ddd;
text-align: center;
}
</style>
</head>
<body>
<p>
<i>foo</i><i>hello</i><i>congratulations</i><i>forward</i><i>interesting</i><i>place</i><i>walk</i><i>to</i><i>anyplace</i><i>next</i><i>sophisticationism</i>
</p>
</body>
Using a mix of small and large words, it somehow figures out how to optimally lay them out so it fills the space completely.
What I would like to do now is, instead of having each box be a dynamically width'd rectangle, I would like for the boxes to "snap to a grid" so to speak. That is, imagine there was a grid of squares that stretched across each row. Sort of like this (which I've completely hardcoded, just for the sake of demonstrating what it looks like. In reality this is what my question is about, how to make this automatic using FlexBox).
<head>
<style>
* {
padding: 0px;
margin: 0px;
text-transform: none;
font-style: normal;
}
p {
display: flex;
flex-wrap: wrap;
width: 220px;
}
i {
width: 50px;
height: 50px;
padding: 5px;
margin: 2px;
background: #ddd;
text-align: center;
}
.l {
width: 114px;
}
</style>
</head>
<body>
<p>
<i>a</i><i>a</i><i>a</i><i>a</i><i class='l'>long</i><i>a</i><i class='l'>long</i><i>a</i><i class='l'>a</i><i class='l'>long</i><i>a</i><i>a</i><i>a</i><i>a</i><i>a</i><i>a</i><i>a</i>
</p>
</body>
So to rephrase, my question is how to cause flowing text (like the words in the images above) layout so (a) it fills each row, and (b) each box is a multiple of a square. That is, it snaps to the grid of a square, weather it's 1, 2, 3+ squares, rather than being 2.5 squares or 1.2345 squares or something. It always snaps to a whole block. It does this by first looking at the longer words, and calculating how many blocks it will take up. Then it stretches any shorter blocks (like the one letter "a" in the example above) so as to fill the blank space.
Wondering how this could be done with FlexBox or otherwise with CSS.
Try (I use split 1-3 words depends on length from here )
function show(n) {
text.innerHTML = '<p>' + split(text.innerText,n).map(line=> {
if(line.length==2 && line[0].length<n && line[1].length<n) {
// case for two short words
return `<i class='long'>${line[0]}</i><i class='short'>${line[1]}</i>`
} else {
return line.map(w=>`<i class='${w.length<9 ?'short':'long'}'>${w}</i>`).join('')
}
}).join('') + '</p>';
}
function split(str,n) {
let z=0, b=[], r=[], w=str.split(' ');
let s = w.map(v => v.length < n ? 1 : 2);
s.map((v,i)=>(
z+v>=4 ? (r.push(b),z=0,b=[]) : 0,
z+=v, b.push(w[i])
))
return b.length ? r.concat([b]) : r;
}
show(9) // 9 is min number of letters for long words;
.short {
flex-basis: 64px;
flex-grow: 1
}
.long {
flex-basis: 140px;
flex-grow: 2
}
* {
padding: 0px;
margin: 0px;
text-transform: none;
font-style: normal;
}
p {
display: flex;
flex-wrap: wrap;
width: 260px;
}
i {
flex: 1;
padding: 5px;
margin: 2px;
background: #ddd;
text-align: center;
}
<div id="text">a aaa foo hello congratulations forward interesting place walk to anyplace next sophisticationism aa bb cccccccccc ddd</div>