I'm trying to have a scrollbar on Y axis when text gets to the end of the right side of the div.
The problem is that when I have texts with spaces its working great but when I'm entering long text without spaces the text is overlapping to X axis.
This is how it's looks:
I'm working with styled components.
This is code samples:
// The container of the white box
const TodoContainer = styled.div`
display: flex;
`;
// The white box with text inside
const TextContainer = styled.div`
text-decoration: ${(props) => props.completed && "line-through"};
background: #fff;
color: ${(props) => props.theme.palette.text.primary};
font-weight: 500;
font-size: 1.6rem;
border-radius: 5px;
padding: 1rem;
margin-right: 1rem;
overflow-x: hidden;
overflow-y: auto;
min-width: 20rem;
max-width: 20rem;
height: 2rem;
`;
You would have to tell css to break long words into new line if needed.
Just add word-break: break-all.
const TextContainer = styled.div`
word-break: break-all;
...
`;
Note: You could also use overflow-wrap: break-word. Thanks #trixn
Related
I just started using styled-components and currently converting all my css into styled components in a project. But i am not sure how to achive some things and i could not find anything relevant in documentation too. I would like to know if the following problem is achievable using this approach in styled-components.
I have two checkboxes(radio input), if its checked i want to style a span element(Dot component in this case).
<div className="acc__type">
<RadioInput type="radio" name="accType" id="dot-1" required />
<RadioInput type="radio" name="accType" id="dot-2" required />
<Category>
<AccTypeLabel for="dot-1">
<Dot></Dot>
<AccTypeTitle>Student</AccTypeTitle>
</AccTypeLabel>
<AccTypeLabel for="dot-2">
<Dot></Dot>
<AccTypeTitle>Staff</AccTypeTitle>
</AccTypeLabel>
</Category>
</div>
here are my styled components
export const RadioInput = styled.input`
display: none;
`;
export const Category = styled.div`
display: flex;
width: 80%;
margin: 15px 0;
justify-content: space-between;
`;
export const AccTypeLabel = styled.label`
display: flex;
align-items: center;
`;
export const AccTypeTitle = styled.div`
font-size: 20px;
font-weight: 500;
`;
export const Dot = styled.span`
height: 18px;
width: 18px;
background: #d9d9d9;
border-radius: 50%;
margin: 10px;
border: 5px solid transparent;
transition: all 0.3s ease;
//here iam trying to change this components styles based on <RadioInput/> components state.
#dot-1:checked & {
border-color: #d9d9d9;
background: #9b59b6;
}
`;
in css i did this and it worked
#dot-1:checked ~ span,
#dot-2:checked ~ span {
border-color: var(--sub-grey);
background: var(--main-purple);
}
/* <Dot/> component was span here */
any help!
In Styled Components it's an ever so slightly different syntax, the reason is that it hashes the class names in a way that makes it difficult to target them. So this is how you do it in a way that ensures SC knows what's what:
const dot1StyledComponent = styled.div`
...
`;
${ dot1StyledComponent }:checked ~ span {
border-color: #d9d9d9;
background: #9b59b6;
}
I am creating a container (which needs to behave responsively for multiple device widths) which can contain a number of different tags. The container needs to have either a consistent padding around the edges and between the rows of wrapped elements, or the elements should have the appropriate margins in place to behave in the same way.
I'm having difficulty getting it to behave how I want and currently it looks like this:
As you can see the top row is perfect; however, the second row has two issues:
The space between the element in the second row and the elements in the first row is twice what it needs to be.
The second row does not have any space on the left of the element.
Currently this is my code:
// Components
const InputContainer = styled.ul`
position: relative;
display: flex;
flex-wrap: wrap;
width: 100%;
border: solid 0.06rem ${colours.darkBluePrimary};
border-radius: 0.6rem;
`;
const Input = styled.input`
appearance: none;
font-family: inherit;
font-size: 1.6rem;
line-height: 1.25;
padding: 1rem;
background-color: white;
border: none;
border-radius: 0.6rem;
&:focus {
outline: none;
}
`;
const Tag = styled.li`
display: flex;
align-items: center;
justify-content: space-between;
margin: 1rem 1rem 1rem 0;
padding: 1rem;
font-family: inherit;
font-size: 1.6rem;
color: white;
background-color: ${colours.darkBluePrimary};
border-radius: 0.6rem;
&:first-child {
margin-left: 1rem;
}
`;
Obviously my approach for using the &:first-child selector will not work. But I am struggling to figure out a way for this to work.
What you are currently doing is having the left margin be 0 and all the other margins be 1rem. This means that the first column doesn't have a left margin either, but you added one manually in
&:first-child {
margin-left: 1rem;
}
You can do this for the second row as well, but that would not solve the 2rem spacing between the rows. So what I think you should do is make all margins 0.5rem, then add padding-left and padding-top to the parent element (the container), and set those values at 0.5rem. Hope this helps!
I try to edit CSS for a list but I did not find how to go to line and to adjust height between list elements properly.
Link to the website : https://denkimedia.com/prod/K2211001/test/
menu open
But I don't know how to fix the size between the list elements :
Display list is not ok
Any idea? :)
I modified position and white-space in article-verticle.css for adjusting the line.
.flowpaper-reflow-tocitem{ position:relative; white-space: normal;
padding, margin, height did not work for adjusting the space between lines.
Please apply below CSS:
li.flowpaper-reflow-tocitem-listitem {
margin-left: -13px !important;
min-height: 38px;
display: flex;
align-items: center;
background: #4f84eb;
margin-bottom: 5px;
border-radius: 5px;
}
li.flowpaper-reflow-tocitem-listitem .flowpaper-reflow-tocitem {
font-family: Lato;
color: #fff;
text-decoration: none;
display: block;
padding-left: 12px;
white-space: break-spaces;
line-height: 1.2;
}
You will get this result:
https://i.imgur.com/KrxyhBS.png
Please let me know if you find any issues
Hello everybody I need a help. The issue is the following: I have flex-container with tabs (number of tabs can be different as they are passed as array in React component).
Each tab contains label and span with a number. By initial conditions for this task, label should not be shorter than 3 letters + "..." (we apply ellipsis for it).
As I have understood, there is no other solution but to do it manually from code (ch unit is based on symbol 0, that's why this approach gives inaccurate result). But let's move to key issue. Text in label can have different length, and we can have different number of tabs.
I need to set tabs in container (let it be restricted by max-width of 900px) as long as it possible. What does it mean: we set tabs with full length of label if it is possible, if not - label shrinks until it reaches min-width (6ch). If number of tabs is too large (all labels have min-width, but tabs exceed container), I will not render them at all. I am going to implement that with help of useLayoutEffect with checks of exceeding container there.
The main problem now is that spans overflow tabs, in other words labels have possibility to shrink, but instead of that other tabs start shrinking arising problems with span. I have tried to use grid with templates columns of 1fr width (number of columns I can set by passing length of array to styled component). That works, but I need to have by tabs aligned to left side (instead of that they would take all available space) and I have problems with extra empty space if label + gap + span < 1fr of container.
By this moment I have no solution, but to hardcode min-width of tab, but all of us understand that it is unacceptable (not to mention the fact that there can be 10,000, for example, in span). I am asking for any help. I would be the happiest person if I found solution.
I have attached images with demonstration of issue, code, and link to codeSandbox with example (there you can insert tabs in mock_data, change length of words).
CodeSandBox - https://codesandbox.io/s/gracious-dijkstra-61s9sp?file=/src/Component.jsx:0-1606
tabs have enough space
labels can shrink, but instead spans overflow tabs
import styled from "#emotion/styled";
const TabsList = styled.ul`
list-style: none;
display: flex;
justify-content: flex-start;
gap: 20px;
margin: 0;
margin-left: 20px;
width: 100%;
max-width: 900px;
background: yellowgreen;
/* because the first tab always will be "all" */
li:first-of-type label {
min-width: 20px;
}
`;
const singleNumPaddingStyles = "0 8px";
const KeywordTab = styled.li`
position: relative;
overflow: hidden;
display: flex;
align-items: center;
padding-bottom: 4px;
gap: 8px;
label {
display: block;
font-weight: 400;
line-height: 23px;
cursor: pointer;
user-select: none;
text-transform: capitalize;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&:hover {
color: blue;
}
/* trying to set minimum 3char + ... */
min-width: 6ch;
}
span {
color: white;
line-height: 23px;
background-color: pink;
user-select: none;
padding: ${({ singleNum }) =>
singleNum ? singleNumPaddingStyles : "0 4px"};
border-radius: 4px;
}
`;
const Group = ({ label, number }) => (
<KeywordTab singleNum={number < 10}>
<label>{label}</label>
<span>{number}</span>
</KeywordTab>
);
export const View = ({ dictionaries }) => {
//logic (useLayoutEffect)
return (
<TabsList>
{dictionaries.map(({ label, total }, index) => (
<Group key={index} label={label} number={total} />
))}
</TabsList>
);
};
//very-very-very bad desicion: hardcode min-width
// of tab ~ 88px (53px for the first - it will always be "all")
I have achieved approximately desired behaviour by using grid instead of flexbox. On parent container i've started to set number of columns dynamically and give them width of minmax(min-content, max-content) (except for the first column as there is always expected element - All). Separate tab was rewritten to grid with 2 columns - (1fr min-content respectively)
import styled from "#emotion/styled";
import { useLayoutEffect, useRef, useState, forwardRef } from "react";
export const TabsListGrid = styled.ul`
margin: 0;
width: 100%;
display: grid;
list-style: none;
background: yellowgreen;
grid-gap: 20px;
grid-template-columns: min-content repeat(${({ columns }) => columns - 1}, minmax(min-content, max-content));
max-width: 712px;
li:first-of-type label {
min-width: min-content;
}
`
const singleNumPaddingStyles = "0 8px";
const KeywordTab = styled.li`
flex-shrink: 0;
position: relative;
overflow: hidden;
display: grid;
grid-template-columns: 1fr min-content;
align-items: center;
padding-bottom: 4px;
grid-gap: 8px;
label {
font-weight: 400;
line-height: 23px;
cursor: pointer;
user-select: none;
text-transform: capitalize;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
&:hover {
color: blue;
}
min-width: 6ch;
}
span {
color: white;
line-height: 23px;
background-color: pink;
user-select: none;
padding: ${({ singleNum }) =>
singleNum ? singleNumPaddingStyles : "0 4px"};
border-radius: 4px;
}
`;
const Group = forwardRef(({ label, number }, ref) => (
<KeywordTab ref={ref} singleNum={number < 10}>
<label>{label}</label>
<span>{number}</span>
</KeywordTab>
));
export const View = ({ dictionaries }) => {
const [visible, setVisible] = useState(true);
const tabsRef = useRef(null);
const tabRef = useRef([]);
useLayoutEffect(() => {
if (tabsRef?.current?.getBoundingClientRect().width < 500) {
setVisible(false);
} else {
setVisible(true);
}
console.log(tabRef);
}, []);
return (
<>
{visible && (
<TabsListGrid ref={tabsRef} columns={dictionaries.length}>
{dictionaries.map(({ label, total }, index) => (
<Group
ref={(el) => (tabRef.current[index] = el)}
key={index}
label={label}
number={total}
/>
))}
</TabsListGrid>
)}
</>
);
};
I have a span what has 2 elements, input and svg.
I want the svg to be centered vertically in the input field.
I have 3 devices where I'm testing the design of my PWA.
Windows 10 - Google Chrome
Android 6.0 - Google Chrome
iOS 12.+ - Safari
On both Windows and Android it's centered vertically, only not on the iOS device.
Does anyone have an idea what this would fix?
React Component:
<StyledInputSpan>
<StyledInput />
<StyledClearButton />
</StyledInputSpan>
Styled Component:
export const StyledInput = styled.input`
//Reset box-shadow
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
display: block;
padding: 0.75em 2em 0.75em 0.75em; //Extra padding on the right for the clear button.
font-size: 1em;
//Hide the standard clear button.
&[type=search]::-webkit-search-cancel-button {
display: none;
}
`;
export const StyledClearButton = styled.button`
position: absolute;
top: calc(2.8em - env(safe-area-inset-top)); //env() is for the nodge on iOS.
right: 0;
`;
const StyledInputSpan = styled.span`
display: flex;
align-items: center;
`;
Find out that using env(safe-area-inset-top) is not what I was looking for.
env(safe-area-inset-top) works only for the top of your app on iOS.
When you use env(safe-area-inset-top) it push down your app with the height of the nodge.
I changed my css/styled component to:
export const StyledInput = styled.input`
//Reset box-shadow
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
position: relative;
display: block;
padding: 0.75em 2em 0.75em 0.75em; //Extra padding on the right for the clear button.
font-size: 1em;
//Hide the standard clear button.
&[type=search]::-webkit-search-cancel-button {
display: none;
}
`;
export const StyledClearButton = styled.button`
position: absolute;
top: 27.5%;
transform: translate(0, -50%);
right: 0;
`;
const StyledInputSpan = styled.span`
position: relative;
display: flex;
align-items: center;
`;