Aligning key colon value data in css without using HTML table? - html

I have the following data that I want to show.
Ideally I want the keys and values left aligned, separated with colons in the middle.
I want the result to be like the following:
key1 : value1
key2 : value2
keyAbc: Value Abc
key_N : value N
And not like the following:
key1: value1
key2: value2
keyAbc: Value Abc
key_N: value N
How to do this in CSS or SCSS, and not using HTML table?

You can use grid, making the columns take on the max width of content.
This snippet adds the colons in a pseudo element as they seem to be just a visual clue rather than part of the data.
Of course you will want probably to add some padding to suit your particular requirements.
.table {
display: grid;
grid-template-columns: max-content max-content;
}
.table > *:nth-child(even)::before {
content: ":";
}
<div class="table">
<div>key1</div>
<div>value1</div>
<div>key2222222</div>
<div>value2</div>
<div>key3</div>
<div>value3</div>
</div>

Just use the inline-block and make sure the children of the main DIV gets that too and it will automatically resize based on widest width, much like table. No need for flex.
.inline-block {
display: inline-block;
}
.inline-block > div {
margin: 2px;
padding: 1px;
}
<div class="inline-block">
<div>key1</div>
<div>keykey2</div>
<div>key3</div>
</div>
<div class="inline-block">
<div>:</div>
<div>:</div>
<div>:</div>
</div>
<div class="inline-block">
<div>value1</div>
<div>value2</div>
<div>Value3</div>
</div>

If you're using div structure, you can use display: flex and could do something like this:
.css-table {
display: flex;
}
.key {
width: 10%;
}
.val::before {
content: ': ';
}
<div class="css-table">
<div class="key">key1</div>
<div class="val">value1</div>
</div>
<div class="css-table">
<div class="key">key2111</div>
<div class="val">value2</div>
</div>
<div class="css-table">
<div class="key">key3</div>
<div class="val">value3</div>
</div>
<div class="css-table">
<div class="key">key4</div>
<div class="val">value4</div>
</div>
If you don't want to specify width, you'll need use JavaScript to calculate the width and apply it inline.
let maxWidth = 0;
// Calculate maxWidth
document.querySelectorAll('.css-table').forEach(function(cssTableEl) {
cssTableEl.querySelectorAll('.key').forEach(function(keyEl) {
let currWidth = keyEl.clientWidth;
if (currWidth > maxWidth) {
maxWidth = currWidth;
}
});
});
// Apply maxWidth
document.querySelectorAll('.css-table').forEach(function(cssTableEl) {
cssTableEl.querySelectorAll('.key').forEach(function(keyEl) {
keyEl.style.width = maxWidth + 'px';
});
});
.css-table {
display: flex;
}
.val::before {
content: ': ';
}
<div class="css-table">
<div class="key">key1</div>
<div class="val">value1</div>
</div>
<div class="css-table">
<div class="key">key2111</div>
<div class="val">value2</div>
</div>
<div class="css-table">
<div class="key">key3</div>
<div class="val">value3</div>
</div>
<div class="css-table">
<div class="key">key4</div>
<div class="val">value4</div>
</div>

Related

Calculate dynamically width of elements

