How to make a responsive image banner that has image and text layers with absolute positions? My client wants the banner along with the layered text and images to scale down when the screen goes smaller (Please refer to the screenshot below). I am not looking for a slider, this is just a simple banner with layers. My client has different banners(with layers) on every page, their website used to be non-responsive and now they want to make it responsive. CSS Media queries will probably not work here since I have to define a new font size and image width for every pixel change on the screen which I believe is time consuming.
As you can see, the banner along with the layered texts and images scales down as the screen goes smaller
Link to my fiddle: https://jsfiddle.net/ophLk9pz/1/
HTML:
<div class = "banner">
<img src = "http://i.imgur.com/yfGOPkH.jpg" />
<img src = "http://www.dummymag.com//media/img/dummy-logo.png" class = "layer-image">
<h1>Sample Banner Text</h1>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. Claritas est etiam processus dynamicus, qui sequitur mutationem consuetudium lectorum. Mirum est notare quam littera gothica, quam nunc putamus parum claram, anteposuerit litterarum formas humanitatis per seacula quarta decima et quinta decima. Eodem modo typi, qui nunc nobis videntur parum clari, fiant sollemnes in futurum.</p>
</div>
CSS:
.banner { width: 1440px; position: relative; }
.banner img { z-index: -1; }
.banner h1 {position: absolute; bottom: 30px; left: 10px; }
.banner p {position: absolute; top: 150px; left: 10px; }
.banner .layer-image { position: absolute; top: 0; left: 150px; z-index: 2; }
Any help or ideas would be greatly appreciated, thanks in advance!
You can try to use viewport percentage units on the texts:
https://drafts.csswg.org/css-values/#viewport-relative-lengths
h1 { font-size: 8vw }
And images can be scaled like so:
img {
height: auto;
width:100%;
}
If you need fancier scaling methods (contain, cover etc) i believe you need to have the image as a background-image
Related
I have a series of blog posts stored in MD files, some of these contain multiple Gist embeds in the form of script tags.
The MD contents are rendered to the page via dangerouslySetInnerHTML, and all is fine when the page is navigated to directly. However when the app's routing is used and a full page refresh doesn't happen the script tag is included in the markup, but not executed.
The following example is using the default Next.JS blog example here: https://github.com/vercel/next-learn-starter/tree/master/basics-final.
Markdown:
---
title: "Example of GIST embedding"
date: "2020-02-20"
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut id arcu at arcu pretium porta. Nam feugiat est ut lectus imperdiet venenatis. Ut tempus vitae lectus id vestibulum. Sed tristique est metus. Ut pretium malesuada risus. Maecenas eget diam tristique, sagittis velit ac, efficitur nisi. Quisque lectus lorem, vehicula at mi vitae, dapibus volutpat augue. Sed dignissim pharetra ligula a efficitur. In ultrices imperdiet libero. Quisque ornare erat eu elit ullamcorper faucibus. Maecenas mattis sem a mauris posuere iaculis.
<script src="https://gist.github.com/robearlam/aec15c65aaffbd5ec00a826c5cbe57ad.js"></script>
Etiam sed interdum ligula, nec tincidunt justo. Aliquam erat volutpat. Fusce in scelerisque nisl. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin venenatis lectus at ligula mollis dapibus. Praesent condimentum metus fringilla, commodo enim non, fringilla dui. Vivamus nec ligula lacinia ante semper rhoncus eu sed nisi. In ac dolor vel lorem tincidunt lacinia. Praesent quis mattis mi, at finibus velit. Etiam auctor, magna fermentum tincidunt interdum, nulla augue porttitor enim, ac lobortis felis eros id dui. Suspendisse dignissim, dui sit amet pulvinar iaculis, nisi tellus rhoncus dolor, eu gravida risus massa accumsan magna.
Page
import Layout from '../../components/layout'
import { getAllPostIds, getPostData } from '../../lib/posts'
import Head from 'next/head'
import Date from '../../components/date'
import utilStyles from '../../styles/utils.module.css'
export default function Post({ postData }) {
return (
<Layout>
<Head>
<title>{postData.title}</title>
</Head>
<article>
<h1 className={utilStyles.headingXl}>{postData.title}</h1>
<div className={utilStyles.lightText}>
<Date dateString={postData.date} />
</div>
<div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />
</article>
</Layout>
)
}
export async function getStaticPaths() {
const paths = getAllPostIds()
return {
paths,
fallback: false
}
}
export async function getStaticProps({ params }) {
const postData = await getPostData(params.id)
return {
props: {
postData
}
}
}
Lib function
export async function getPostData(id) {
const fullPath = path.join(postsDirectory, `${id}.md`)
const fileContents = fs.readFileSync(fullPath, 'utf8')
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents)
// Use remark to convert markdown into HTML string
const processedContent = await remark()
.use(html)
.process(matterResult.content)
const contentHtml = processedContent.toString()
// Combine the data with the id and contentHtml
return {
id,
contentHtml,
...matterResult.data
}
I also have a repo showing the issue here: https://github.com/robearlam/gist-embedding-issue
Cheers!
I ran into this same problem, I found this post to be very helpful.
Basically, you create a custom code block that formats your code tags inline.
It has you use <ReactMarkdown> component to render your markdown (instead of remark) and then you use the react-syntax-highlighter library in your custom code block component.
When rendering your markdown use:
import CodeBlock from "../../components/codeblock"
<ReactMarkdown components={CodeBlock}>{your markdown data here}</ReactMarkdown>
Importing your custom codeblock component for the markdown processor.
Tom's custom code block example below:
// components/codeblock.js
import React from "react"
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"
import {dracula} from 'react-syntax-highlighter/dist/cjs/styles/prism';
const CodeBlock = {
code({node, inline, className, children, ...props}) {
const match = /language-(\w+)/.exec(className || '')
return !inline && match ? (
<SyntaxHighlighter
style={dracula}
language={match[1]}
PreTag="div" {...props}>
{String(children).replace(/\n$/, '')}
</SyntaxHighlighter>
) : (
<code className={className} {...props}>
{children}
</code>
)
}
}
export default CodeBlock
Let me explain the situation. Currently I am doing a project to practice SCSS and React. It is a website dedicated to soccer team. The problem is that I am creating a custom modal window using CSS and HTML. What I want is that whenever I click the button "see pics" a modal window related to this card should open, while in my case all modal windows open at once.
All modal windows open at once stacked one on each other. Like that.
There are four modal windows like that overall, but only the top modal shows.
The HTML structure of these modal windows is the following:
They have got the same classes and ids.
In React part I have a component called PopUp, which gets information from db.json as props.
import React from 'react';
import Button from './button-round-dark';
const generateAdditionalInfo = ({info}) => {
if (info) {
return info.map((item) => {
const addInfo = item.additionalInfo;
console.log(addInfo);
return (
<div className="popup" id="popup">
<div className="popup__content" key={addInfo.id}>
<div className="popup__left">
<img className="popup__img" src={`../../${process.env.PUBLIC_URL}/images/additionalInfoPics/${addInfo.images[0]}`}/>
<img className="popup__img" src={`../../${process.env.PUBLIC_URL}/images/additionalInfoPics/${addInfo.images[1]}`}/>
</div>
<div className="popup__right">
x
<h2 className="heading-secondary u-margin-bottom-small">{addInfo.title}</h2>
<p className="popup__description">{addInfo.description}</p>
</div>
</div>
</div>
)
})
}
}
const PopUp = (props) => {
return (
<div>
{generateAdditionalInfo(props)}
</div>
)
}
export default PopUp;
db.json
"legendaryTeam":[
{
"id":"p1",
"name": "buffon",
"image":"buffon.jpg",
"years":"2001-2018",
"number":"18",
"position":"goalkeeper",
"physicalFeatures":{
"weight":"86",
"height":"194",
"speed":"7",
"power":"250"
},
"additionalInfo":{
"id":"1",
"images":["buffon_1.jpg","buffon_2.jpg"],
"title":"Buffon title",
"description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Etiam dignissim diam quis enim lobortis scelerisque. Egestas tellus rutrum tellus pellentesque eu tincidunt tortor aliquam nulla. Lorem sed risus ultricies tristique nulla aliquet enim. Ultrices in iaculis nunc sed augue lacus viverra vitae congue."
}
},
{
"id":"p2",
"name": "Ravanelli",
"image":"ravanelli.jpg",
"years":"1992-1996",
"number":"10",
"position":"forward",
"physicalFeatures":{
"weight":"75",
"height":"176",
"speed":"9",
"power":"300"
},
"additionalInfo":{
"id":"2",
"images":["ravanelli_1.jpg","ravanelli_2.jpg"],
"title":"Ravanelli title",
"description":"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Etiam dignissim diam quis enim lobortis scelerisque. Egestas tellus rutrum tellus pellentesque eu tincidunt tortor aliquam nulla. Lorem sed risus ultricies tristique nulla aliquet enim. Ultrices in iaculis nunc sed augue lacus viverra vitae congue."
}
}
Please pay attention to additionalInfo object, it is where information goes to PopUp component.
Custom CSS code for modal window looks like this.
.popup {
height: 100vh;
width:100%;
position:fixed;
top:0;
left:0;
background-color: rgba($color-black,0.8);
z-index:99999;
opacity: 0;
visibility: hidden;
transition:all .3s;
&:target {
opacity: 1;
visibility: visible;
}
&__content {
#include centrify;
width:75%;
background-color: $color-white;
box-shadow: 0 2rem 4rem rgba($color-black, .2);
border-radius: 3px;
display: table;
overflow: hidden;
}
&__left {
width:33.33333333%;
display: table-cell;
}
&__right {
width:66.666666666%;
display: table-cell;
vertical-align: middle;
padding: 3rem 5rem;
}
&__img {
display: block;
width:100%;
}
&__description {
font-size: 1.4rem;
margin-bottom: 4rem;
}
}
Modal window open with help of target selector. Now I am scratching head over how to make implement what I want. Please help me out. Do you have any ideas?
By the way other modal windows look like this. But they are lower in stack so they are not shown.
If you want to tinker with my project click here
To run react see picture below
To run db.json you need to install it globally
$ npm install -g json-server
And then run it, see pic below
To run SCSS see pic below
Your problem is not in your description, you bind the ButtonRoundDark to all of the modal. You need to add onClick event to your 'see pics' button. After click, fetch the data, show the modal.
I am adding a readmore directive to an angular app. The read-more works great, but try to use a filter for text and it does not interpret the filter string correctly.
Example: http://plnkr.co/edit/Tsqkv1nd6CC8e5Kr9pdU?p=preview
Change demo text to the code below to see what is happening:
<p read-more>(1) This is a short paragraph.</p>
<p read-more>(2) This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph.</p>
<p>(3) {{desc}}</p>
<p read-more>(4) {{desc}}</p>
Notice the 3rd and 4th examples use the $scope.desc value defined in the controller in app.js. #3 works. #4 fails. Why? How to fix?
app.js:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.desc = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec rutrum vehicula tortor, vitae ornare nunc semper eu. Vivamus varius, eros vel tristique accumsan, libero nulla cursus ante, eu eleifend risus orci scelerisque nibh. Curabitur feugiat, augue ut commodo bibendum, nisi leo porttitor diam, tincidunt auctor tellus ante sit amet nibh. Duis velit libero, aliquam at felis eu, pellentesque mollis mi. Nam a est orci. Ut bibendum sagittis semper. Cras eget arcu non augue mollis aliquam. Ut ut gravida ligula. Nulla imperdiet lacinia mi, nec fringilla mauris interdum at. Phasellus gravida tempor varius. Cras molestie et nulla eget maximus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris aliquet malesuada feugiat. Curabitur fermentum bibendum nulla, non dictum ipsum tincidunt non. Quisque convallis pharetra tempor. Donec id pretium leo. Pellentesque luctus massa non elit viverra pellentesque. Cras vitae neque molestie, rhoncus ipsum sit amet, lobortis dui. Fusce in urna sem. Vivamus vehicula dignissim augue et scelerisque. Etiam quam nisi, molestie ac dolor in, tincidunt tincidunt arcu. Praesent sed justo finibus, fringilla velit quis, porta erat. Donec blandit metus ut arcu iaculis iaculis. Cras nec dolor fringilla justo ullamcorper auctor. Aliquam eget pretium velit. Morbi urna justo, pulvinar id lobortis in, aliquet placerat orci.';
});
app.directive('readMore', function() {
return {
restrict: 'A',
transclude: true,
replace: true,
template: '<p></p>',
scope: {
moreText: '#',
lessText: '#',
words: '#',
ellipsis: '#',
char: '#',
limit: '#',
content: '#'
},
link: function(scope, elem, attr, ctrl, transclude) {
var moreText = angular.isUndefined(scope.moreText) ? ' <a class="read-more">Read More...</a>' : ' <a class="read-more">' + scope.moreText + '</a>',
lessText = angular.isUndefined(scope.lessText) ? ' <a class="read-less">Less ^</a>' : ' <a class="read-less">' + scope.lessText + '</a>',
ellipsis = angular.isUndefined(scope.ellipsis) ? '' : scope.ellipsis,
limit = angular.isUndefined(scope.limit) ? 150 : scope.limit;
attr.$observe('content', function(str) {
readmore(str);
});
transclude(scope.$parent, function(clone, scope) {
readmore(clone.text().trim());
});
function readmore(text) {
var text = text,
orig = text,
regex = /\s+/gi,
charCount = text.length,
wordCount = text.trim().replace(regex, ' ').split(' ').length,
countBy = 'char',
count = charCount,
foundWords = [],
markup = text,
more = '';
if (!angular.isUndefined(attr.words)) {
countBy = 'words';
count = wordCount;
}
if (countBy === 'words') { // Count words
foundWords = text.split(/\s+/);
if (foundWords.length > limit) {
text = foundWords.slice(0, limit).join(' ') + ellipsis;
more = foundWords.slice(limit, count).join(' ');
markup = text + moreText + '<span class="more-text">' + more + lessText + '</span>';
}
} else { // Count characters
if (count > limit) {
text = orig.slice(0, limit) + ellipsis;
more = orig.slice(limit, count);
markup = text + moreText + '<span class="more-text">' + more + lessText + '</span>';
}
}
elem.append(markup);
elem.find('.read-more').on('click', function() {
$(this).hide();
elem.find('.more-text').addClass('show').slideDown();
});
elem.find('.read-less').on('click', function() {
elem.find('.read-more').show();
elem.find('.more-text').hide().removeClass('show');
});
}
}
};
});
style.css:
/* Put your css in here */
a.read-more, a.read-less {
cursor: pointer;
color: blue;
font-size: 0.8em;
}
span.more-text {
display: none;
}
span.more-text.show {
display: inline !important
}
index.html:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>Angular Read More Directive</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="jquery" data-semver="2.1.1" src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script data-require="angular.js#1.3.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.7/angular.js" data-semver="1.3.7"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p read-more>This is a short paragraph.</p>
<p read-more>This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph. This is a long paragraph.</p>
<p read-more>{{desc}}</p>
</body>
</html>
As per your current code implementation readmore is getting called before the transcluded DOM content gets projected on directive template.
In this case you should take use content attribute just by saying content="{{desc}}", which will allow to call readmore method of directive as attr.$observe method will get fired.
<p read-more content="{{desc}}">(4)</p>
Demo Plunkr
I want to show show more text only if the p tag is more than 40px height and if the text expands on click of show more, it should change to show less. So how can I check the condo if the text size is more than 40px ? Kindly help.
<p class="expandable" ng-class={expanded:show}>long text-------</p>
<a ng-if="!show" ng-click="show=true">show more</a>
<a ng-if="show" ng-click="show=false">show less</a>
CSS:
.expandable {
line-height:40px;
Overflow:hidden;
}
.expanded{
line-height:auto;
}
Hi referer this https://plnkr.co/edit/gfQmrD1mRvF81QXp7C8C?p=preview
HTML
<p class="expandable hideContent" ng-class=showclass> Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
ghjgjgjkghkk jkhkj
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.-</p>
<div class="show-more">
{{showtest}}
</div>
JS
$scope.showtest = 'ShowLess';
$scope.showmore = function(_logout) {
if($scope.showtest == 'ShowMore')
{
$scope.showtest = 'ShowLess';
$scope.showclass = 'hideContent';
}
else
{
$scope.showtest = 'ShowMore';
$scope.showclass = 'showContent';
}
}
using the Line-height i implement the class
CSS
/* Put your css in here */
.hideContent {
overflow: hidden;
line-height: 1em;
height: 2em;
}
.showContent {
line-height: 1em;
height: auto;
}
.showContent{
height: auto;
}
I'm new to ExtJS, and I'm trying to create a nested, scrollable panel within a window. Unfortunately, none of the answers I've researched so far have provided a solution to this particular problem (or I'm just not understanding them).
Extjs scrollable panel
Autoscroll on parent panel, when there is overflow on child panels.Extjs
Extjs 4.1 What layout for 3 components scrollable
Here is a set of examples that contains a scrollable panel ('Framed Panel: Width 280/Height 180'):
http://docs.sencha.com/extjs/4.2.1/extjs-build/examples/panel/panel.html
Evidently, this technique doesn't work when nesting panels inside a window, as per my sample code below (using version 4.2.1.883):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Nested Scrollable Panel Demo</title>
<script type="text/javascript" src="ext/ext-all-dev.js"></script>
<link rel="stylesheet" href="ext/resources/css/ext-all.css" />
<script type="text/javascript">
Ext.onReady(function(){
var btnTest = Ext.create("Ext.Button",{
text : "Scrollable Nested Panel Test",
renderTo: Ext.getBody()
});
btnTest.on('click', function(){
var html_text = '<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed metus nibh, sodales a, '+
'porta at, vulputate eget, dui. Pellentesque ut nisl. Maecenas tortor turpis, interdum non, sodales non, iaculis ac, '+
'lacus. Vestibulum auctor, tortor quis iaculis malesuada, libero lectus bibendum purus, sit amet tincidunt quam turpis '+
'vel lacus. In pellentesque nisl non sem. Suspendisse nunc sem, pretium eget, cursus a, fringilla vel, urna.<br/><br/>'+
'Aliquam commodo ullamcorper erat. Nullam vel justo in neque porttitor laoreet. Aenean lacus dui, consequat eu, adipiscing '+
'eget, nonummy non, nisi. Morbi nunc est, dignissim non, ornare sed, luctus eu, massa. Vivamus eget quam. Vivamus tincidunt '+
'diam nec urna. Curabitur velit. Lorem ipsum dolor sit amet.</p>';
var win = Ext.create("Ext.window.Window",{
title : "Main Window",
width : 300,
height : 200,
maximizable : true,
defaults: {
xtype : "panel",
height : 60,
collapsible : true,
autoscroll : true
},
items : [{
title : "Menu",
html : 'menu panel content'
},{
html: html_text,
frame : true,
width : '100%',
height : 300
}]
});
win.show();
});
});
</script>
</head>
<body>
<h1>Nested Scrollable Panel Demo</h1>
</body>
</html>
How can I get this to work, where the content of the second panel will scroll, like the panel entitled 'Framed Panel: Width 280/Height 180' in the linked example above?
If you add autoScroll: true to the window configuration the content of the window will be scrollable. (Example below)
However, like Evan is pointing out, if you want the content of the second panel to be scrollable you don't set a height on the panel and add the autoScroll: true property to the second panel, add a flex and vbox layout to the window. (second example)
First Example
Live Example
Ext.onReady(function(){
var btnTest = Ext.create("Ext.Button",{
text : "Scrollable Nested Panel Test",
renderTo: Ext.getBody()
});
btnTest.on('click', function(){
var html_text = '<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed metus nibh, sodales a, '+
'porta at, vulputate eget, dui. Pellentesque ut nisl. Maecenas tortor turpis, interdum non, sodales non, iaculis ac, '+
'lacus. Vestibulum auctor, tortor quis iaculis malesuada, libero lectus bibendum purus, sit amet tincidunt quam turpis '+
'vel lacus. In pellentesque nisl non sem. Suspendisse nunc sem, pretium eget, cursus a, fringilla vel, urna.<br/><br/>'+
'Aliquam commodo ullamcorper erat. Nullam vel justo in neque porttitor laoreet. Aenean lacus dui, consequat eu, adipiscing '+
'eget, nonummy non, nisi. Morbi nunc est, dignissim non, ornare sed, luctus eu, massa. Vivamus eget quam. Vivamus tincidunt '+
'diam nec urna. Curabitur velit. Lorem ipsum dolor sit amet.</p>';
var win = Ext.create("Ext.window.Window",{
title : "Main Window",
width : 300,
height : 200,
maximizable : true,
autoScroll: true,
defaults: {
xtype : "panel",
height : 60,
collapsible : true,
autoscroll : true
},
items : [{
title : "Menu",
html : 'menu panel content'
},{
html: html_text,
frame : true,
width : '100%',
height : 300
}]
});
win.show();
});
});
Second Example
Live Example
var win = Ext.create("Ext.window.Window",{
title : "Main Window",
width : 300,
height : 200,
maximizable : true,
layout: {
type: 'vbox',
align: 'stretch'
},
defaults: {
xtype : "panel",
collapsible : true,
autoscroll : true
},
items : [{
title : "Menu",
html : 'menu panel content'
},{
html: html_text,
frame : true,
flex: 1,
autoScroll: true
}]
});