I recive {patients} and place it into a div:
<div className="patients">
{patients}
</div>
It contains Name and Surname, each row in two spans:
(Dev Tools)
(Current state)
How can style those spans into columns (table-like)?
(Expexted result)
---EDIT---
Content of {patients} changes. It's a result of searching, so different names come, sometimes more, sometimes less. I can't apply a style to them separatly.
See the code.
Flexbox is perfect for this kind of layout. Create the flexbox layout in each row by giving the .patient wrapper display: flex;:
.patient {
display: flex;
justify-content: space-between;
}
The justify-content: space-between rule puts the spans on the left and right ends of the available space, one of my favorite things flexbox can do.
.patients {
border: 1px solid black;
max-width: 250px;
}
.patient {
display: flex;
justify-content: space-between;
border-top: 1px solid black;
}
.patient span {
padding: 0 20px; // gives a little space around each span
}
.patient:first-child {
border-top: none;
}
<div class="patients">
<div class="patient">
<span>Eri</span>
<span>Car</span>
</div>
<div class="patient">
<span>Dude</span>
<span>Ok</span>
</div>
<div class="patient">
<span>Nice</span>
<span>One</span>
</div>
</div>
<div class="patients">
<div class="patient">
<span>Eric</span>
<span>Car</span>
<span>Car</span>
</div>
<div class="patient">
<span>Eric</span>
<span>Car</span>
<span>Car</span>
</div>
<div class="patient">
<span>Eric</span>
<span>Car</span>
<span>Car</span>
</div>
<div class="patient">
<span>Eric</span>
<span>Car</span>
<span>Car</span>
</div>
</div>
CSS
----
.patients {
border: 1px solid black;
display: table;
width: 100%;
border-bottom: none;
}
.patient {
display: table-row;
}
.patient > span {
display: table-cell;
border-bottom: 1px solid black;
}
You can use display with table/table-row/table-cell or use display block with a fix with or make each row a flexbox with a fixed width or some other solution. There are many ways to achieve that.
Related
I am implementing a chat for my web app and I find difficulty in placing the messages correctly and I am not skilled in CSS. I want to place the owner's messages to right and the other user's on the left.
Here some sample code:
// this is the container
<div className="container">
{messages.map(({ text='', isOwnMessage=false })=> <Message text={text} isOwnMessage={isOwnMessage}/>)}
</div>
// This is the message component
//...
<div classname="message">{text}</div>
I need to place <Message /> component to left if isOwnMessage is false, on the right otherwise. I know It can be done by giving position absolute and right:0 but that's not good for me. I tried as well: marginLeft: '50%' but then there's a problem with the dimension of the message itself, which is max 80% of the container, otherwise is like its content.
So how would you do that?
I hope this help to solve your problem:
.message{
clear:both;
padding: 10px;
color: #eee;
}
.message.right{
background: green;
float:right;
}
.message.left{
background: cadetblue;
float:left;
}
<div class="container" >
<div class="message right">Owner message...</div>
<div class="message left">Response message...</div>
</div>
You can implement Message component like this:
<div classname=`message ${isOwnMessage ? 'right' : 'left'}`>{text}</div>
By using the align-self property for flex children.
body {
font-family: sans-serif;
}
.conversation {
border: 1px solid black;
display: flex;
flex-direction: column;
gap: 0.2rem;
max-width: 300px;
padding: 0.5rem;
}
.message {
border-radius: 100vh;
padding: 0.5em 0.8em;
}
.self {
align-self: end;
background-color: #006aff;
color: white;
}
.other {
align-self: start;
background-color: gainsboro;
color: black;
}
<div class="conversation">
<div class="message other">hi</div>
<div class="message self">hello</div>
<div class="message other">what's up</div>
<div class="message self">i'm weekending</div>
<div class="message self">hbu</div>
</div>
Made these changes using flex.
.flex{
display:flex;
}
.flex-col{
flex-direction:column;
}
.ml-auto{
margin-left:auto;
}
// Component
<div className="container flex flex-col">
{messages.map(({ text='', isOwnMessage=false })=> <Message text={text} isOwnMessage={isOwnMessage}
className={isOwnMessage?"ml-auto":""}
/>)}
</div>
// This is the message component
<div classname={["message", props.className].join(" ")}>{text}</div>
I am trying to place my card boxes on 1 row rather than on 1 column. Can someone explain to me what is wrong with this CSS?
import "./Card.css"
class Card extends PureComponent {
render() {
return (
<div className="cardcontainer">
<div className="cardbox">
<div>{this.props.title}</div>
<div>{this.props.category}</div>
<div>{this.props.likes / this.props.dislikes}</div>
</div>
</div>
)
}
}
export default Card
.cardcontainer{
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
.cardbox{
border: 1px solid red;
width: 200px;
height: 200px;
}
Your cardlist style needs to be applied with the parent component of the Card component.
EG you may have another component called cardList and within the render method for that you apply the cardcontainer style EG.
<div className = cardcontainer>
<Card/>
</div>
This is because in your current code you have initiated the cardcontainer style for every row. I have recoded your work in CSS and HTML so you can see what I mean. I hope this helps.
.cardcontainer{
display: flex;
flex-direction: row;
flex-wrap: nowrap;
width:1000px;
}
.cardbox{
border: 1px solid red;
width: 200px;
height: 200px;
}
<div class="cardcontainer">
<div class="cardbox">
<div>A title</div>
<div>A CAtegory</div>
</div>
<div class="cardbox">
<div>A title</div>
<div>A CAtegory</div>
</div>
</div>
How do I target the last child of a class when there are siblings with another class after it? It would be nice to have a :last-sibling and :last-sibling-of-type.
FIDDLE
<div class="grid">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div> /* How do I target this if its nth position is unknowable? */
<div class="grid-orphan"></div>
<div class="grid-orphan"></div>
<div class="grid-orphan"></div>
</div>
If you need to get the last .grid-item element out of the document, regardless of what it's inside, then you can't do that in CSS. In CSS, you can only select the first, last, or nth element at one particular level of the hierarchy, you can't select the last element of some type regardless of what it's nested in.
Here is one way to get the last div inside of .grid
.grid div:last-of-type
Here's another way to get the last child of some outer div:
div :last-child
BUT The thing you probably need is some js:
You could do this the jquery approach (like below), or just do getElementsByClassNameand then set the last element in the list in the same manner.
function getlastchild() {
var items = $(".grid-item");
items.last().css("background-color", "red");
//OR even as one-liner: $(".grid-item").last().css("background-color", "red");
}
.grid {
width: 200px;
}
.grid div:last-of-type {
color: white;
}
div:last-child {
background-color: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="grid">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-orphan">5</div>
<div class="grid-orphan">6</div>
<div class="grid-orphan">7</div>
</div>
<button onclick="getlastchild()">Press me to get last grid-item</button>
I see 4 possibilities here:
Case 1:
You already know the number of grid-orphan items, so you can use nth-last-child.
.grid-item:nth-last-child(4) {
background: blue;
}
Case 2:
You are an adventurer and this is not for production: use the newest version of nth-child and nth-last-child:
.grid-item:nth-last-child(1 of .grid-item) {
background: blue;
}
However, it only works on Safari for now (12.99%).
See specs
Case 3:
Use JavaScript.
const items = document.querySelectorAll('.grid-item')
const selectedItem = [].slice.call(items).pop();
selectedItem.style.background = 'blue';
Case 4:
Just add an extra class.
<div class="grid-item grid-item--special"></div>
.grid-item.grid-item--special {
background: blue;
}
You can use either :nth-last-child or :nth-last-of-type if you are able to put all your .grid-orphan elements inside another div.
HTML
<div class="grid">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-orphans">
<div class="grid-orphan"></div>
<div class="grid-orphan"></div>
<div class="grid-orphan"></div>
</div>
</div>
SCSS
.grid {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
.grid-item {
background: gray;
border: 1px solid white;
position: relative;
display: flex;
flex-direction: column;
height: 100px;
width: calc(25% - 20px);
min-width: 360px;
flex-grow: 2;
justify-content: flex-start;
cursor: pointer;
&:nth-last-child(2) {
background: navy;
}
}
.grid-orphan {
height: 0;
border: 0;
display: flex;
flex-direction: column;
width: calc(25% - 20px);
min-width: 360px;
flex-grow: 2;
justify-content: flex-start;
cursor: pointer;
}
}
Jsfiddle available here.
Otherwise, a CSS-only approach would be limited to only Apple's browsers, that is Safari desktop and on iOS, since they are the only ones that implement the selector list argument, which allows you to narrow down the elements by a class selector. For seeing this just change &:nth-last-child(2) with &:nth-last-child(1 of .grid-item)
All those answers are great. Thank you. I ended up just making the orphans <span>'s and then .grid-item:last-child worked fine. I knew I could do that but was wondering if it could be done (easily) when the orphans were the same element type as the grid items.
I have 2 divs inside another div container. I'm using flexbox to center them vertically inside the container, but I want them to be next to each other horizontally rather than one on top of the other. I tried a few different approaches including changing the display property of the container from flex to inline-flex as well as adding display:inline-block to the child divs. Here is a picture of what I'm working with. As you can see the 2 divs (the picture and group 1 label) are centered within the parent div, but I want Group 1 to be next to the picture instead of below it.
Code below and link to JSfiddle:
HTML
<div class="user-group">
<div>
Picture 1
</div>
<div class="user-group-name"><h4>Group 1</h4></div>
</div>
JS
.user-group{
font-family: 'Purista';
border: solid 1px;
display: inline-flex;
float: left;
justify-content:center;
align-content:center;
flex-direction:column; /* column | row */
width: 50%;
height: 200px;
}
.user-group > div{
display: inline-flex;
}
It depends if you intend to have multiple picture + text pairs in the element. If you don't, simply using align-items: center should fix your issue. There are some issues with your code:
align-content is not a flex property
Avoid using display: inline-flex, your situation does not call for it
Floats and flex are conflicting layout methods. Pick one—in this case, we settle for flex.
Use the default flex direction, which is row (if undeclared, it defaults to row, so we can just remove that property)
.user-group {
font-family: 'Purista';
border: 1px solid;
display: flex;
justify-content: center;
align-items: center;
width: 50%;
height: 200px;
}
h4 {
margin: 0;
}
<div class="user-group">
<div>
<img src="https://placehold.it/32x32" alt="" title="" />
</div>
<div class="user-group-name">
<h4>Group 1</h4></div>
</div>
On the other hand, if you have multiple picture + text pairs, you will have to resort to nesting. Each pair will have to be wrapped by an additional <div>:
.user-group {
font-family: 'Purista';
border: 1px solid;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 50%;
height: 200px;
}
.user-group > div {
display: flex;
margin-bottom: 10px;
}
h4 {
margin: 0;
}
<div class="user-group">
<div>
<img src="https://placehold.it/32x32" alt="" title="" />
<div class="user-group-name"><h4>Group 1</h4></div>
</div>
<div>
<img src="https://placehold.it/32x32" alt="" title="" />
<div class="user-group-name"><h4>Group 2</h4></div>
</div>
<div>
<img src="https://placehold.it/32x32" alt="" title="" />
<div class="user-group-name"><h4>Group 3</h4></div>
</div>
</div>
I am working on a responsive site in which the mobile/tablet view differs from the desktop view in the way it re-orders the DIVs.
Is there a way to write maintainable CSS that let's you re-organize the order of how HTML DIVs appear?
For example, the code below controls the order of how DIVs would appear on a desktop device:
<div class="container">
<div class="row1">
<div class="col1A">Sample content</div>
<div class="col2A">Sample content</div>
<div class="col3A">Sample content</div>
</div>
<div class="row2">
<div class="col1B">Sample content</div>
<div class="col2B">Sample content</div>
<div class="col3B">Sample content</div>
</div>
</div>
However, for mobile/tablet view, I want to display the DIVs in different order using CSS, like the example below:
Show row2, col2B
Then row1, col1A
Then row1, col3A
Then row2, col1B
Is this possible using CSS ?
As a proof-of-concept, you can use the flex CSS property to reorder how elements are visually rendered.
In your example, I had to keep the child elements within a single container
and then I could control the order using the order property.
If you want to hide some items on the small screen view, use display: none on the specific items.
Note: For a wide screen, you would need some CSS rules to get the items to look like two rows. (Please specify what you need.)
If you combine this with media queries, you can get a workable solution.
.container {
display: flex;
flex: center;
flex-direction: column;
align-items: center;
border: 1px dotted blue;
}
.container div {
text-align: center;
padding: 10px;
border: 1px dotted gray;
width: auto;
}
.col1A {
order: 2;
}
.col2A {
display: none;
}
.col3A {
order: 3;
}
.col1B {
order: 4;
}
.col2B {
order: 1;
}
.col3B {
display: none;
}
<div class="container">
<div class="row1 col1A">Sample content 1A</div>
<div class="row1 col2A">Sample content 2A</div>
<div class="row1 col3A">Sample content 3A</div>
<div class="row2 col1B">Sample content 1B</div>
<div class="row2 col2B">Sample content 2B</div>
<div class="row2 col3B">Sample content 3B</div>
</div>
If you want to simulate two rows of three elements, you can still use flex with some adjustments. The following may be helpful.
.container {
display: flex;
flex: center;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
border: 1px dotted blue;
padding: 20px 0;
}
.container .row1 {
margin-bottom: 20px;
}
.container div {
text-align: center;
padding: 10px;
border: 1px dotted gray;
flex-basis: calc(33% - 20px);
}
.col1B {
background-color: yellow;
}
<div class="container">
<div class="row1 col1A">Sample content 1A</div>
<div class="row1 col2A">Sample content 2A</div>
<div class="row1 col3A">Sample content 3A</div>
<div class="row2 col1B">Sample content 1B</div>
<div class="row2 col2B">Sample content 2B</div>
<div class="row2 col3B">Sample content 3B</div>
</div>
Set a screen size for mobile device detection in the css and add the following
#media screen and (max-width: SIZE) {
.row2{
display: flex; flex-flow: column;
}
.col1B{
order: 1;
}
.col2B{
order: 2;
}
.col3B{
order: 3;
}
}
And then add the classes to the DIVs
<div class="row2">
<div class="col1B">Sample content</div>
<div class="col2B">Sample content</div>
<div class="col3B">Sample content</div>
</div>
Change order: 1/2/3; to your needs.