I have array of elements that I want to display, and I want to create this all tiles in same width, and make div 100% width. (In this code the tile sizes are different). Any help is much appreciated.
<div class="summaryArea" align="center">
<div *ngFor="let item of getSummery()">
<kendo-tilelayout [rowHeight]="200" [resizable]="true">
<kendo-tilelayout-item>
<kendo-tilelayout-item-body align="center">
<div class="summary" align="center">
<h4>{{item.amount}}</h4>
<div *ngIf="item.status == 'up'"><span class="k-icon k-i-arrow-60-up k-icon-md" style="color:green"></span></div>
<div *ngIf="item.status == 'down'"><span class="k-icon k-i-arrow-60-down k-icon-md" style="color:red"></span></div>
</div>
<br />
<div>{{item.name}}</div>
<hr />
<div>{{item.Description}} </div>
</kendo-tilelayout-item-body>
</kendo-tilelayout-item>
</kendo-tilelayout>
</div>
</div>
This is my CSS
.summary {
display:inline-flex;
}
.summaryArea {
width:fit-content;
font-size:medium;
display: flex;
}
I tried like this but this not works
<kendo-tilelayout-item [width] ="calculatewidth(getSummery().length)">
Ts file
public calculatewidth(length) {
return 100 / length+'%';
}
what if the width in the .summaryArea area is changed to width : 100%? is the result what you want?
I did it using following code. Thanks All for your effort
<div class="summaryArea">
<div *ngFor="let item of getSummery()" [style.width]="calculatewidth(getSummery().length)">
<kendo-tilelayout [rowHeight]="170">
<kendo-tilelayout-item>
<kendo-tilelayout-item-body align="center">
//content
</kendo-tilelayout-item-body>
</kendo-tilelayout-item>
</kendo-tilelayout>
</div>
</div>
Css
.summaryArea {
width:100%;
font-size:medium;
display: flex;
}
ts
public calculatewidth(length) {
return 100 / length + '%';
}
try by using 25% each because it is 4 box

Animate div's height with nested divs

