How can I achieve the effect below using only CSS?
My current Code
<div>
<h4></h4>
<img>
<p>
</div>
#media (min-width: 550px)
{
img {float: left; width: 300px;}
}
EDIT: apologies for the confusion, but currently my code keeps the h4 element on top of the image after floating it. I want to move it to the side as shown in the figure. The text needs to wrap around the image when it is too long.
You could use CSS Grid Layout for that. Just add a two column layout with two rows for the right column like that:
body {
font-family: sans-serif;
background-color: lightblue;
}
img {
max-width: 100%;
height: auto;
display: block;
}
h4 span.variation--big {
display: none;
}
#media only screen and (min-width: 600px) {
body {
background-color: lightgreen;
}
.two-col-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-areas:
"image text_top"
"image text_bottom"
;
}
.two-col-grid img {
grid-area: image;
}
.two-col-grid h4 {
grid-area: text_top;
margin: 0 0 0.5em 0;
padding: 0 1em;
}
.two-col-grid p {
grid-area: text_bottom;
margin:0;
padding: 0 1em;
}
h4 span.variation--small {
display: none;
}
h4 span.variation--big {
display: inline;
}
}
<div class="two-col-grid">
<h4>
<span class="variation--small">Small</span>
<span class="variation--big">Big</span> Screen
</h4>
<img src="https://picsum.photos/id/134/1600/900">
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It
has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop
publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
</div>
Using float and media query.
.card-container {
border: 1px solid #ddd;
padding: 10px;
}
.card-header {
font-family: verdana;
margin: 0 0 10px 0;
}
#media (min-width: 550px)
{
.card-container {
border-color: red;
}
.card-header {
float: right;
width: calc(100% - 210px);
}
.card-img {
float: left;
margin: 0 10px 0 0;
}
}
.clearfix::before,
.clearfix::after {
content: " ";
display: table;
}
.clearfix::after {
clear: both;
}
<div class="card-container clearfix">
<h4 class="card-header">This is header</h4>
<img class="card-img" src="https://picsum.photos/200/200">
<p class="card-desc">1Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quibusdam tenetur eum dignissimos esse dolorum dolorem quia quaerat voluptates ullam, qui dolor quod hic incidunt ab ipsum, architecto pariatur in repellendus.</p>
</div>
You can use the float
img {
width: 200px;
}
#media (min-width: 550px) {
img {
float: left;
width: 300px;
}
xmp {
float: right;
}
}
<div>
<h4>
<xmp>
<h4>Small Screen</h4>
</xmp>
</h4>
<img src="https://pics.freeicons.io/uploads/icons/png/9023038671580097531-512.png">
<xmp>
<p>Text goes here</p>
</xmp>
</div>
Related
Mockup:
The parent div's height is dynamic; it shrinks to fit the left-hand div (the one containing the text). I'd like the right-hand div (white background, with child img) to stretch vertically to fill the parent div. Unfortunately, height: 100% only works when the parent div's height is statically determined.
Here's what I've got right now:
.container {
background-color: lightgray
}
.blurb {
display: inline-block;
padding: 2em;
}
.decoration {
float: right;
background-color: white;
position: relative;
left: -10px;
height: 100% // XXX does not work
}
<div class="container">
<div class="blurb">
Lorem ipsum...
</div>
<div class="decoration">
✓
</div>
</div>
Answers to similar questions recommend using display: table-cell;, but then you have the issue of making the first (text) div stretch horizontally all the way, which is a different can of worms entirely.
Flexbox can do that.
.container {
background-color: lightgray;
display: flex;
border: 1px solid red;
width: 80%;
margin: 1em auto;
}
.blurb {
flex: 1;
padding: 2em;
}
.decoration {
display: flex;
align-items: center;
background-color: white;
margin-right: 1em;
}
<div class="container">
<div class="blurb">
Lorem ipsum...
</div>
<div class="decoration">
✓
</div>
</div>
<div class="container">
<div class="blurb">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Reiciendis molestiae accusantium, magni commodi repellendus quidem facilis doloremque perspiciatis, ab odio omnis deleniti, obcaecati maiores dolores?
</div>
<div class="decoration">
✓
</div>
</div>
You can achieve it with position property. The parent container set to relative and child decoration set to absolute with top and bottom set to 0.
.container {
background-color: lightgray;
position: relative;
}
.blurb {
display: inline-block;
padding: 2em;
}
.decoration {
float: right;
background-color: white;
position: absolute;
top: 0;
bottom: 0;
right: 10px;
/* Align the content to center */
display:flex;
justify-content:center;
align-items:center;
text-align: center;
}
<div class="container">
<div class="blurb">
Lorem ipsum...
</div>
<div class="decoration">
✓
</div>
</div>
Background
On commercial TVs, there's a mode called Video Wall mode, where you can stretch a single desktop across multiple screens. Let's say I'm working with 4 screens, I'm trying to make a web page that appears like it's not stretched, which means on a normal single screen showing one desktop it will look like it's been compressed 4 times.
I've currently got a partial solution by creating a 4 desktop wide page, then using CSS trasform to scale the page by 1/4 horizontally.
Although images are blurry, that could be mitigated by excluding transformation on elements with images.
The issue
When the scaling transform is done, the fonts are pixelated as if they went through a bad (low quality) jpeg compression.
Below is my current code sample.
body {
font-family: Helvetica, Arial, sans-serif;
color: #333;
display: flex;
flex-flow: row;
white-space: nowrap;
overflow: hidden;
min-width: min-content;
animation: fadein 3s;
}
#keyframes fadein {
from {
opacity: 0
}
to {
opacity: 1
}
}
.screen {
display: grid;
grid: 50% auto / 50% auto;
}
.main {
grid-column: 1 / 2;
grid-row: 1 / 2;
background-size: 100% 100%;
background-repeat: no-repeat;
float: left;
}
.dynamic {
grid-column: 1 / 2;
grid-row: 2 / 3;
float: left;
display: flex;
flex-flow: row;
justify-content: space-between;
}
.list {
grid-column: 2 / 3;
grid-row: 1 / 3;
}
.dynamic .item {
position: relative;
height: 100%;
width: 49.8%;
}
.dynamic .item > div {
position: relative;
transform-origin: left;
}
.dynamic .item .name {
display: block;
}
.dynamic .item .header > * {
display: inline-flex;
}
.dynamic .item .values > * {
display: inline-flex;
}
#media (min-aspect-ratio: 16/9) {
body {
font-size: 4vh;
height: 100vh;
}
.screen {
width: calc(8000vh/(9*5));
height: 100vh;
}
.dynamic .text { font-size: 2vh }
.dynamic .name > * { font-size: 4vh }
.list { font-size: 2vh }
.list .title { font-size: 4vh }
}
#media (aspect-ratio: 16/9) {
body {
flex-direction: row;
width: calc(8000vh/9);
height: 100vh;
transform: scaleX(.25);
transform-origin: top left;
}
}
<div class="screen">
<div class="list">
<div class="section">
<div class="title text">Subsection 1</div>
<div class="item">
<div class="text">Text 1</div>
<div class="text">Text 2</div>
<div class="text">Text 3</div>
</div>
</div>
<div class="section">
<div class="title text">Subsection 2</div>
<div class="item">
<div class="text">Text 1</div>
<div class="text">Text 2</div>
<div class="text">Text 3</div>
</div>
</div>
</div>
<div class="main"></div>
<div class="dynamic">
<div class="item">
<div class="name"><span class="text">Subsection 1</span></div>
<div class="header">
<div class="text"><span>Header 1</span></div>
<div class="text"><span>Header 2</span></div>
<div class="text"><span>Header 3</span></div>
<div class="text"><span>Header 4</span></div>
</div>
<div class="values">
<div class="text"><span>Text 1</span></div>
<div class="text"><span>Text 2</span></div>
<div class="text"><span>Text 3</span></div>
<div class="text"><span>Text 4</span></div>
</div>
</div>
<div class="item">
<div class="name"><span class="text">Subsection 2</span></div>
<div class="header">
<div class="text"><span>Header 1</span></div>
<div class="text"><span>Header 2</span></div>
<div class="text"><span>Header 3</span></div>
<div class="text"><span>Header 4</span></div>
</div>
<div class="values">
<div class="text"><span>Text 1</span></div>
<div class="text"><span>Text 2</span></div>
<div class="text"><span>Text 3</span></div>
<div class="text"><span>Text 4</span></div>
</div>
</div>
</div>
</div>
What is causing this, and is there a way to work around it, using HTML/CSS?
Let's say you had a website that was made with only mobile in mind, and you wanted to make it good to go for desktop, you wouldn't use transform scale, right? Simply don't use transform for that. Use media-queries and adjust the actual size of the elements accordingly. Using scale like that will mess with the pixel values and cause this blurry effect.
It doesn't matter how big or small the media you're working with is, the principles of responsive design work the same. Use relative units instead of absolute ones and it's not that hard.
If you use rem units for font-sizes, margins and paddings and etc, and unitless line-heights, they are relative to the root font-size (which is normally 16px by default), so by modifying the font-size on the html element, they will all scale in proportion. For general layout structure, you can use percentages, or even better, use CSS Grid and fr units.
Images will require a bit more work, as you should provably use different images for different sizes, but for everything else, this does it.
A demonstration:
body {
margin: 0;
font-family: sans-serif;
line-height: 1.5;
}
p {
margin-top: 0;
margin-bottom: .75rem;
font-size: 1rem;
line-height: 1.5;
}
.main {
display: grid;
grid-template-rows: 7.5rem max-content 1fr;
min-height: 100vh;
}
.header {
display: flex;
justify-content: center;
align-items: center;
background-color: blue;
color: yellow;
}
.header__title {
font-size: 2rem;
line-height: 2.25;
text-transform: uppercase;
}
.navbar {
display: flex;
background: lightblue;
border-top: 0.125rem solid;
border-bottom: 0.125rem solid;
}
.navbar__item {
flex-grow: 1;
padding: .375rem .75rem;
text-align: center;
text-transform: capitalize;
text-decoration: none;
color: black;
font-size: 1.125rem;
line-height: 1.5;
}
.content {
background: silver;
padding: 1.5rem;
}
.content__title {
font-size: 1.125rem;
line-height: 2.25;
margin-top: 0;
margin-bottom: .75rem;
}
<main class="main">
<header class="header">
<h1 class="header__title">Title</h1>
</header>
<nav class="navbar">
item
item
item
item
item
item
item
</nav>
<article class="content">
<h2 class="content__title">Lorem Ipsum</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cupiditate at omnis hic, maxime ab iure facilis. Dolore alias veniam nisi doloribus at corrupti sapiente ipsam quo voluptates? Excepturi, mollitia qui!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cupiditate at omnis hic, maxime ab iure facilis. Dolore alias veniam nisi doloribus at corrupti sapiente ipsam quo voluptates? Excepturi, mollitia qui!</p>
</article>
</main>
Simple enough, right? The conversion to rem is basically the pixel value divided by 16 (the default root font-size). Now adding just a single line, we can scale everything:
html { font-size: 32px; } /* added just that, doubling the scale (16*2 = 32) */
body {
margin: 0;
font-family: sans-serif;
line-height: 1.5;
}
p {
margin-top: 0;
margin-bottom: .75rem;
font-size: 1rem;
line-height: 1.5;
}
.main {
display: grid;
grid-template-rows: 7.5rem max-content 1fr;
min-height: 100vh;
}
.header {
display: flex;
justify-content: center;
align-items: center;
background-color: blue;
color: yellow;
}
.header__title {
font-size: 2rem;
line-height: 2.25;
text-transform: uppercase;
}
.navbar {
display: flex;
background: lightblue;
border-top: 0.125rem solid;
border-bottom: 0.125rem solid;
}
.navbar__item {
flex-grow: 1;
padding: .375rem .75rem;
text-align: center;
text-transform: capitalize;
text-decoration: none;
color: black;
font-size: 1.125rem;
line-height: 1.5;
}
.content {
background: silver;
padding: 1.5rem;
}
.content__title {
font-size: 1.125rem;
line-height: 2.25;
margin-top: 0;
margin-bottom: .75rem;
}
<main class="main">
<header class="header">
<h1 class="header__title">Title</h1>
</header>
<nav class="navbar">
item
item
item
item
item
item
item
</nav>
<article class="content">
<h2 class="content__title">Lorem Ipsum</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cupiditate at omnis hic, maxime ab iure facilis. Dolore alias veniam nisi doloribus at corrupti sapiente ipsam quo voluptates? Excepturi, mollitia qui!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Cupiditate at omnis hic, maxime ab iure facilis. Dolore alias veniam nisi doloribus at corrupti sapiente ipsam quo voluptates? Excepturi, mollitia qui!</p>
</article>
</main>
Edit: Okay, I see it now - after the discussion on the comments. If your hardware is the one doing the scaling, and not the browser, I believe you are out of luck. But it should be possible to configure your monitors to extend one another horizontally instead, which would make it a proper 7680x1080 canvas that you could detect with a media-query for a 64:9 aspect ratio. Most OS will have that option (excluding things like windows starter). Ubuntu is a free option that have it out of the box, for example. I just assumed that's what you had, since it's usually the simplest way to go.
I found the reason to be related to OS anti-aliasing - since I believe you're not supposed to be able to change or force anti-aliasing on the fonts through the browser.
Since I'm on Windows, enabling ClearType smoothed out the text enough to be legible.
I want to place text next to an image and add padding to it. I have both text and image in one box, so that may be problem. I also need site to be mobile friendly.
Here is my code:
.content-title {
font-size: 50px;
}
#section-a ul {
list-style: none;
margin: 0px;
padding: 0;
}
#tiso {
position: static;
padding: 0px;
height: auto;
float: left;
max-width: 800px;
max-height: 800px;
}
#tiso_text {
padding: 3em;
text-align: center;
}
<section id="section-a" class="grid">
<div class="content-wrap">
<ul class="obr">
<img src="IMG/tiso.png" alt="Tiso-main" id="tiso">
<h1 class="content-title">Jozef Tiso</h1>
<li class="textcontent">
<p id="tiso_text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptate obcaecati et porro quidem iure, odio.
</p>
</li>
</ul>
</div>
</section>
Now, it works when the browser is resized to minimum, but it doesn't work on full. I know why, see image below, I just don't know how to fix that.
Image of what I have, and what I need.
so here is my solution, i hope its that what you wanted..
.content-title {
font-size: 50px;
text-align: center;
}
.item {
max-width: 300px;
float: left;
padding: 20px 3rem;
}
#tiso {
position: static;
padding: 0px;
height: auto;
float: left;
max-width: 800px;
max-height: 800px;
display: block;
}
#tiso_text {
text-align: center;
}
<section id="section-a" class="grid">
<div class="content-wrap">
<div class="box">
<img src="IMG/tiso.png" alt="Tiso-main" id="tiso">
<div class="item">
<h1 class="content-title">Jozef Tiso</h1>
<p id="tiso_text">Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Voluptate obcaecati et porro quidem iure, odio.
</p>
</div>
</div>
</div>
</section>
I'd like to use CSS Grid. Something like this I think…
html {
height: 100%;
}
body {
min-height: 100%;
display: grid;
grid-template-rows: auto auto [whatever's left of the vh] auto auto;
position: relative;
}
Set the viewport with display: flex and height: 100vh and add to the last element
flex-grow: 1
.viewportDiv {
display: flex;
flex-direction: column;
height: 100vh;
}
.div1{
background-color: yellow;
height: 100px;
}
.remainingDiv{
background-color: red;
flex-grow: 1;
}
<div class="viewportDiv">
<div class="div1"></div>
<div class="remainingDiv"></div>
</div>
Using CSS Grid you need to wrap the top two elements and the remaining space and then apply display: grid to that.
In other words, your diagram actually was the solution.
The wrapper should have a height of 100vh…
html {
height: 100%;
}
body {
margin: 0;
min-height: 100%;
background: pink;
display: grid;
grid-template-rows: 100vh auto auto;
position: relative;
}
.wrapper {
display: grid;
grid-template-rows: auto auto 1fr;
}
header {
background: green;
padding: .25em;
}
nav {
background: orangered;
padding: .25em;
}
main {
background: rebeccapurple;
}
footer {
background: yellow;
}
.subfooter {
background: blue;
}
<div class="wrapper">
<header>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Ratione magnam placeat quia iusto, quisquam cum temporibus modi, ex dolorem velit fuga! Minima, ex.
</header>
<nav>
Lorem ipsum dolor, sit amet consectetur adipisicing elit.
</nav>
<main></main>
</div>
<footer>Lorem, ipsum.</footer>
<div class="subfooter">Lorem ipsum dolor, sit amet consectetur adipisicing elit. Ex dignissimos ratione maxime officia eum. ea!
</div>
You can do it using flex.
.a {
width: 100%;
height: auto;
}
.remaining {
width: 100%;
flex-grow: 1;
}
.holder {
display: flex;
flex-direction: column;
height: 100%;
}
html,
body {
height: 100%;
}
HTML code:
<div class="holder">
<div class="a">
Content here
</div>
<div class="a">
Content here
</div>
<div class="remaining">
Content here
</div>
</div>
I have a containing DIV, that I use as part of my responsive grid. It expands to the maximum width I allow which is 1280px, then margins appear for large devices. Here's my CSS + a bit of Less.
.container
{
margin-left:auto;
margin-right:auto;
max-width:1280px;
padding:0 30px;
width:100%;
&:extend(.clearfix all);
}
However on some occasions I'd like to overflow sideways - lets say I have an background image or colour that needs to be full width. I'm not great at CSS - but is it possible to achieve what I want?
The most obvious solution is just to close the container...have your full width div then open a new container. The title 'container' is just a class...not an absolute requirement that it hold everything all at the same time.
In this instance you apply the background color to the full width div and you don't need to apply a color to the internal, restricted div.
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
padding: 0;
}
.container {
max-width: 80%;
border: 1px solid red;
margin: 0 auto;
}
.fullwidth {
background: orange;
}
header {
height: 50px;
background: #663399;
}
.mydiv {
/* background: orange; */
min-height: 50px;
}
footer {
height: 50px;
background: #bada55;
}
<div class="container">
<header></header>
</div>
<div class="fullwidth">
<div class="container">
<div class="mydiv">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsum illum veniam in delectus corrupti autem magnam. Tenetur ducimus provident nisi aut esse aliquid accusamus quas.</p>
</div>
<div class="mydiv">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsum illum veniam in delectus corrupti autem magnam. Tenetur ducimus provident nisi aut esse aliquid accusamus quas.</p>
</div>
</div>
</div>
<div class="container">
<footer></footer>
</div>
However, for some they like a single all encompassing container so if all you are after is a background you could use a pseudo-element like so:
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
overflow-x: hidden;
}
.container {
max-width: 80%;
border: 1px solid red;
margin: 0 auto;
}
header {
height: 50px;
background: #663399;
}
.mydiv {
height: 100px;
position: relative;
}
.mydiv:after {
content: "";
position: absolute;
height: 100%;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 100vw;
background: orange;
z-index: -1;
}
footer {
height: 50px;
background: #bada55;
}
<div class="container">
<header></header>
<div class="mydiv">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsum illum veniam in delectus corrupti autem magnam. Tenetur ducimus provident nisi aut esse aliquid accusamus quas.</p>
</div>
<footer></footer>
</div>
Support for vw is IE9+ - See http://caniuse.com/#feat=viewport-units
There are cases where actual content is required in the 100% wide div and the container cannot be opened/closed at will (perhaps to retrofit a slider).
In those cases, where the height of the new div is known the same technique can be used to position it as to be 100% viewport wide:
* {
margin: 0;
padding: 0;
}
body {
overflow-x: hidden;
}
.container {
max-width: 80%;
border: 1px solid red;
margin: 0 auto;
}
header {
height: 50px;
background: #663399;
}
.mydiv {
height: 100px;
position: relative;
}
.myslider {
position: absolute;
height: 100%;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 100vw;
background: orange;
}
footer {
height: 50px;
background: #bada55;
}
<div class="container">
<header></header>
<div class="mydiv">
<div class="myslider">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsum illum veniam in delectus corrupti autem magnam. Tenetur ducimus provident nisi aut esse aliquid accusamus quas.</p>
</div>
</div>
<footer></footer>
</div>
JSfiddle Demo
Note: there are instances where 100vw can cause overflow and a horizontal scrollbar might appear. overflow-x:hidden on the <body> can attend to that..it should not be an issue because everything else is still inside the container.
I found this super useful trick by using vw on margins (Source)
Example :
.inner-but-full {
margin-left: calc(-50vw + 50%);
margin-right: calc(-50vw + 50%);
}
Demo :
html,body {
overflow-x: hidden; /* Prevent scrollbar */
}
.inner-but-full {
margin-left: calc(-50vw + 50%);
margin-right: calc(-50vw + 50%);
height: 50px;
background: rgba(28, 144, 243, 0.5);
}
.container {
width: 300px;
height: 180px;
margin-left: auto;
margin-right: auto;
background: rgba(0, 0, 0, 0.5);
}
<div class="container">
<div class="inner-but-full"></div>
</div>
Can I use :
http://caniuse.com/#feat=calc
http://caniuse.com/#feat=viewport-units
<meta charset="UTF-8">
<style type="text/css">p{text-align:center;margin-left:25%;height:300px;width:50%;border:1px solid red;margin-bottom:0;margin-top:0;padding:0;
} body{margin:0;text-align:center;height:100%;width:100%;max-width:100%;max-height:100%;}</style>
<p style="color:yellow;background-color: red;">yep</p><p style="color:red;background-color: yellow;">yep</p><p style="color:white;background-color: blue;">yep</p>