I have a requirement where I need to set special style to an element of its children is focused. Issue is, the changes are not reflected if the element is not self of children of element in action.
In the below example, I'm using a variable --bg-color as background for Test1, Test3 and Test4.
This variable is update on hover for:
Test2 to Blue
Test3 to Black
If you notice,
Test1 never has an update
Test3 changes background on Test2's hover but not on Test4's hover
:root {
--bg-color: lightblue;
}
div {
height: 200px;
width: 200px;
}
.test1 {
background: var(--bg-color)
}
.test2{
background: red;
display: flex;
flex-direction: column;
}
.test3, .test4 {
background: var(--bg-color);
width: 100px;
height: 100px;
z-index: 1;
}
.test2:hover {
--bg-color: blue;
}
.test3:hover {
--bg-color: black;
}
<div class="test1">Test 1</div>
<div class="test2">
Test 2
<div class="test3">Test 3</div>
<div class="test4">Test 4</div>
</div>
So the question is, can we do this in anyway just by using CSS and is there a restriction for repaint?
Note: I'm aware I can use JS to add class to an element and update style based on it but CSS is faster and my usecase needs css approach. This is just a sample of problem
Related
Let's say there is a row with X amount of columns. The starting height of these columns should all be the same and each of these columns may expand to change their height based off a click (for this case, hover will be used). Let's also assume the height is dynamic and never gets defined (in this example it will be for the sake of usability).
Here is the sandbox that demonstrates the problem: http://www.cssdesk.com/RkqHc
Code below:
.parent {
display: table;
}
.child {
display: table-cell;
background-color: red;
}
.child2 {
display: table-cell;
background-color: blue;
}
.child2:hover {
height: 400px;
}
<div class="parent">
<div class="child">
Some Test Data
Some Test Data
</div>
<div class="child2">
Test
</div>
</div>
You'll notice that both columns are the same size because of the table/table-cell properties, but when hovering over the blue column the height of the red column increases as well. I've tried using flex and grid but reached the same conclusions.
How would one go about keeping a column's sibling (in this case, the red) its original height when the height of the column in question (blue) changes?
Is there a way to do this without using grid, flex, or table?
Thanks
Just came across your post. In case you're still searching for an answer to this question, this is what you can do.
Method 1: Table
The thing with a table cell is that if even one cell in a row or column has a greater height/width, all cells in that row/column will adjust themselves to match that and make the table look consistent. So I don't think this is possible with a table.
Method 2: Flex
With flex, increasing the height of one element will increase the height of the parent container as well. Since the parent height increases, the heights of all other flexboxes in the container will also increase to match that.
To stop this behavior, you can use the align-items/align-content properties on the parent container to align the flexbox to flex-start, flex-end or center. This will maintain the original height of the flexbox, and position all flexboxes, except the one with the new height, at the top/bottom or vertical center of the parent container.
If you want different flexboxes to be positioned separately, you can assign them a align-self prop. which will have the same values mentioned above.
This is what it would look like:
.parent {
display: flex;
color: white;
align-items: flex-start;
font-family: sans-serif;
}
.child, .child2 {
padding: 15px 20px;
}
.child {
display: flex;
background-color: crimson;
}
.child2 {
display: flex;
background-color: steelblue;
}
:where(.child2, .child):hover {
height: 150px;
}
<div class="parent">
<div class="child">
Some test data
</div>
<div class="child2">
Test
</div>
</div>
Method 3: Div
Not much to explain here.
.parent {
display: block;
color: white;
font-family: sans-serif;
}
.child, .child2 {
padding: 15px 20px;
}
.child {
display: inline-block;
background-color: crimson;
}
.child2 {
display: inline-block;
background-color: steelblue;
}
:where(.child2, .child):hover {
height: 150px;
}
<div class="parent">
<div class="child">
Some test data
</div>
<div class="child2">
Test
</div>
</div>
Method 4: Grid
Very similar to flex implementation:
.parent {
display: grid;
grid-template-columns: auto auto;
color: white;
align-items: flex-start;
font-family: sans-serif;
}
.child, .child2 {
padding: 15px 20px;
}
.child {
display: block;
background-color: crimson;
}
.child2 {
display: block;
background-color: steelblue;
}
:where(.child2, .child):hover {
height: 150px;
}
<div class="parent">
<div class="child">
Some test data
</div>
<div class="child2">
Test
</div>
</div>
So here you go. Hope this helped you
I have 4 divs, all of them have their background image. When I hover one of them, that background image should spread over the all divs. Attached is example of how it should work.
How can I achieve this effect with CSS?
example:
.container{
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
}
.card{
height: 500px;
width: 250px;
}
.first{
background-color: red;
}
.first:hover ~ .card{
background-color: red !important
}
.second {
background-color: blue;
}
.third{
background-color: yellow;
}
.fourth{
background-color: green;
}
<div class="container">
<div class="card first"></div>
<div class="card second"></div>
<div class="card third"></div>
<div class="card fourth"></div>
</div>
In this case all the Cards are "siblings" cause they are all direct child elements of container. The ~ selector is for "siblings" there are definetly more elegant solutions for this with SCSS but this generally describes how it works, also look at the following post describing all kinds of Selectors depending on their heritage:
Post
I'm designing a simple webpage using HTML and CSS. I want to design a row at the top of my page which shall have 4 buttons - lets say with content "A", "BB", "CCC", "DDDD". I want to create these 4 buttons such that their width differs according to the length of the content, i.e "A" would be small, but "DDDD" would be a bigger button since it has 4 letters instead of 1.
Can I achieve this using just HTML and CSS or do I need to learn any more technologies for this?
This can be done with HTML alone:
<div class="top-row">
<button>A</button>
<button>BB</button>
<button>CCC</button>
<button>DDDD</button>
</div>
You can absolutely do that with flexbox. For example:
div.header {
position: fixed;
top: 0;
left: 0;
width: 100vw;
display: flex; /* This element is a flexbox */
}
a.button {
background-color: green;
min-width: 50px;
text-align: center;
border: 1px solid white;
}
section {
display: flex; /* This element is a flexbox */
flex-direction: row;
flex-wrap: nowrap;
background: pink;
}
div.column {
border: 1px solid grey;
min-height: 100vh;
}
/* These properties set the column widths within an element that is a flexbox */
.width-1x {
flex-grow: 1;
}
.width-2x {
flex-grow: 2;
}
.width-3x {
flex-grow: 3;
}
.width-4x {
flex-grow: 4;
}
<div class="header">
A
BB
CCC
DDDD
</div>
<section>
<div class="column width-1x"></div>
<div class="column width-2x"></div>
<div class="column width-3x"></div>
<div class="column width-4x"></div>
</section>
By setting the CSS flex-grow property of each button, we can decide what proportion of the width it would take.
Doing this through JavaScript would also work in the case that the columns need to be updated automatically according to their number of characters.
I got a problem with positioning, I need to show Element 2 before Element 1. It is because of a PHP traitement, php code of the second element is executed at the end but I need to show it in first in my page
Ex :
<div class="Element1">
Text after Element 2
</div>
<div class="Element2">
Text before Element 1
</div>
Wrap them in a container and you could make use of CSS3 Flexbox.
That way you only have to change the order. In fact just change the order on one div (Element2) and it will automatically switch. You could also use column-reverse to reverse the order of the entire list.
Something like this:
#container {
width: 240px; height: 240px;
border: 1px solid gray;
display: flex;
flex-direction: column;
/* flex-direction: column-reverse; */
/* use column-reverse if needed to reverse the entire list */
}
.Element1, .Element2 {
height: 100px;
margin: 8px;
}
.Element1 {
order: 2;
background-color: #00f;
}
.Element2 {
order: 1;
background-color: #f00;
}
<div id="container">
<div class="Element1">
Text after Element 2
</div>
<div class="Element2">
Text before Element 1
</div>
</div>
I want to make some boxes have different properties based on whether they're the odd or even number box in the group but only for a selector of multiple classes: But it's including the original box class's object despite it not being in the CSS selector for nth-child:
http://jsfiddle.net/wLx67r83/
<div class="box">1</div>
<div class="box special">1</div>
<div class="box special">1</div>
.box
{
width: 100px;
height: 50px;
background-color: #e3e3e3;
}
.box.special:nth-child(odd)
{
background-color: red;
}
.box.special:nth-child(even)
{
background-color: blue;
}
The third box should be blue, but it's red! And the second should be red, but it's blue!
You have to change the even/odd around in the css.
http://jsfiddle.net/wLx67r83/6/
<div class="box">1</div>
<div class="box special">1</div>
<div class="box special">1</div>
.box
{
width: 100px;
height: 50px;
background-color: #e3e3e3;
}
.special:nth-child(even)
{
background-color: red;
}
.box.special:nth-child(odd)
{
background-color: blue;
}
Edit: Or you can choose the formula option
http://jsfiddle.net/wLx67r83/28/
.special:nth-child(2n+0)
{
background-color: red !important;
}
.special:nth-child(2n+3)
{
background-color: blue !important;
}
nth-child is counting from the parent's child nodes. The correct answer is nth-of-type:
.box.special:nth-of-type(odd)
{
background-color: red;
}
.box.special:nth-of-type(even)
{
background-color: blue;
}