Here is the snippet: https://jsfiddle.net/wc48jvgt/69/
I have a horizontally shaped div #cleaning_card_1, which has embedded divs which act like borders and vertical div #cleaning_card_right_1 with a nested div #cleaning_card_right_content_1. Inside the last div I have multiple divs which amount is dynamic. What I want to achieve is #cleaning_card_right_1 acting like a dropdown menu. I have a simple function to achieve that:
function maximizeCleaningCard () {
var cleaning_card_number = $(this).attr('number')
$(this).animate({width: '97%'}, 200, function () {
$('#cleaning_card_right_' + cleaning_card_number).removeClass('cleaning_card_right').addClass('cleaning_card_right_maximized')
$('#cleaning_card_right_' + cleaning_card_number).animate({height: 400}, 400)
$('#cleaning_card_right_content_' + cleaning_card_number).animate({height: 400 - 80}, 400)
$('#cleaning_card_right_left_border_1, #cleaning_card_right_right_border_1').animate({height: 400 - 80}, 400)
})
}
$('.cleaning_card').click(maximizeCleaningCard)
Animation is properly run on #cleaning_card_1 and border divs, however the #cleaning_card_right_content_1 is not animated at all. It just pops up there and thats it. If I'll remove nested items out of it, animation will properly work. I think that the problem is that div's height is not equal to 0 due to nested elements, but most likely I am mistaken. How to overcome this issue?
I noticed you are animated multiple divs to get the simultaneous vertical animate. You could streamline your div layout to get the same effect by just using 2 animates to complete the sequence.
I've removed all the unnecessary divs and used more practical css to get the same effect. Might not be perfect for your final use but may get you on the right track.
I've also added a minimizing sequence using the class .maximized to tell what state the cleaning card is in, and which sequence to run.
Here is a fiddle too https://jsfiddle.net/joshmoto/0ynrm1ts/2/
See comments in my script to see what is happening...
// maximize cleaning card
function maximizeCleaningCard() {
// store current clicked cleaning card variable for later use in animate
let cleaningCard = this;
// set cleaning card right element variable
let cleaningCardRight = $('.cleaning_card_right', cleaningCard);
// check we actually have a cleaning card right
if($(cleaningCardRight).length) {
// set the cleaning card right content variable
let cleaningCardRightContent = $('.cleaning_card_right_content', cleaningCardRight);
// if cleaning card has maximized class
if($(cleaningCard).hasClass('maximized')) {
// remove the maximized class
$(cleaningCard).removeClass('maximized');
// animate cleaning card right first to reverse sequence
$(cleaningCardRight).animate({
height: '0px'
}, 500, function() {
// when cleaning card right is fully closed
// animate cleaning card to finish the closing sequence
$(cleaningCard).animate({
width: '70%'
}, 500 );
});
// else if cleaning card does not have maximized class
} else {
// add the maximized class
$(cleaningCard).addClass('maximized');
// animate cleaning card width to 100%
$(cleaningCard).animate({
width: '100%'
}, 500, function() {
// when cleaning card is fully open
// animate cleaning card height to the cleaning card right content
$(cleaningCardRight).animate({
height: $(cleaningCardRightContent).outerHeight()
}, 500 );
});
}
}
}
// when cleaning card is clicked
$(document).on('click','.cleaning_card', maximizeCleaningCard );
BODY {
padding: 15px;
margin: 0;
}
.cleaning_card {
position: relative;
width: 70%;
border: 1px solid black;
height: 80px;
font-size: 15px;
overflow: visible;
margin-bottom: 15px;
}
.cleaning_card:hover {
cursor: pointer;
}
.cleaning_card_right {
position: absolute;
width: 25%;
height: 0;
background-color: white;
border-bottom: 1px solid black;
border-left: 1px solid black;
border-right: 1px solid black;
overflow: hidden;
top: 100%;
right: -1px;
}
.cleaning_card_right_content {
position: relative;
padding: 5px;
overflow: hidden;
}
.cleaning_card_right_content_item {
position: relative;
background-color: cornsilk;
}
<div id="cleaning_card_1" class="cleaning_card">
<div class="cleaning_card_right">
<div class="cleaning_card_right_content">
<div class="cleaning_card_right_content_item">
<div class="cleaning_card_right_category"> Standard </div>
<div class="cleaning_card_right_value"> 1 </div>
</div>
<div class="cleaning_card_right_content_item">
<div class="cleaning_card_right_category"> Junior Suite </div>
<div class="cleaning_card_right_value"> 2 </div>
</div>
<div class="cleaning_card_right_content_item">
<div class="cleaning_card_right_category"> Lux </div>
<div class="cleaning_card_right_value"> 3 </div>
</div>
</div>
</div>
</div>
<div id="cleaning_card_2" class="cleaning_card">
<div class="cleaning_card_right">
<div class="cleaning_card_right_content">
<div class="cleaning_card_right_content_item">
<div class="cleaning_card_right_category"> Standard </div>
<div class="cleaning_card_right_value"> 1 </div>
</div>
<div class="cleaning_card_right_content_item">
<div class="cleaning_card_right_category"> Junior Suite </div>
<div class="cleaning_card_right_value"> 2 </div>
</div>
<div class="cleaning_card_right_content_item">
<div class="cleaning_card_right_category"> Lux </div>
<div class="cleaning_card_right_value"> 3 </div>
</div>
</div>
</div>
</div>
<div id="cleaning_card_3" class="cleaning_card">
<div class="cleaning_card_right">
<div class="cleaning_card_right_content">
<div class="cleaning_card_right_content_item">
<div class="cleaning_card_right_category"> Standard </div>
<div class="cleaning_card_right_value"> 1 </div>
</div>
<div class="cleaning_card_right_content_item">
<div class="cleaning_card_right_category"> Junior Suite </div>
<div class="cleaning_card_right_value"> 2 </div>
</div>
<div class="cleaning_card_right_content_item">
<div class="cleaning_card_right_category"> Lux </div>
<div class="cleaning_card_right_value"> 3 </div>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Understanding CSS selectors. Hover to show information from another div [duplicate]

This question already has answers here:
Is there a CSS parent selector?
(33 answers)
Closed 2 years ago.
I have a setup for displaying information as the user hovers over a specific element. When the specific element is hovered over, the information will appear in an adjacent div depending on which div the user hovers over. Here's the HTML...
#emp-node:hover+#emp-details {
opacity: 1;
}
.node-details {
opacity: 0;
}
<div class="half interactions">
<div id="nodes">
<div id="emp-node" class="node">EMPATHY</div>
<div id="def-node" class="node">DEFINE</div>
<div id="id-node" class="node">IDEATE</div>
<div id="por-node" class="node">PROTOTYPE</div>
<div id="test-node" class="node">TESTING</div>
</div>
<div id="node-text">
<div id="emp-details" class="node-details">1</div>
<div id="def-details" class="node-details">2</div>
<div id="id-details" class="node-details">3</div>
<div id="por-details" class="node-details">4</div>
<div id="test-details" class="node-details">5</div>
</div>
</div>
The node-details are set to an opacity of 0. When I hover over emp-node I would like emp-details to show, and the same pattern for the other divs. Here's the CSS...
#emp-node:hover + #emp-details { opacity: 1; }
I believe my issue is with the selector. I know that I need to use one but I've tried them all to no avail. Can some help me figure out how to get this to work properly? Do I need to restructure my HTML or is there a solution?
Thanks is advance.
Keep in mind CSS can take you just part of the way, for example there is no parent selectors in CSS yet, you can not walk back. For stuff like that there is JS.
So for you its restructure HTML, for example you simply make them siblings, to be on same level at least:
#emp-node:hover~#emp-details {
opacity: 1;
}
#def-node:hover~#def-details {
opacity: 1;
}
#id-node:hover~#id-details {
opacity: 1;
}
#test-node:hover~#test-details {
opacity: 1;
}
.node-details {
opacity: 0;
}
<div class="half interactions">
<div id="nodes">
<div id="emp-node" class="node">EMPATHY</div>
<div id="def-node" class="node">DEFINE</div>
<div id="id-node" class="node">IDEATE</div>
<div id="por-node" class="node">PROTOTYPE</div>
<div id="test-node" class="node">TESTING</div>
<div id="emp-details" class="node-details">1</div>
<div id="def-details" class="node-details">2</div>
<div id="id-details" class="node-details">3</div>
<div id="por-details" class="node-details">4</div>
<div id="test-details" class="node-details">5</div>
</div>
Or javascript:
document.querySelectorAll("#nodes > .node").forEach(node => {
node.addEventListener("mouseover", function(event) {
let id = this.id.split("-")
//get ids
document.querySelectorAll("#node-text > .node-details").forEach(details => {
details.style.opacity = 0;
});
//on every hover set all to opacity 0
document.querySelector("#node-text > div[id^='" + id[0] + "']").style.opacity = 1;
});
//set the one that id bigins with id of hover element opacity 1
});
document.querySelectorAll("#nodes > .node").forEach(node => {
node.addEventListener("mouseover", function(event) {
let id = this.id.split("-")
document.querySelectorAll("#node-text > .node-details").forEach(details => {
details.style.opacity = 0;
});
document.querySelector("#node-text > div[id^='" + id[0] + "']").style.opacity = 1;
});
});
.node-details {
opacity: 0;
}
<div class="half interactions">
<div id="nodes">
<div id="emp-node" class="node">EMPATHY</div>
<div id="def-node" class="node">DEFINE</div>
<div id="id-node" class="node">IDEATE</div>
<div id="por-node" class="node">PROTOTYPE</div>
<div id="test-node" class="node">TESTING</div>
</div>
<div id="node-text">
<div id="emp-details" class="node-details">1</div>
<div id="def-details" class="node-details">2</div>
<div id="id-details" class="node-details">3</div>
<div id="por-details" class="node-details">4</div>
<div id="test-details" class="node-details">5</div>
</div>
</div>
Useful topic:
Is there a CSS parent selector?
You can achieve your needs by removing the 2 div wrappers id nodes and node-text as the below :
Html`
<div class="half interactions">
<div id="emp-node"classs="node">EMPATHY</div>
<div id="def-node" class="node">DEFINE</div>
<div id="id-node" class="node">IDEATE</div>
<div id="por-node" class="node">PROTOTYPE</div>
<div id="test-node" class="node">TESTING</div>
<div id="emp-details" class="node-details">1</div>
<div id="def-details" class="node-details">2</div>
<div id="id-details" class="node-details">3</div>
<div id="por-details" class="node-details">4</div>
<div id="test-details" class="node-details">5</div>
</div>
Css
#emp-node:hover ~ #emp-details {
opacity: 1;
}
.node-details {
opacity: 0;
}
Codepen https://codepen.io/ahamdan/pen/gOMaeNv

bulma level inside box overflowing

I am having trouble trying to have a responsive grid of 3 boxes with some aligned content inside using the library Bulma. I would like to make it work still maintaining the level inside a box if possible.
Any help would be appreciated.
This is the result I expect:
But when decreasing the width, it breaks:
This is the code I am using:
<div className="columns sub">
{this.props.options.map(option => (
<div className="column is-one-third" key={option.id}>
<div
name={option.id}
className={
`box ` +
(this.props.optionToBeChosen === option.id
? "box-is-active"
: "")
}
onClick={() => this.props.onClick(option.id)}
>
<div className="level is-mobile">
<div className="level-item level-left">
<div>
<p className="box-text-title">{option.title}</p>
<p className="box-text-small">{option.description}</p>
<p className="box-text-small">{option.description2}</p>
</div>
</div>
<div className="level-item level-right has-text-right">
<div>
<p className="box-text-demo">{option.cta}</p>
</div>
</div>
</div>
</div>
</div>
))}
</div>
The Bulma levels are explicitly told not to shrink
.level-left, .level-right {
flex-basis: auto;
flex-grow: 0;
flex-shrink: 0;
}
You'll have to override that to get the levels to not break out of the .box elements.
Rather than overriding ALL level items, I suggest you add a custom class to those levels that you want to be able to shrink.
Something like
<div class="level is-mobile level-is-shrinkable">
Level items here...
</div>
<style>
.level-is-shrinkable .level-left,
.level-is-shrinkable .level-right {
flex-shrink: 1;
}
</style>
In my case, I had to add a third styling condition for centered level-item elements:
.level-is-shrinkable .level-left,
.level-is-shrinkable .level-item,
.level-is-shrinkable .level-right {
flex-shrink: 1;
}
Many thanks to just-a-web-designer for his|her answer.

First-child changes multiple nested divs CSS

I am having some problem with the first-child and nth-child function in CSS. I have some divs structured like this:
<div class = container>
<div id = 456, class = item>
<div id = header_123, class = item_header>
<div class = text_container>
<div class="header_span">This is Item 456</div>
</div>
</div>
</div>
<div id = 789, class = item>
<div id = header_124, class = item_header>
<div class = text_container>
<div class="header_span">This is Item 789</div>
</div>
</div>
</div>
<div id = 123, class = item>
<div id = header_125, class = item_header>
<div class = text_container>
<div class="header_span">This is Item 123</div>
</div>
</div>
</div>
</div>
I want to change the left-margin of the first div with class item. I use
.item div:first-child{
margin-left: 30px;
}
This changes the div with id 456's margin, but also the margin of all the text_container and header_span. This is not what I want; what am I doing wrong?
Use the immediate child selector >:
.item > div:first-child {
margin-left: 30px;
}
Note: And I could see that you are not wrapping your attributes inside " and also an id cannot start with a number.
I want to change the left-margin of the first div with class item.
If that's the case, you need to use:
div.item:first-child {
margin-left: 30px;
}
But that gives totally a different one.
Try This
.item:first-child{
margin-left: 30px;
}
Your html has few mistakes, Try to fix it like this: Demo
Wrap class and id with " "
Remove div's that have , in between id and class
HTML:
<div class="container">
<div id="456" class="item">
<div id="header_123" class="item_header">
<div class="text_container">
<div class="header_span">This is Item 456</div>
</div>
</div>
</div>
...
CSS:
.item:first-child {
margin-left: 30px;
}
As Sanjay and Praveen mentioned you need to use :first-child pseudo-class